Skip to content

OCPBUGS-87829: Scope minted AWS IAM policies to cluster-owned resources#1043

Open
dlom wants to merge 1 commit into
openshift:masterfrom
dlom:OCPBUGS-87829
Open

OCPBUGS-87829: Scope minted AWS IAM policies to cluster-owned resources#1043
dlom wants to merge 1 commit into
openshift:masterfrom
dlom:OCPBUGS-87829

Conversation

@dlom

@dlom dlom commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

xref: OCPBUGS-87829

Add an implicit StringEquals condition to every Allow statement in minted IAM user policies, requiring the standard kubernetes.io/cluster infraName tag (with a value of "owned"). This restricts minted credentials to resources tagged as belonging to the cluster, reducing the blast radius if credentials are compromised (CVE-2026-10843).

The CVE advisory suggests tightening Resource ARNs from "*" to specific ARNs, but this isn't feasible: CredentialsRequest manifests are authored before cluster infrastructure exists, so resource ARNs for specific clusters are not known when the CR is authored.

the aws:ResourceTag condition key is not evaluated by all AWS api actions. For actions that do not support it, AWS silently ignores the condition and the action is allowed unconditionally. These actions are never destructive. This means that the fix only affects destructive actions, the same category of actions explicitely called out by the CVE.

The condition is not applied to Deny statements (this would actually narrow and weaken the policy), nor is it applied to the auto-generated iam:GetUser self-lookup statement, which is already scoped to just the own user's ARN.

Summary by CodeRabbit

  • New Features
    • Generated minted-user IAM policies are now infrastructure-aware, adding aws:ResourceTag/kubernetes.io/cluster/<infra> StringEquals-scoped permissions alongside unscoped ones where applicable.
  • Bug Fixes
    • Cluster tag validation and user tagging now consistently use the expected tag value, and statement conditions are preserved while Deny rules remain unchanged.
  • Tests / Automation
    • Added unit tests covering infra scoping behavior, action classification, and statement splitting.
    • Added an automation script to verify payload AWS action coverage against the expected scoped/unscoped action sets.

@openshift-ci-robot openshift-ci-robot added jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. labels Jun 25, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@dlom: This pull request references Jira Issue OCPBUGS-87829, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

xref: OCPBUGS-87829

Add an implicit StringEquals condition to every Allow statement in minted IAM user policies, requiring the standard kubernetes.io/cluster infraName tag (with a value of "owned"). This restricts minted credentials to resources tagged as belonging to the cluster, reducing the blast radius if credentials are compromised (CVE-2026-10843).

The CVE advisory suggests tightening Resource ARNs from "*" to specific ARNs, but this isn't feasible: CredentialsRequest manifests are authored before cluster infrastructure exists, so resource ARNs for specific clusters are not known when the CR is authored.

the aws:ResourceTag condition key is not evaluated by all AWS api actions. For actions that do not support it, AWS silently ignores the condition and the action is allowed unconditionally. These actions are never destructive. This means that the fix only affects destructive actions, the same category of actions explicitely called out by the CVE.

The condition is not applied to Deny statements (this would actually narrow and weaken the policy), nor is it applied to the auto-generated iam:GetUser self-lookup statement, which is already scoped to just the own user's ARN.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. label Jun 25, 2026
@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 4ca9414b-cdf7-4f7e-a19e-284c0d274708

📥 Commits

Reviewing files that changed from the base of the PR and between fd2e802 and 5da5c51.

📒 Files selected for processing (5)
  • hack/verify-action-maps.sh
  • pkg/aws/actuator/actuator.go
  • pkg/aws/actuator/actuator_test.go
  • pkg/aws/utils.go
  • pkg/aws/utils_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • hack/verify-action-maps.sh
  • pkg/aws/actuator/actuator.go
  • pkg/aws/utils.go
  • pkg/aws/actuator/actuator_test.go

Walkthrough

Infrastructure-aware IAM policy generation now scopes supported allow statements with resource-tag conditions, threads the infrastructure name through minted-user flows, and aligns cluster tag validation and tagging with shared tag constants. Tests and verification tooling cover the new action classification.

