Skip to content

fix(iac/aws): case-insensitive tag match on kms:GetKeyPolicy deploy grant - #1514

Merged
cristim merged 1 commit into
mainfrom
fix/kms-advrev-getkeypolicy-case
Jul 27, 2026
Merged

cristim merged 1 commit into
mainfrom
fix/kms-advrev-getkeypolicy-case

Conversation

@cristim

@cristim cristim commented Jul 27, 2026 •

Copy link
Copy Markdown
Member

What

Adversarial-review follow-up to #1496 and #1512 (OIDC signing-key RSA->ECC replace). Switches KMSReadTaggedOnly in policy_compute_b.tf from case-sensitive StringEquals "CUDly" to StringEqualsIgnoreCase.

Why

#1496 discovered that the OIDC signing key is tagged Project=cudly (lowercase): the tag comes from local.common_tags (Project = var.project_name, default "cudly"), which overrides the provider default_tags value "CUDly" for that resource. It fixed KMSMutateTaggedOnly (kms:ScheduleKeyDeletion etc.) to StringEqualsIgnoreCase accordingly.

KMSReadTaggedOnly gates the deploy role's only grant for kms:GetKeyPolicy on the same tag, but was left as case-sensitive StringEquals "CUDly", so by the identical reasoning it never matches the signing key. The AWS provider reads the key policy (kms:GetKeyPolicy) on every aws_kms_key refresh, so once both bootstrap policies are applied the deploy role hits AccessDenied: kms:GetKeyPolicy when refreshing/replacing the signing key, blocking the exact ECC replace #1496/#1512 exist to enable.

This was found by adversarially reviewing both merged PRs: the mutate path was fixed but the read path (GetKeyPolicy) carries the same latent case mismatch.

Confidence

  • The case mismatch and the single-point GetKeyPolicy grant are confirmed by inspection (tag chain traced to local.common_tags -> var.project_name = "cudly"; GetKeyPolicy appears only in KMSReadTaggedOnly).
  • The runtime "blocks the deploy" impact depends on the provider reading + hard-failing on GetKeyPolicy during aws_kms_key refresh (standard behaviour); precise fatality is best confirmed against live AWS. The fix is safe and internally consistent regardless.

Scope of the review (other probes)

  • create_before_destroy on the key only (fix(iac/aws): create_before_destroy on OIDC signing key (follow-up to #1480) #1512): sound — the alias and IAM role-policy are updated in place (UpdateAlias / PutRolePolicy), not replaced, so no cycle and no need for CBD on them; new key is created and the alias repointed before the old key is scheduled for deletion.
  • OIDC/JWKS continuity: the AWS signer caches the public key + kid via sync.Once with no invalidation, so warm Lambda containers can serve a stale JWKS during any signing-key replacement (transient verification mismatch until recycled). Pre-existing app-code behaviour, not introduced by these PRs, out of scope here.
  • Tag-value: confirmed the signing key's Project tag is lowercase cudly.

Test

terraform validate passes on ci-cd-permissions.

Closes nothing; filed as a follow-up fix.

Summary by CodeRabbit

  • Bug Fixes
    • Improved consistency when validating project tags during signing key policy operations, regardless of capitalization.
    • Added clarification around tag matching and key policy refresh behavior.

…rant

Follow-up to #1496. That PR fixed KMSMutateTaggedOnly in policy_compute.tf
to use StringEqualsIgnoreCase after discovering the OIDC signing key is
tagged Project=cudly (lowercase, from local.common_tags / var.project_name),
which overrides the provider default_tags value CUDly and never matched a
case-sensitive StringEquals "CUDly".

KMSReadTaggedOnly in policy_compute_b.tf gates the deploy role's only grant
for kms:GetKeyPolicy on the same tag with case-sensitive StringEquals, so it
does not match the signing key either. The AWS provider reads the key policy
on every aws_kms_key refresh, so the deploy role hits AccessDenied on
kms:GetKeyPolicy when refreshing or replacing the signing key, blocking the
RSA to ECC replace that #1496/#1512 exist to support.

Switch KMSReadTaggedOnly to StringEqualsIgnoreCase for consistency with
KMSMutateTaggedOnly. terraform validate passes.
@cristim cristim added triaged Item has been triaged priority/p1 Next up; this sprint severity/high Significant harm urgency/now Drop other things impact/internal Team-internal only effort/xs Trivial / one-liner type/security Security finding labels Jul 27, 2026
@cristim

cristim commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

No new commits to review since the last review.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6ba2a486-c5ae-4537-8d1b-48d9c81d81a8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The compute_b KMS read policy now matches the Project resource tag case-insensitively when authorizing kms:GetKeyPolicy, with comments documenting the signing key policy behavior.

Changes

KMS tag policy

Layer / File(s) Summary
Update KMS read condition
terraform/environments/aws/ci-cd-permissions/policy_compute_b.tf
KMSReadTaggedOnly changes the Project tag condition from StringEquals to StringEqualsIgnoreCase and adds explanatory comments.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: making the kms:GetKeyPolicy tag match case-insensitive for the deploy grant.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/kms-advrev-getkeypolicy-case

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

effort/xs Trivial / one-liner impact/internal Team-internal only priority/p1 Next up; this sprint severity/high Significant harm triaged Item has been triaged type/security Security finding urgency/now Drop other things

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant