Why I Built It
Security Hub and Trusted Advisor already exist. So does Prowler, and Prowler is very good. The gap for me was context switching.
When I am in the IDE writing a Lambda or a security group rule, I do not want to open a browser, log into a console, wait for Security Hub to aggregate, and then translate a finding ID back into the thing I just wrote. I want to type "run a security scan" and get a report in the same window.
The second thing: most scanners run every check against every service whether or not you use that service. I have zero RDS instances. I do not need 22 RDS checks generating noise in a report I have to read. So this one discovers what actually exists in your account first, shows you the inventory, then asks you what to scan.
Read-only by design
Every call is describe, list or get. Nothing is created, modified or deleted.
Scoped to your account
Discovery runs first. Checks only fire against services you actually use.
Report stays local
Markdown and HTML written to your working directory. Nothing leaves the machine.
Two modes, kept apart
A hygiene report and an audit response are read by different people.
What Is Inside: 4 MCP Servers, 5 Skills
Four MCP servers do the actual work. The steering files carry the logic: 44 execution phases and a catalog of all 194 checks with their compliance mappings.
| Server | Purpose |
|---|---|
aws-mcp | Every AWS API call, read-only |
iam-mcp-server | Policy simulation, inline policy audit |
well-architected-security-mcp-server | Security Pillar assessment |
aws-documentation-mcp-server | Remediation references |
Three Scan Modes
| Mode | Trigger | Output |
|---|---|---|
| General | "run a security scan" | PASS / WARN / FAIL plus a risk score |
| Compliance | Only when you name CIS, HIPAA, PCI DSS, SOC 2 or FSBP | Binary pass or fail, compliance rate as a percentage |
| Well-Architected | "run well-architected security assessment" | Security Pillar findings and recommendations |
I kept them separate on purpose. A CIS report and a general hygiene report answer different questions for different readers, and mashing them together produces a document nobody trusts.
Setup and the First Run
Install is one step. Kiro, then Powers, then Add Custom Power, then Import from GitHub with the repo URL. Kiro reads plugin.json and mcp.json and wires up the MCP servers itself.
uvx, and a working aws sts get-caller-identity.Then I typed "run the AWS security scan" and it asked three questions before touching anything.
I said us-east-1 and Hyderabad, and no on Trusted Advisor since I have no Business or Enterprise Support. It skipped that check set instead of failing on it.
{
"regions": ["us-east-1", "ap-south-2"],
"outputDir": "./security-reports",
"includeTrustedAdvisor": false,
"accountId": "123456789012",
"scanType": "general"
}root. I was testing in a sandbox account and got lazy. The scanner had opinions about that later, and it was right.Discovery: 238 Roles, 0 Detectors
Before running a single check, it inventories the account. This is the part I like most.
238 IAM roles. 83 S3 buckets. 18 Lambda functions in us-east-1, five in Hyderabad. 24 and 17 security groups. 13 and 4 KMS keys. Then a column of zeros for RDS, ECS, EKS, SQS, API Gateway, ECR, OpenSearch, ElastiCache, Redshift and WAF.
Two lines stopped me.
GuardDuty 0 detectors 0 detectors
CloudTrail 0 trails 0 trailsI have been running things in this account for months. No detective controls at all. That is the finding, and I did not need 194 checks to surface it. I needed the inventory.
It recommended categories 1 to 15 and skipping the rest: 14 phases instead of 44.
iam-deep-dive skill exists because of exactly this.The General Scan: 72/100
72 out of 100. High risk. In my own account. 5 critical, 8 high, 12 medium, 14 passing, from 39 findings across the 14 scoped phases.
IAM and Credentials
Root MFA was on, the one thing I had done right. Root also had an active access key, the worst item in the report and the easiest to fix. It has been deleted since. Beyond that: no custom password policy, and one IAM user with no MFA and two active access keys. Access Analyzer passed in both regions.
Detective Controls
Three criticals and a high, all the same shape. No CloudTrail in either region, no GuardDuty detectors in either region, Security Hub not subscribed anywhere. If something had happened in this account, I would have had nothing to look at afterwards.
EC2 and Network
The default security group was open to 0.0.0.0/0 on all ports, and a leftover launch-wizard-3 group was too. SSH from anywhere appeared across 11 security groups spanning both regions, which is what happens when you spin up demo instances for two years and never clean up.
IMDSv2 was enforced and the instance had an IAM profile, so the two checks I expected to fail actually passed. Those are defaults now, and defaults getting better is the quiet win nobody writes about.
Data and Application Layer
SNS topic encryption failed, DynamoDB point-in-time recovery and deletion protection came back as warnings on both tables, and a Secrets Manager secret had no rotation configured. Lambda environment variables were not encrypted with a customer managed key on two functions. On the pass side: EFS encrypted at rest, KMS key rotation on, and all 23 Lambda functions running python3.12 or nodejs20.x with no deprecated runtimes.
The CIS Scan: 12.5%
The general scan tells you what is wrong. A compliance scan tells you what an auditor will say about it. Same account, different question, so I typed "Run the CIS Scan".
It reused the IAM data from the general scan instead of re-enumerating 238 roles. That is the behaviour I wanted from the steering file, and the main reason both modes live in one power.
5 of 40 Controls Passing
35 failing, 4 excluded as not applicable. The general scan gave me 72/100 and that felt bad enough. CIS scored the same account at 12.5 percent, and both numbers are right because they measure different things. A risk score weights findings by severity. A compliance rate counts controls, and an unimplemented control is worth zero no matter how unlikely you think the risk is.
| Section | Rate | Passing |
|---|---|---|
| 1. IAM | 35.7% | 5 / 14 |
| 2. Logging | 0% | 0 / 4 |
| 3. Monitoring | 0% | 0 / 14 |
| 4. Networking | 0% | 0 / 4 |
| 5. Storage | 0% | 0 / 4 |
Section 1: Identity and Access
Root has one active access key created 2026-02-27, failing 1.4. Root MFA is on so 1.5 passes, but it is virtual rather than hardware, so 1.6 fails. No custom password policy takes out 1.8 and 1.9 together. The console user has no MFA (1.10) and holds two active keys (1.13).
1.15 and 1.16 are worth reading as a pair. 1.15 is permissions only through groups, and it failed on a policy attached directly to the user. 1.16 is no full admin policies attached, and it failed because the group that user belongs to carries AdministratorAccess. Two controls, two separate problems, and the evidence column is what makes that distinction visible.
On the pass side, 1.12 and 1.14 held: nothing unused past 45 days, keys rotated within 90, five days old. Rotating credentials on schedule does not help much when one key belongs to root and the other belongs to a user with no MFA.
Zero Out of Eighteen
Section 2 failed all four: no trails exist, so log file validation and CloudWatch Logs integration have nothing to attach to, and no Config recorders were found.
Section 3 failed all fourteen, and the report explains why in one line at the top. Every monitoring control needs CloudTrail feeding CloudWatch Logs, then metric filters, then alarms. With no CloudTrail there is no chain to start. Unauthorized API calls, console sign-in without MFA, root usage, IAM policy changes: all fourteen fail for the same upstream reason.
What to Fix First
The report ordered remediation by how many controls each action unlocks rather than by severity. Enabling CloudTrail with CloudWatch integration clears 19 of the 35 failures on its own and moves the account from 12.5 percent to roughly 60 percent once metric filters and alarms are configured.
Deleting the root key ranks second. It is the highest-privilege risk in the account and clears exactly one control, which shows why ordering by control count alone would be wrong. Below that: strip the default security group, enable account-level S3 Block Public Access across all 83 buckets, add MFA on the console user, set a password policy, restrict SSH and RDP to known CIDRs, enable flow logs, default EBS encryption, and AWS Config.
The same facts appear in both reports. The general scan called it "IAM user MFA enabled: FAIL, HIGH". CIS called it 1.10. One goes in a ticket, the other goes in an audit response. That is why I did not merge the modes.
TL;DR Checklist
- Install from GitHubKiro, Powers, Add Custom Power, Import from GitHub. Kiro reads plugin.json and mcp.json automatically.
- Verify credentials first
aws sts get-caller-identitymust work. Do not run it as root, unlike me. - Let discovery run before scanningScoping to services you actually use cut 44 phases to 14 and removed the noise.
- Use general mode for hygieneRisk score, severity weighting, remediation ordered by impact.
- Name the framework for complianceCIS, HIPAA, PCI DSS, SOC 2 or FSBP. It will not guess.
- Fix upstream causes firstCloudTrail alone cleared 19 of my 35 failing CIS controls.
https://github.com/aquavis12/power-aws-security-analyzerImport it, confirm your credentials, then type "run the AWS security scan". It asks before it does anything, and it only ever reads.