Changes

Infra-tag-aware IAM policy updates

Layer / File(s) Summary
Shared tag and action primitives
pkg/aws/utils.go
Exports the infra resource tag prefix and value, adds scoped and unscoped action maps, classifies actions for infra-tag conditions, and notes that IAM simulation omits aws:ResourceTag context.
Minted-user policy and cluster tag updates
pkg/aws/actuator/actuator.go
getDesiredUserPolicy accepts infraName, adds infra-tag StringEquals conditions for supported allow statements, and passes infra.Status.InfrastructureName through minted-user policy paths. userHasExpectedTags and tagUser use ccaws.InfraResourceTagValue for kubernetes.io/cluster/<infraName> tags.
Policy conditioning tests
pkg/aws/actuator/actuator_test.go
The new test unmarshals generated policy JSON and checks conditioning, statement splitting, preserved conditions, Deny handling, the iam:GetUser statement, and unknown-action behavior.
Action-map coverage and verification
hack/verify-action-maps.sh, pkg/aws/utils_test.go
The new verification script compares release payload AWS actions against the code-defined action maps, and the new tests cover payload action classification plus map disjointness and formatting.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: scoping minted AWS IAM policies to cluster-owned resources.
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.
Stable And Deterministic Test Names ✅ Passed Added test titles are static literals; the only parameterized subtest uses fixed payload action strings, not run-specific data.
Test Structure And Quality ✅ Passed The added tests are plain testify unit tests, not Ginkgo specs; they create no cluster resources and use no Eventually/Consistently waits, matching repo patterns.
Microshift Test Compatibility ✅ Passed Only standard Go unit tests were added; no Ginkgo e2e tests or MicroShift-unsupported OpenShift APIs/features are referenced.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PASS: The PR only adds Go unit tests under pkg/aws using testing/testify; no Ginkgo e2e tests or multi-node/SNO assumptions were introduced.
Topology-Aware Scheduling Compatibility ✅ Passed Diff only touches AWS IAM policy/tag logic, tests, and a bash verifier; no manifests, controllers, affinity, node selectors, or topology checks were added.
Ote Binary Stdout Contract ✅ Passed The touched Go files add no stdout writes in main/init/TestMain/setup code; the only new init just registers a scheme, and the OTE entrypoint remains stderr-safe.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the changes are unit tests and helper code only, with no IPv4-only or external connectivity assumptions.
No-Weak-Crypto ✅ Passed Touched files add IAM policy/tag logic only; no MD5/SHA1/DES/RC4/ECB, custom crypto, or secret/token constant-time comparison code was introduced.
Container-Privileges ✅ Passed Touched files are Go/tests and a Bash script; no container/K8s manifests were changed and no privileged/hostPID/hostNetwork/SYS_ADMIN/allowPrivilegeEscalation settings were found.
No-Sensitive-Data-In-Logs ✅ Passed No new logging of secrets, tokens, or PII was added; the new logs only emit user names, infra names, cluster UUIDs, and tag key/value metadata.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@dlom

dlom commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

/assign @JoelSpeed

@openshift-ci openshift-ci Bot requested a review from jstuever June 25, 2026 04:12
@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 25, 2026
@openshift-ci-robot

Copy link
Copy Markdown
Contributor

@dlom: This pull request references Jira Issue OCPBUGS-87829, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

xref: OCPBUGS-87829

Add an implicit StringEquals condition to every Allow statement in minted IAM user policies, requiring the standard kubernetes.io/cluster infraName tag (with a value of "owned"). This restricts minted credentials to resources tagged as belonging to the cluster, reducing the blast radius if credentials are compromised (CVE-2026-10843).

The CVE advisory suggests tightening Resource ARNs from "*" to specific ARNs, but this isn't feasible: CredentialsRequest manifests are authored before cluster infrastructure exists, so resource ARNs for specific clusters are not known when the CR is authored.

the aws:ResourceTag condition key is not evaluated by all AWS api actions. For actions that do not support it, AWS silently ignores the condition and the action is allowed unconditionally. These actions are never destructive. This means that the fix only affects destructive actions, the same category of actions explicitely called out by the CVE.

The condition is not applied to Deny statements (this would actually narrow and weaken the policy), nor is it applied to the auto-generated iam:GetUser self-lookup statement, which is already scoped to just the own user's ARN.

Summary by CodeRabbit

  • New Features

  • AWS credential handling now respects infrastructure-specific tags when generating and validating IAM policies.

  • Permission checks can now include infrastructure-scoped context for more accurate access simulation.

  • Bug Fixes

  • Fixed policy and tag matching so AWS user credentials are validated against the correct cluster tag value.

  • Improved handling of IAM policy conditions to preserve existing conditions while adding infrastructure-based constraints where needed.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 47.31%. Comparing base (9d6f071) to head (5da5c51).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1043      +/-   ##
==========================================
+ Coverage   47.06%   47.31%   +0.24%     
==========================================
  Files          97       97              
  Lines       12560    12608      +48     
==========================================
+ Hits         5911     5965      +54     
+ Misses       5994     5987       -7     
- Partials      655      656       +1     
Files with missing lines Coverage Δ
pkg/aws/actuator/actuator.go 69.24% <100.00%> (+1.45%) ⬆️
pkg/aws/utils.go 86.11% <100.00%> (+2.24%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/aws/actuator/actuator.go (1)

236-278: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Thread InfrastructureName into this simulation path too.

The minted-user policy path now compares policies with infra.Status.InfrastructureName, but the fallback/current-credential simulation below still builds ccaws.SimulateParams with only Region. Any principal whose policy depends on the new aws:ResourceTag/kubernetes.io/cluster/<infra> condition can be simulated without that context and look insufficient even when the tagged-resource policy is valid.

Proposed fix
-			region, err := awsutils.LoadInfrastructureRegion(a.Client, logger)
-			if err != nil {
-				return true, err
-			}
+			infra, err := utils.GetInfrastructure(a.Client)
+			if err != nil {
+				return true, err
+			}
+			region, err := awsutils.LoadInfrastructureRegion(a.Client, logger)
+			if err != nil {
+				return true, err
+			}
 			simParams := &ccaws.SimulateParams{
-				Region: region,
+				Region:    region,
+				InfraName: infra.Status.InfrastructureName,
 			}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/aws/actuator/actuator.go` around lines 236 - 278, The fallback simulation
path in the actuator still omits InfrastructureName, so policies using the
aws:ResourceTag/kubernetes.io/cluster/<infra> condition can be evaluated
incorrectly. Update the ccaws.SimulateParams construction in this branch to
carry infra.Status.InfrastructureName as well, mirroring the minted-user path’s
use of getDesiredUserPolicy/awsPolicyEqualsDesiredPolicy, and thread that value
through any simulation helper that consumes SimulateParams.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/aws/actuator/actuator.go`:
- Around line 236-278: The fallback simulation path in the actuator still omits
InfrastructureName, so policies using the
aws:ResourceTag/kubernetes.io/cluster/<infra> condition can be evaluated
incorrectly. Update the ccaws.SimulateParams construction in this branch to
carry infra.Status.InfrastructureName as well, mirroring the minted-user path’s
use of getDesiredUserPolicy/awsPolicyEqualsDesiredPolicy, and thread that value
through any simulation helper that consumes SimulateParams.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e41cf280-6879-4c47-8e5b-dd77167b9c21

📥 Commits

Reviewing files that changed from the base of the PR and between 9d6f071 and 11b8ad9.

📒 Files selected for processing (4)
  • pkg/aws/actuator/actuator.go
  • pkg/aws/actuator/actuator_test.go
  • pkg/aws/utils.go
  • pkg/operator/credentialsrequest/credentialsrequest_controller_test.go

@JoelSpeed

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 25, 2026
@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: dlom, JoelSpeed

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot removed the lgtm Indicates that a PR is ready to be merged. label Jun 25, 2026
@openshift-ci

openshift-ci Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

New changes are detected. LGTM label has been removed.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@hack/verify-action-maps.sh`:
- Around line 21-31: The no-argument release image resolution path uses curl
without checking that it is installed, so the preflight should fail earlier with
a clear missing-dependency error. Update the command checks at the top of
verify-action-maps.sh to include curl alongside oc, jq, and yq, and keep the
RELEASE_IMAGE fallback flow unchanged so the missing binary is caught before
attempting the nightly lookup.
- Around line 107-113: The extraction currently scans every quoted
service:Action string in utils_test.go, so it can be satisfied by unrelated test
samples instead of only the payload list. Update verify-action-maps.sh to limit
the grep/sort pipeline to the payloadAWSActions section in
pkg/aws/utils_test.go, using the payloadAWSActions symbol as the anchor so only
canonical payload actions are counted.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a32a2ba9-6f07-443a-8aaf-155980e53c11

📥 Commits

Reviewing files that changed from the base of the PR and between 6ef3407 and fd2e802.

📒 Files selected for processing (5)
  • hack/verify-action-maps.sh
  • pkg/aws/actuator/actuator.go
  • pkg/aws/actuator/actuator_test.go
  • pkg/aws/utils.go
  • pkg/aws/utils_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/aws/actuator/actuator_test.go
  • pkg/aws/utils.go
  • pkg/aws/actuator/actuator.go

Comment thread hack/verify-action-maps.sh Outdated
Comment thread hack/verify-action-maps.sh
Add an implicit StringEquals condition to every Allow statement in
minted IAM user policies, requiring the standard kubernetes.io/cluster
infraName tag (with a value of "owned"). This restricts minted
credentials to resources tagged as belonging to the cluster, reducing
the blast radius if credentials are compromised (CVE-2026-10843).

The CVE advisory suggests tightening Resource ARNs from "*" to specific
ARNs, but this isn't feasible: CredentialsRequest manifests are authored
before cluster infrastructure exists, so resource ARNs for specific
clusters are not known when the CR is authored.

Not all AWS actions support the aws:ResourceTag condition. Actions that
create new resources fail (because the resource doesn't exist yet).
Describe and List actions lack resource-level permissions. Some services
don't support it at all. However, within the payload, the list is both
finite and rarely changed. As such, we can easily classify the entire
list into supported/incompatible categories. Unrecognized actions
produce an error state, with directions pointing the developer to update
the classification list in the CCO.

The condition is not applied to Deny statements (this would actually
narrow and weaken the policy), nor is it applied to the auto-generated
iam:GetUser self-lookup statement, which is already scoped to just the
own user's ARN.
@dlom

dlom commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

/test e2e-upgrade

@dlom

dlom commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

/override ci/prow/security

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@dlom: Overrode contexts on behalf of dlom: ci/prow/security

Details

In response to this:

/override ci/prow/security

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@dlom: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@dlom

dlom commented Jun 26, 2026

Copy link
Copy Markdown
Contributor Author

/payload 4.22 nightly blocking

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@dlom: trigger 13 job(s) of type blocking for the nightly release of OCP 4.22

  • periodic-ci-openshift-release-main-nightly-4.22-e2e-aws-ovn-serial-1of2
  • periodic-ci-openshift-release-main-nightly-4.22-e2e-aws-ovn-serial-2of2
  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-upgrade-ovn-single-node
  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-techpreview
  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-techpreview-serial-1of3
  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-techpreview-serial-2of3
  • periodic-ci-openshift-release-main-ci-4.22-e2e-aws-ovn-techpreview-serial-3of3
  • periodic-ci-openshift-release-main-nightly-4.22-e2e-aws-ovn-upgrade-fips
  • periodic-ci-openshift-release-main-ci-4.22-e2e-azure-ovn-upgrade
  • periodic-ci-openshift-release-main-ci-4.22-upgrade-from-stable-4.21-e2e-gcp-ovn-rt-upgrade
  • periodic-ci-openshift-hypershift-release-4.22-periodics-e2e-aws-ovn-conformance
  • periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ipi-ovn-ipv4
  • periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ipi-ovn-ipv6

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/49a327b0-71b3-11f1-8eaa-a502797692f3-0

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/severity-important Referenced Jira bug's severity is important for the branch this PR is targeting. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants