You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sec(iac/aws): deploy role grants account-wide kms:Decrypt and CreateGrant unconditioned #253
The KMS statement in the CI/CD deploy role's networking policy grants kms:CreateGrant, kms:Decrypt, kms:Encrypt, kms:GenerateDataKey and kms:DescribeKey on Resource = "*" with no Condition. Every other KMS grant in ci-cd-permissions/ is gated on an ARN prefix or on aws:ResourceTag/Project (KMSAliasMutate, KMSReadTaggedOnly, KMSTagOnCreate, KMSMutateTaggedOnly), and KMSReadTaggedOnly gates the far weaker kms:GetKeyPolicy explicitly to stop account-wide key reconnaissance. Because AWS CMKs carry the default key policy that delegates to IAM, this statement really does reach unrelated keys in the account. Blast radius is our own hosted AWS account, not customer accounts.
Location
terraform/environments/aws/ci-cd-permissions/policy_networking.tf:166 at 3c0f8ac94048a2c36fce5ccddee54e6c4849a5cd (the KMS Sid spans lines 164-175)
Failure scenario
A leaked GitHub Actions OIDC token assumes cudly-terraform-deploy and calls kms:Decrypt against any CMK in the account, including keys belonging to unrelated workloads that share it. kms:CreateGrant lets it hand Decrypt on any CMK to a grantee principal it controls, and that grant survives the deploy role later being revoked.
Add the same StringEqualsIgnoreCase condition on aws:ResourceTag/Project that KMSMutateTaggedOnly (policy_compute.tf:347-375) already uses, keeping only kms:DescribeKey unconditioned if a plan-time lookup needs it. Note the ACM (:139) and Route53 (:152) statements in the same file are also uncommented "*" grants, though those actions are read-mostly.
Found by the 2026-09-02 codebase audit, finding A13-004, reported by one reviewer and independently confirmed by a second. Full report: docs/audits/codebase-audit-2026-09-02.md.
Verified against current main (7a541dae919249c6d360d432d1f1cdc6b34cef9e): fully fixed.
The unconditioned Sid = "KMS" statement (kms:CreateGrant, kms:Decrypt, kms:Encrypt, kms:GenerateDataKey, kms:DescribeKey on Resource = "*") no longer exists in terraform/environments/aws/ci-cd-permissions/policy_networking.tf — the entire block was deleted rather than narrowed, since nothing on the deploy path consumes any of these actions (AWS-managed keys don't consult the caller's identity policy).
Fixed by merged PR #4 (sec(iac/aws): drop unconditioned account-wide KMS data-plane grant from deploy role, merge commit 381d3c5cd6ac6a956dc541ad49ab007a8bbca2d0).
A regression guard now exists: TestKMSDataPlaneActionsAreNotUnconditionallyGranted in terraform/environments/aws/ci-cd-permissions/policy_guard_test.go:1703, which asserts these actions are never granted without a aws:ResourceTag/Project condition (and kms:GrantIsForAWSResource for CreateGrant) across all five policy files.
Activity
cristim commentedon Sep 28, 2026
Verified against current
main(7a541dae919249c6d360d432d1f1cdc6b34cef9e): fully fixed.The unconditioned
Sid = "KMS"statement (kms:CreateGrant,kms:Decrypt,kms:Encrypt,kms:GenerateDataKey,kms:DescribeKeyonResource = "*") no longer exists interraform/environments/aws/ci-cd-permissions/policy_networking.tf— the entire block was deleted rather than narrowed, since nothing on the deploy path consumes any of these actions (AWS-managed keys don't consult the caller's identity policy).Fixed by merged PR #4 (
sec(iac/aws): drop unconditioned account-wide KMS data-plane grant from deploy role, merge commit381d3c5cd6ac6a956dc541ad49ab007a8bbca2d0).A regression guard now exists:
TestKMSDataPlaneActionsAreNotUnconditionallyGrantedinterraform/environments/aws/ci-cd-permissions/policy_guard_test.go:1703, which asserts these actions are never granted without aaws:ResourceTag/Projectcondition (andkms:GrantIsForAWSResourceforCreateGrant) across all five policy files.Closing as completed; no residual work.