The IAM policy Kulshan runs with.
The composed policy contains 160 unique read-only actions and zero create, update, modify, or delete actions. Verify the hash, inspect the JSON, and decide whether the access boundary fits your environment.
Kulshan/iam/per-check/. Composed at release time, attested by hash.What the policy allows.
Plain-language summary. Every line below maps to read-only AWS APIs. The full action list is in the JSON file above.
Decrypt. No GenerateDataKey. No cryptographic operations.What it explicitly does NOT allow.
Verbs the policy never grants. If you find a Kulshan code path that calls one of these, that is a bug, and it should be reported to [email protected].
- No
Put,Create,Update,Modify,Delete, orTerminateon any service. - No
iam:CreateAccessKey,iam:UpdateLoginProfile,iam:CreateUser, or any IAM mutation. - No
sts:AssumeRolein the policy itself. Kulshan uses your existing credential chain; assuming a role is your decision, not the policy's. - No
s3:GetObject. The bucket configuration is readable; the bucket contents are not. - No
kms:Decrypt,kms:GenerateDataKey,kms:Encrypt, or any cryptographic operation. - No
ec2:RunInstances,ec2:TerminateInstances,ec2:CreateTags, or any compute-lifecycle action. - No
rds:Modify*,lambda:UpdateFunctionCode,secretsmanager:GetSecretValue, or any other resource modification or secret access.
Verify it yourself.
Download the JSON, hash it locally, and compare to the SHA256 above. If the two match, the file you have is the file we ship.
$ shasum -a 256 Kulshan-readonly.json
6533e48168c2a4ce8e96f383f42534a9f05575ad459f1e5b9f86dcbac632678f Kulshan-readonly.json
If the hash does not match, something is wrong. Email [email protected].
Per-pack policies.
Each pack ships its own minimum-viable policy. Attach only the packs you intend to run. Per-pack totals do not add up to 160 because some read-only actions are reused across multiple checks. The composed policy de-duplicates shared actions into 160 unique IAM actions.
Trust Ledger.
Corrections, disclosures, and integrity events. Newest first.
2026-07-20 // v0.4.2
Three S3 entries in our published IAM policy used AWS API operation names instead of IAM action names. They granted nothing. More importantly, the scanner could treat the resulting authorization failure as a clean result, meaning a user applying our published least-privilege policy could receive a false clean for an affected S3 check.
We corrected the IAM action names and changed the scanner so a failed evaluation is reported as "could not check," with the denied action named. A check is now marked clean only when the required evidence was successfully retrieved and evaluated.
s3:GetBucketEncryption, s3:GetBucketLifecycleConfiguration, s3:GetBucketReplications3:GetEncryptionConfiguration, s3:GetLifecycleConfiguration, s3:GetReplicationConfigurationReuse freely under CC BY 4.0. Credit: MissionFinOps, missionfinops.com.
This applies to the policy file (kulshan-readonly.json and the per-pack files in kulshan/iam/per-check/) only. The CC BY 4.0 license on the policy file is in addition to the Apache 2.0 license that covers the rest of the Kulshan codebase.
If your team or tool adopts this policy as a baseline, no permission needed. A link back is appreciated, not required.