Aura
An AWS cloud security posture scanner, written in Go.
- built
- 2026, over 2-3 months of research and building
- stack
- Go, PostgreSQL, Starlark, React, AWS (SQS, CloudTrail, Config, ECS Fargate)
- coverage
- 24 scanners, 83 rules, 19 AWS services
Why
Cloud security platforms like Wiz are excellent, and priced for enterprises. Most smaller companies can't justify that, so they run AWS without really knowing what they have or what's exposed. That's a real risk: one leaked access key or one public bucket is enough.
So I built the foundation myself, in two layers. First, ingestion and inventory: an accurate, always-current picture of every resource in the account. Second, scanning on top of it: rules that turn that picture into findings someone can act on. Both are designed so the next layers, like a graph of how resources connect and what's actually reachable from the internet, can sit on top without a rewrite.
Screens
From connecting an account to the dashboard after the first scan. All data here is made up.
How it works
- Scanners list resources through the AWS APIs on a schedule, with rate limiting, retries and bounded concurrency so a big account doesn't get throttled. Each one writes into a single canonical inventory schema (ARN, tags, lifecycle status, relationships), so rules never care which scanner produced a resource.
- Real-time ingestion. Periodic scans are blind between runs. CloudTrail events flow through SQS into Aura, so a security group opened between scans shows up within moments, not at the next run.
- AWS Config integration adds the "current state" view and a drift check that compares Config's record against Aura's last scan.
- Native AWS findings from GuardDuty, Security Hub, Inspector and IAM Access Analyzer are pulled in next to Aura's own, instead of trying to rebuild what AWS already does well.
Rules
Rules live in their own repository and are written in Starlark, a small, sandboxed dialect of Python. That means a security engineer can add a check without touching Go or redeploying: Aura watches the rules folder and hot-reloads on change. A rule looks like this:
COMPLIANCE = {
"cis_aws_foundations": ["2.1.1"],
"soc2": ["CC6.1"],
"pci_dss": ["2.2"],
"nist_800_53": ["AC-3", "AC-6"],
}
def evaluate(resource):
pab = resource["public_access_block"]
if not pab["block_public_acls"] or not pab["ignore_public_acls"]:
return finding("S3-001", "HIGH",
"S3 bucket does not block public ACLs", ..., "s3")
return no_finding("S3-001")
- Rules map to compliance controls: NIST 800-53 (81 rules), SOC 2 (64), CIS AWS Foundations (44), PCI DSS (43) and HIPAA (10).
- Every rule ships remediation three ways: an AWS CLI command, console steps, and a Terraform fix.
- A shared standard library (public CIDRs, sensitive ports, tag helpers, "is this production?") keeps rules short and consistent.
- Rules are tested against pass/fail fixtures (147 of them) with
aura test-rules, so a rule change that breaks detection fails before it ships.
What it covers
IAM (users, roles, policies), S3, EC2 and security groups, VPC and subnets, ELB, CloudFront, RDS, Lambda, KMS, Secrets Manager, CloudTrail, AWS Config, ECR, ECS, EKS, GuardDuty, Security Hub, Inspector and IAM Access Analyzer.
Findings that don't turn into noise
- A lifecycle: open → acknowledged / in progress / suppressed → resolved, and reopened automatically if the problem comes back.
- Findings resolve themselves when the next scan sees the fix.
- Suppression rules for accepted risks, and SLA tracking per severity, with a view of what's breached.
- Notifications to Slack, PagerDuty (Events API v2) and signed webhooks (HMAC-SHA256).
Running it
- One Go binary:
aura serveruns the API, the scheduler and the ingestor. API keys, rate limiting and Prometheus metrics are built in. - A React dashboard for accounts, onboarding, findings, inventory, the event timeline, posture and SLA breaches.
- Deployed with a CloudFormation template to ECS Fargate behind an ALB; the image is built in CI and pushed to GitHub's registry.
How I built it
Most of the time went into research: how existing posture tools model an inventory, how they keep findings from turning into noise, and which AWS services produce the findings that matter most. Then I built it in layers: the inventory schema first, then hardened scanners, real-time ingestion, the rule library, and coverage from 5 to 19 services.
Not done yet
- Onboarding accounts automatically through AWS Organizations; today each account is added by hand.
- Network reachability: "is this open port actually reachable from the internet?" needs a proper graph of VPCs, routes and gateways.






