Skip to content

fix(rds-postgres-server): grant KMS permissions for storage encryption CMK - #10

Merged
sebastiancorrea81 merged 5 commits into
mainfrom
fix/rds-postgres-server-kms-permissions
Aug 24, 2026
Merged

fix(rds-postgres-server): grant KMS permissions for storage encryption CMK#10
sebastiancorrea81 merged 5 commits into
mainfrom
fix/rds-postgres-server-kms-permissions

Conversation

@sebastiancorrea81

Copy link
Copy Markdown
Contributor

Summary

  • rds-postgres-server/deployment always creates its own customer-managed KMS key for RDS storage encryption (required for AVD-AWS-0079 compliance, not optional), but specs/requirements/aws granted no kms:* actions at all — create-rds-postgresql-server failed at apply time with AccessDenied on kms:CreateKey.
  • Adds a tag-scoped KMS policy to the rds-postgres-server permissions role, gated on the managed-by=nullplatform tag the deployment module already applies to the key it creates — not "Resource": "*" — so the role can create/manage only the CMKs it tags itself and can never touch, disable, or schedule deletion of any other KMS key in the account.
  • Exposes the new policy's ARN as rds_kms_policy_arn output, matching the existing rds_policy_arn / rds_sg_policy_arn / rds_secretsmanager_policy_arn outputs.

Why each permission is here (found via live testing against a real account, iterating on each AccessDenied)

  • kms:CreateKey / kms:TagResource — create the CMK and tag it.
  • kms:GetKeyPolicy — the AWS provider reads the key policy back right after creating aws_kms_key.rds.
  • kms:CreateAlias / kms:DeleteAlias / kms:UpdateAlias on both the tag-scoped key statement and a separate alias-ARN-scoped statement — these actions authorize against the alias ARN and the target key ARN as two independent resource checks.
  • kms:ListAliases — KMS has no DescribeAlias API; the provider reads an alias back via ListAliases, which only supports "Resource": "*" (no per-item ARN/tag condition exists for this action). Read-only, exposes alias names only.
  • kms:CreateGrant / kms:ListGrants / kms:RevokeGrant, kms:EnableKeyRotation / kms:GetKeyRotationStatus, kms:ScheduleKeyDeletion / kms:CancelKeyDeletion, kms:ListResourceTags, kms:DescribeKey — standard lifecycle management of the CMK the role itself created.

Test plan

  • Applied against a real AWS account (log-controller-test), with the rds-postgres-server requirements module pointed at this branch.
  • Ran create-rds-postgresql-server end-to-end through the actual nullplatform agent — completed successfully (Apply complete: 8 added, 0 changed, 0 destroyed), RDS instance + CMK + alias + Secrets Manager secret all created.
  • Verified the secret_kms_key_id (bring-your-own-CMK for the Secrets Manager secret) flow separately with an external customer-managed key — worked without needing any change to this policy.
  • Same CMK-creation pattern likely affects aurora-postgres-server (services-postgresql-aurora) — not yet tested/fixed there.

sebas_correa added 5 commits August 24, 2026 12:32
…e encryption

rds-postgres-server/deployment always creates its own customer-managed KMS
key for RDS storage encryption (required for AVD-AWS-0079 compliance, not
optional), but specs/requirements/aws granted no kms:* actions at all,
causing CreateKey/TagResource to fail with AccessDenied at apply time.

Scope the new policy by the "managed-by=nullplatform" tag the deployment
module already applies to the key, rather than "Resource": "*", so the role
can only create/manage CMKs it tagged itself and can never touch any other
KMS key in the account.
Live test surfaced a second missing permission after the previous
kms:CreateKey/TagResource fix: the AWS provider reads the key policy back
right after creating aws_kms_key.rds, which needs kms:GetKeyPolicy. Add it
to the same tag-scoped ManageOwnCMK statement.
Live test surfaced a third missing permission: kms:CreateAlias authorizes
against BOTH the alias ARN and the target key ARN as separate resource
checks. The previous fix only covered the alias-ARN side (ManageOwnAlias);
add the same three actions to the tag-scoped ManageOwnCMK statement so the
key-side check passes too.
Live test surfaced a fourth missing permission: KMS has no DescribeAlias
API, so the AWS provider reads aws_kms_alias back via ListAliases, which
only supports "Resource": "*" (it enumerates every alias in the
account/region, with no per-item ARN or tag condition available). Read-only:
exposes alias names, not key material or policies.
…licy

Keep the section header/one-liner pattern the rest of the file already
uses; the detailed rationale lives in the PR description instead.
@sebastiancorrea81
sebastiancorrea81 merged commit cd12953 into main Aug 24, 2026
6 checks passed
@sebastiancorrea81
sebastiancorrea81 deleted the fix/rds-postgres-server-kms-permissions branch August 24, 2026 21:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant