sar-aws-faultline
Find the security gaps in your AWS account, ranked by what to fix first.
Read-only. Never changes anything.
pipx install sar-aws-faultline
sar-aws-faultline scan --all-regions
The problem
You are three people. A prospect just sent a security questionnaire, or an investor asked when you will have SOC 2. You know your AWS account has problems. You do not know which ones matter, which ones an auditor will actually stop at, or which fixes will show up on next month's bill.
So you run a scanner. It produces four hundred findings, sorted by severity, in vocabulary written for people who already know the answer. You scroll for ten minutes, close the tab, and nothing changes.
This tool takes the opposite bet: a small number of checks, ordered by what to fix first, each with the steps to fix it, how long it takes, and what it costs per month.
What makes it different
Every finding carries two axes, not one:
- Severity — how bad this is if someone exploits it.
- Audit impact —
blocker,expectedorhardening. What it costs you in a SOC 2 readiness conversation.
These do not correlate, and collapsing them is why generic scanner output needs triage before it is useful. A missing CloudTrail trail is medium severity — nothing is exposed — but it is an absolute audit blocker, because without it you cannot evidence any monitoring control at all. A permissive security group on an isolated dev VPC is the reverse.
Findings are ordered by audit impact first. That ordering is the product.
And every fix carries its price:
| Finding | Severity | Audit impact | Effort | Cost of fixing |
|---|---|---|---|---|
| Publicly accessible S3 bucket | critical | blocker | minutes | $0 |
GuardDuty, a Config recorder and VPC flow logs all carry a real monthly bill. A three-person team deciding whether to turn them on needs that number in the same table as the red X.
Sample output
sar-aws-faultline — account 123456789012
┏━━━━━┳━━━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┓
┃ # ┃ Impact ┃ Severity ┃ Region ┃ Resource ┃ Finding ┃ Fix ┃
┡━━━━━╇━━━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━┩
│ 1 │ blocker │ critical │ global │ acme-app-prod-assets │ Publicly accessible S3 bucket │ minutes │
│ 2 │ blocker │ critical │ global │ acme-customer-exports │ Publicly accessible S3 bucket │ minutes │
└─────┴───────────┴──────────┴──────────────┴───────────────────────┴───────────────────────────────┴─────────┘
1 check(s) across 1 region(s) in 0.2s — 2 gap(s), 2 blocker(s).
Run with --output markdown for fix steps, effort and monthly cost.
Checks AWS configuration only, which is one part of a SOC 2 audit. Not a compliance assessment.
--output markdown produces a report with, for each finding: why it matters in
plain language, the affected resources, console steps, a CLI one-liner, what
the fix might break, and the control references it bears on.
Install
pipx install sar-aws-faultline # recommended
pip install sar-aws-faultline
Python 3.11+. Three runtime dependencies: boto3, typer, rich.
Usage
sar-aws-faultline scan # default profile, default region
sar-aws-faultline scan --all-regions # every enabled region
sar-aws-faultline scan --profile prod -r us-east-1 -r eu-west-1
sar-aws-faultline scan --output markdown > gaps.md
sar-aws-faultline scan --output json | jq '.findings[] | select(.audit_impact=="blocker")'
sar-aws-faultline scan --framework soc2-tsc # only checks mapped to SOC 2
sar-aws-faultline scan --impact blocker # only audit blockers
sar-aws-faultline scan --severity high # only high and above
sar-aws-faultline checks # what it looks at
sar-aws-faultline frameworks # what it maps to
sar-aws-faultline iam-policy # the policy it needs
Configuration can also live in sar-aws-faultline.toml — see
sar-aws-faultline.toml.example. Precedence
is CLI flags > SAR_AWS_FAULTLINE_* environment > config file > defaults.
As a CI gate
- run: pipx install sar-aws-faultline
- run: sar-aws-faultline scan --all-regions --fail-on blocker
Exit codes are an interface; changing them is a breaking change.
| Code | Meaning |
|---|---|
| 0 | Clean, or findings below the --fail-on threshold |
| 1 | Findings at or above the threshold |
| 2 | One or more checks could not run |
| 3 | Usage error |
Code 2 is deliberately distinct from code 1. "You have two problems" and
"I could not look at three of your checks" are different messages, and a
pipeline that treats an AccessDenied as a clean pass is worse than no scan at
all. --fail-on blocker is usually what you want: fail on anything an auditor
would stop at, regardless of its severity score.
Read-only, structurally
This is not a promise in a README. A botocore before-call hook inspects every
operation before it goes over the wire and raises if the operation name is not
a read. A check that tried to change something would fail in CI rather than
quietly succeed against your production account.
The guarantee is enforced twice more: the generated IAM policy is asserted to contain no mutating action, and the policy generator refuses to emit one.
There is no remediation in v1, deliberately. A tool that can fix things is a tool that needs write credentials, and write credentials change the risk calculus of pointing it at production for the first time — which is exactly when it is most useful. Every finding ships with the commands to fix it yourself. You run them.
IAM policy
Generated from the check registry, never hand-written. CI regenerates and diffs it, so it cannot advertise permissions the code does not use, or omit ones it does.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SarAwsFaultlineReadOnlyScan",
"Effect": "Allow",
"Action": [
"ec2:DescribeRegions",
"s3:GetAccountPublicAccessBlock",
"s3:GetBucketAcl",
"s3:GetBucketPolicy",
"s3:GetBucketPolicyStatus",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketTagging",
"s3:ListAllMyBuckets"
],
"Resource": "*"
}
]
}
Always current at docs/iam-policy.json, or run
sar-aws-faultline iam-policy. AWS's managed SecurityAudit policy also
covers everything here, if you would rather not manage a custom one.
Compliance mapping, honestly
Each check maps to control references. The mapping is deliberately modest about what it claims.
Two hops, with different confidence. Mapping a check to a CIS AWS Foundations recommendation is objective — recommendations are numbered, prescriptive and testable. Mapping that to a SOC 2 Trust Services Criterion is interpretive: the TSC are principles-based, and there is no authoritative AWS-configuration-to-TSC mapping. Every interpretive mapping must declare the objective control it was reasoned from, so you can audit the inference instead of taking it on trust.
Nothing is ever "satisfied". The relationship vocabulary has exactly two
values, supports and partially_supports, and a test fails the build if
anyone adds a third. A configuration scanner cannot establish that a control is
met; it produces one input to that judgement.
What this tool does not see. AWS configuration is roughly a quarter of a SOC 2 audit. Access reviews, onboarding and offboarding, change management, vendor management, incident response, security training and written policy are the rest, and no scanner can see any of it. This tool is not a substitute for Vanta, Drata or Secureframe — those cover the organisational side and barely touch what this does. It is also not a substitute for an auditor.
Green output does not mean compliant. It means no gaps were found in the things this tool looks at. That is a useful thing to know and a much smaller thing than compliance.
Mapping data lives in src/sar_aws_faultline/data/
as TOML, one file per framework, reviewable without reading Python. Adding a
framework touches no code.
Control identifiers and short paraphrased titles only. The AICPA's Trust Services Criteria text and CIS's benchmark text are both licensed and are not reproduced in this repository.
Why this exists when Prowler does
It mostly should not, and you should probably use Prowler.
Prowler runs 600+ AWS checks across 80+ services, maps to 40+ compliance frameworks including a 156-check SOC 2 framework, exports HTML/CSV/JSON, and has a funded team behind it. For a real audit, use Prowler. This tool does not try to match it and will not.
AWS Security Hub is the managed option and a good floor if you are already all-in on AWS. Per-check pricing across accounts and regions adds up, and findings live in one account's console.
ScoutSuite has not been updated since May 2024.
What this does that they do not:
- Ordering by audit impact, not just severity. Nothing else models the second axis, so nothing else can tell you a medium-severity finding is the one that will stop your audit.
- Cost of remediation on every finding. Nobody puts the monthly bill of turning on a control next to the finding that says you should.
- A scan short enough to actually read. Prowler's full run takes 15–40 minutes and produces hundreds of findings. This targets under a minute and a page.
- Fix steps written for someone who does not already know. Console path and CLI one-liner, plus what the fix might break.
If you want completeness, use Prowler. If you want to know what to do on Monday morning, try this.
Checks
Currently one, with more landing incrementally. sar-aws-faultline checks lists
what is present in your installed version.
| Check | Severity | Audit impact | Effort | Cost/mo |
|---|---|---|---|---|
s3-bucket-public-access |
critical | blocker | minutes | $0 |
Planned areas: encryption at rest, public exposure, IAM hygiene, logging and
monitoring, key management, data protection. Scope is intentionally curated —
see the TODO checklist and what was cut (and why) in
docs/DECISIONS.md.
Limitations
- Single account. No AWS Organizations or multi-account aggregation.
- Point in time. Not continuous monitoring.
- Configuration only. Cannot see your processes, your people, or your code.
- No remediation. By design; see above.
- Curated, not complete. Passing every check means passing every check. It does not mean your account is secure.
--all-regionsis slower than it looks on accounts with many enabled regions.
Adding a check
Drop a file in src/sar_aws_faultline/checks/. Nothing else changes — the
registry discovers it, the IAM policy picks up its permissions, and the
renderers handle it. Third-party distributions can ship checks via the
sar_aws_faultline.checks entry-point group.
See CONTRIBUTING.md.
Related
Part of a set of small, single-purpose AWS tools:
sar-aws-baseline— Terraform modules for a secure account baseline.
Each stands alone; there is no dependency between them.
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sar_aws_faultline-0.1.0.tar.gz.
File metadata
- Download URL: sar_aws_faultline-0.1.0.tar.gz
- Upload date:
- Size: 56.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
05d73b13ebea7f9e88b7fa75c5956707270102d32d47094b747964b067c0d5e6
|
|
| MD5 |
7442dc88d1c5e00122f6428c316519b4
|
|
| BLAKE2b-256 |
58e79af1b7979e19b9f52442130f7cddb12ed80ca3344404a72ebaa12edcfaf2
|
Provenance
The following attestation bundles were made for sar_aws_faultline-0.1.0.tar.gz:
Publisher:
release.yml on achutharaman/sar-aws-faultline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sar_aws_faultline-0.1.0.tar.gz -
Subject digest:
05d73b13ebea7f9e88b7fa75c5956707270102d32d47094b747964b067c0d5e6 - Sigstore transparency entry: 2599485748
- Sigstore integration time:
-
Permalink:
achutharaman/sar-aws-faultline@2ce87c5a9c01e4f22eb2a3dfae8f852b75679594 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/achutharaman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2ce87c5a9c01e4f22eb2a3dfae8f852b75679594 -
Trigger Event:
push
-
Statement type:
File details
Details for the file sar_aws_faultline-0.1.0-py3-none-any.whl.
File metadata
- Download URL: sar_aws_faultline-0.1.0-py3-none-any.whl
- Upload date:
- Size: 46.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7c79a3f4ec44c7d3e291af9d8e320d7a96ead5e5de159f4efc70248b34491990
|
|
| MD5 |
855c069dcbd35c93f4ea17725f357749
|
|
| BLAKE2b-256 |
f986b9c285d2a4b5c324780b9cd71fecb46cdc88fb6c51582386f15e024865c2
|
Provenance
The following attestation bundles were made for sar_aws_faultline-0.1.0-py3-none-any.whl:
Publisher:
release.yml on achutharaman/sar-aws-faultline
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sar_aws_faultline-0.1.0-py3-none-any.whl -
Subject digest:
7c79a3f4ec44c7d3e291af9d8e320d7a96ead5e5de159f4efc70248b34491990 - Sigstore transparency entry: 2599486062
- Sigstore integration time:
-
Permalink:
achutharaman/sar-aws-faultline@2ce87c5a9c01e4f22eb2a3dfae8f852b75679594 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/achutharaman
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2ce87c5a9c01e4f22eb2a3dfae8f852b75679594 -
Trigger Event:
push
-
Statement type: