Local-first, read-only AWS audit CLI. Ten audit packs, one command, zero writes.
Project description
Kulshan
Read-only AWS audit CLI.
pip install kulshan
kulshan report
One command. One report. Zero writes to your AWS account.
Documentation | IAM Policy | Changelog
What Kulshan does
Ten read-only audit packs in one CLI. Cost anomalies, security posture, waste detection, DR gaps, drift, tag compliance, observability blind spots, quota headroom, and network topology - scored 0-100, exportable as HTML, JSON, SARIF, or CSV.
Reads your Cost Explorer data and your own CUR/Data Export Parquet files in place. No data leaves your machine. No SaaS account. No telemetry. Nothing to opt out of, because nothing exists.
What Kulshan does not do
- Does not write to AWS. The IAM policy contains only Get, List, and Describe actions.
- Does not phone home. No telemetry, no update checks, no analytics.
- Does not require infrastructure. No databases, no containers, no SaaS.
- Does not hold credentials. Uses the same credential chain as the AWS CLI.
Install
pip install kulshan
Python 3.9+. macOS, Linux, Windows. Optional extras: kulshan[pdf], kulshan[excel], kulshan[pptx], kulshan[mcp], kulshan[slm], or kulshan[all].
Credentials
If aws sts get-caller-identity works, Kulshan works.
aws login
kulshan report
Named profiles, environment variables, and role assumption all work:
kulshan --profile production report
kulshan --role-arn arn:aws:iam::123456789012:role/KulshanAudit report
Run kulshan doctor to verify connectivity and permissions without incurring any cost.
The 10 Audit Packs
| Pack | What it watches |
|---|---|
cost |
Anomalies (z-score, IQR, MAD), commitment gaps, spend acceleration, forecasts |
security |
IAM, encryption, network exposure, logging, public access, GuardDuty |
sweep |
Orphaned volumes, unused EIPs, idle LBs, detached ENIs, empty repos |
dr |
Backup coverage, single-AZ, single points of failure, missing replication |
age |
EOL runtimes, expiring certs, stale AMIs, outdated engines |
drift |
CloudFormation drift, IaC coverage, severity classification |
tag |
Missing required tags, unattributed spend, key inconsistencies |
pulse |
Alarm gaps, missing metric filters, blind spots |
limit |
Quota headroom, at-limit services, scaling risk |
topo |
CIDR overlaps, route integrity, peering issues, TGW misconfigs |
kulshan report # cost only (default, ~$0.15)
kulshan report --packs security,sweep # specific packs (free APIs)
kulshan report --packs all --regions us-east-1 # full diagnostic
Automatic Environment Isolation
On first run, Kulshan identifies your AWS principal, creates an isolated local environment, and routes all data there. Different identities get separate environments. No flags required.
✓ Created environment readonlyrole-cedar
Using readonlyrole-cedar · account 1234…5678
When CUR data reveals a payer account, the environment binds to that payer. Multiple identities accessing the same payer can be reconciled into a unified timeline:
kulshan workspace reconcile
Workspaces with multiple connections produce consolidated reports automatically - one scan, all connections, deduplicated findings, per-connection coverage metadata.
CUR / Data Export Investigation
Query your CUR Parquet files locally or from S3. No Athena, no Glue, no data warehouse. DuckDB queries in place.
kulshan cur validate --path ./cur/
kulshan investigate cost --path ./cur/ --month 2024-06
kulshan investigate ec2 --cur ./cur/ --month 2024-06
kulshan investigate cost --s3 s3://bucket/prefix/ --month 2024-06
Top movers by service, account, region, usage type. Period-over-period deltas. Resource-level contributors. Tag coverage. All outputs include provenance, evidence IDs, and human_review_required: true.
MCP Server
Kulshan exposes its findings to MCP-compatible agents (Claude Desktop, Cursor, Kiro, others). Deterministic evidence in, agent reasoning out.
kulshan mcp-serve
{
"mcpServers": {
"kulshan": { "command": "kulshan", "args": ["mcp-serve"] }
}
}
Seven tools: kulshan_doctor, kulshan_report, kulshan_quick_security, kulshan_list_packs, kulshan_cur_validate, kulshan_investigate_ec2, kulshan_investigate_cost.
Output Formats
kulshan report -o report.html # Self-contained HTML report
kulshan report --format json -o s.json # Structured, machine-readable
kulshan report --format sarif -o r.sarif # GitHub Security tab
kulshan report --format csv -o f.csv # Spreadsheet / JIRA import
kulshan convert -i scan.json -o r.html # Re-render without re-scanning
Account IDs redacted by default. --show-pii for full IDs. Atomic writes prevent partial files.
CI/CD
kulshan report --packs security --format sarif -o results.sarif --yes --no-history
Exit code 1 when critical findings are present - use as a quality gate. SARIF uploads to GitHub Code Scanning. Full GitHub Actions and GitLab CI examples in docs/ci-cd.md.
Trust and Security
Read-only by construction, not read-only by default. There is no cleanup mode to leave off, no write path to enable. The published IAM policy contains zero actions that create, modify, or delete resources.
- 147 read-only actions, zero write actions. Read every line.
- Reports stay on your machine
- No telemetry, no phone-home
- Open source: Apache 2.0. IAM policy additionally CC BY 4.0.
- Per-pack least-privilege policies at
iam/per-check/ - Compliance metadata: CIS, SOC 2, NIST 800-53, Well-Architected
Quick Reference
kulshan --version # Version
kulshan doctor # Check credentials and permissions
kulshan report # Cost baseline (default)
kulshan report --quick # Skip confirmation
kulshan report -o report.html # HTML report
kulshan report --packs all --regions us-east-1 --deep # Full deep scan
kulshan report --perf # Show API timing
kulshan history # Past scans
kulshan history --direct-only # Current workspace only
kulshan workspace list # All environments
kulshan workspace reconcile # Link shared-payer environments
kulshan shell # Interactive REPL
kulshan convert -i scan.json -o r.html # Re-render
AWS API Cost
Cost pack: ~$0.15 (CE API at $0.01/request). All other packs use free APIs. Kulshan confirms before making CE calls. Use --yes in CI/CD.
About the Name
Kulshan is the Lummi name for the mountain known colonially as Mt. Baker, meaning "great white watcher." The mountain is visible from Mission, BC and is an active volcano in the Cascade Range. We acknowledge the Lummi and Nooksack peoples as the original namers of this mountain.
Maintained by
Mission FinOps - open-source AWS audit tooling.
License
Apache 2.0. Free and open source forever.
Project details
Release history Release notifications | RSS feed
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 kulshan-0.3.4.tar.gz.
File metadata
- Download URL: kulshan-0.3.4.tar.gz
- Upload date:
- Size: 307.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c504963f811d07e0d95e74f2893641dfaa9a7217370163e146fbe43cb4611acb
|
|
| MD5 |
1761975ac6670d5ba2af4181d9edf2d2
|
|
| BLAKE2b-256 |
022bd95b7e5051731fcc56248432076504124fbb2c3b26d8d08a20d55e88282c
|
Provenance
The following attestation bundles were made for kulshan-0.3.4.tar.gz:
Publisher:
publish.yml on MissionFinOps/kulshan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kulshan-0.3.4.tar.gz -
Subject digest:
c504963f811d07e0d95e74f2893641dfaa9a7217370163e146fbe43cb4611acb - Sigstore transparency entry: 2188110683
- Sigstore integration time:
-
Permalink:
MissionFinOps/kulshan@aa90bace80b9fb58911e5d2a088584c6fb3e1da4 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/MissionFinOps
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa90bace80b9fb58911e5d2a088584c6fb3e1da4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file kulshan-0.3.4-py3-none-any.whl.
File metadata
- Download URL: kulshan-0.3.4-py3-none-any.whl
- Upload date:
- Size: 396.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7d4e5bf2183bdeee53a4425c584e00fd62ae15208279dfca76b991e07d07d9a6
|
|
| MD5 |
1343b10ce13bc03a2758a4084742ff79
|
|
| BLAKE2b-256 |
77853d2e3575963880094ee23924f73e5c12ca167ff671f57a41878f80b2e175
|
Provenance
The following attestation bundles were made for kulshan-0.3.4-py3-none-any.whl:
Publisher:
publish.yml on MissionFinOps/kulshan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
kulshan-0.3.4-py3-none-any.whl -
Subject digest:
7d4e5bf2183bdeee53a4425c584e00fd62ae15208279dfca76b991e07d07d9a6 - Sigstore transparency entry: 2188110690
- Sigstore integration time:
-
Permalink:
MissionFinOps/kulshan@aa90bace80b9fb58911e5d2a088584c6fb3e1da4 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/MissionFinOps
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@aa90bace80b9fb58911e5d2a088584c6fb3e1da4 -
Trigger Event:
push
-
Statement type: