Skip to content

OCPCLOUD-1645: Scope capi-controllers RBAC to least-privilege#585

Open
stefanonardo wants to merge 1 commit into
openshift:mainfrom
stefanonardo:OCPCLOUD-1645
Open

OCPCLOUD-1645: Scope capi-controllers RBAC to least-privilege#585
stefanonardo wants to merge 1 commit into
openshift:mainfrom
stefanonardo:OCPCLOUD-1645

Conversation

@stefanonardo

@stefanonardo stefanonardo commented Jun 8, 2026

Copy link
Copy Markdown

Summary

  • Replace wildcard RBAC rules (apiGroups: ['*'], resources: ['*'], verbs: ['*']) in the openshift-capi-controllers ClusterRole and capi-controllers Role with enumerated, auditable permissions
  • Split namespaced resources out of the ClusterRole into namespace-scoped Roles in openshift-cluster-api, openshift-machine-api, and kube-system — secrets access is no longer cluster-wide
  • Restrict ClusterOperator access to the cluster-api object specifically via resourceNames, and remove the create verb (CVO creates the ClusterOperator, not this operator)
  • Remove the GetOrCreateClusterOperator create fallback in operator_status.go — renamed to GetClusterOperator
  • Derived from code analysis of all controllers (capi-controllers + machine-api-migration) and cross-validated with audit2rbac on a live cluster
  • Adds docs/rbac.md documenting the RBAC structure and /rbac-review skill for repeating this process

Permission justification

Each rule was derived from code analysis and validated against audit2rbac output from an AWS cluster with MachineAPIMigration enabled.

Confirmed by audit2rbac

Scope API Group Resource Verbs Code evidence
ClusterRole config.openshift.io infrastructures get, list, watch corecluster_controller.go:122, infracluster_controller.go:278, kubeconfig.go:85
ClusterRole config.openshift.io clusteroperators list, watch operator_status.go:115 — informer cache (resourceNames not applicable to list/watch)
ClusterRole config.openshift.io clusteroperators (resourceNames: cluster-api) get, patch operator_status.go:115,186, controller_status.go:295
ClusterRole config.openshift.io clusteroperators/status (resourceNames: cluster-api) update, patch operator_status.go:186, controller_status.go:295
ClusterRole config.openshift.io featuregates, clusterversions get, list, watch featuregates.go:50-53
ClusterRole apiextensions.k8s.io customresourcedefinitions get, list, watch audit2rbac confirmed (userAgent: machine-api-migration)
ClusterRole "" nodes get, list, watch, patch, update audit2rbac confirmed (userAgent: cluster-api-controller-manager)
Role: openshift-cluster-api cluster.x-k8s.io clusters, machines, machinesets get, list, watch, create, update, patch, delete corecluster_controller.go:122,152, machine_sync_controller.go:220,656,686,1060, machineset_sync_controller.go:200,838,866,1191
Role: openshift-cluster-api cluster.x-k8s.io clusters/status, machines/status, machinesets/status update, patch corecluster_controller.go:216, machine_sync_controller.go:1365, machineset_sync_controller.go:917
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsclusters get, list, watch, create, patch aws.go:57,90
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsclusters/status update, patch infracluster_controller.go:162
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsmachines get, list, watch, create, update, patch, delete machine_sync_mapi2capi_infrastructure.go:108,136,213
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsmachines/status update, patch machine_sync_mapi2capi_infrastructure.go:194
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsmachinetemplates get, list, watch, patch, deletecollection machineset_sync_controller.go:251,453,763,492
Role: openshift-cluster-api "" pods get audit2rbac confirmed — upstream CAPI controller-manager reads its own pod (cluster_accessor.go:270)
Role: openshift-cluster-api "" secrets get, list, watch, update, patch secret_sync_controller.go:73,90,161, kubeconfig.go:138,171,209
Role: openshift-cluster-api "" events create machine_sync_controller.go:180, machineset_sync_controller.go:151
Role: openshift-cluster-api coordination.k8s.io leases get, update Standard controller-runtime leader election
Role: openshift-machine-api machine.openshift.io machines, machinesets get, list, watch, create, update, patch, delete machine_sync_controller.go:203,1391,1467,1039, machineset_sync_controller.go:190,943,1149
Role: openshift-machine-api machine.openshift.io machines/status, machinesets/status update, patch machine_sync_controller.go:1441, machineset_sync_controller.go:996, migratestatus.go:105
Role: openshift-machine-api machine.openshift.io controlplanemachinesets get, list, watch infracluster_controller.go:285-288,412
Role: openshift-machine-api "" secrets get, list, watch secret_sync_controller.go:73 — controller-runtime cache needs list/watch for Get
Role: openshift-machine-api "" events create, patch machine_sync_controller.go:180

Not observed by audit2rbac — justified by code evidence

Scope API Group Resource Verbs not observed Justification
Role: openshift-cluster-api cluster.x-k8s.io clusters/finalizers, machines/finalizers, machinesets/finalizers update Sync controllers set blockOwnerDeletion: true on ownerReferences (machine_sync_controller.go:577,867, machineset_sync_controller.go:635). Kubernetes requires update on the owner's finalizers subresource. Not captured by audit2rbac (validated by GC admission plugin, not a separate API call).
Role: openshift-machine-api machine.openshift.io machines/finalizers, machinesets/finalizers update Same blockOwnerDeletion pattern — MAPI machines set ownerReferences to MAPI machinesets (machine_sync_controller.go:953-958).
Role: openshift-cluster-api "" secrets create secret_sync_controller.go:152, azure.go:131 — creates secrets if not found.
Role: openshift-cluster-api "" events patch Event recorder can patch existing events. Only create was observed.
Role: openshift-cluster-api coordination.k8s.io leases create, list, watch, patch, delete create only on first leader election. list/watch/delete are standard controller-runtime patterns.
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io non-AWS resources all Platform-specific — identical code patterns to AWS. Can only be verified on respective platforms.
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io azureclusteridentities get, list, watch, create Azure-only. azure.go:142 Get (controller-runtime cache needs list/watch), :188 Create.
Role: openshift-cluster-api infrastructure.cluster.x-k8s.io awsmachinetemplates create, update, delete SSA patch and DeleteAllOf were used instead.
Role: openshift-machine-api machine.openshift.io machinesets create machineset_sync_controller.go — creates MAPI MachineSets during CAPI→MAPI sync. Only MAPI→CAPI direction was tested.
Role: kube-system "" secrets list, watch vSphere — controller-runtime cache (resourceNames not applicable to list/watch)
Role: kube-system "" secrets (resourceNames: vsphere-creds) get vSphere credentials. vsphere.go:157 — only exercised on vSphere clusters.

🤖 Generated with Claude Code

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 8, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 8, 2026

Copy link
Copy Markdown

@stefanonardo: This pull request references OCPCLOUD-1645 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Replace wildcard RBAC rules (apiGroups: ['*'], resources: ['*'], verbs: ['*']) in the openshift-capi-controllers ClusterRole and capi-controllers Role with enumerated, auditable permissions
  • Derived from code analysis of all controllers (capi-controllers + machine-api-migration) and cross-validated with audit2rbac on a live cluster
  • The cluster-capi-operator-pull-secret Role in openshift-config was already scoped and is unchanged

Test plan

  • make lint passes
  • Phase 1: Deployed with wildcard RBAC on AWS cluster, ran e2e (40/40 passed), collected audit logs, ran audit2rbac to establish baseline
  • Phase 1: Produced gap report comparing audit2rbac output against planned rules — all gaps justified by code evidence (non-AWS platform paths, untriggered edge cases)
  • Phase 2: Applied new RBAC to cluster, restarted controllers — 0 forbidden errors, ClusterOperator healthy
  • Phase 2: Re-ran e2e tests with new RBAC — 40/40 passed

🤖 Generated with Claude Code

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.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Wildcard RBAC rules were removed and replaced with explicit ClusterRole and Role rules that enumerate specific API groups, resources, and verbs for the capi-controllers ServiceAccount. RoleBindings were added to bind those Roles to the ServiceAccount in openshift-machine-api and kube-system namespaces. Documentation and a /rbac-review skill were added to establish the RBAC maintenance and audit process using audit2rbac and static code analysis.

Changes

RBAC Permissions Hardening

Layer / File(s) Summary
ClusterRole and Roles explicit permissions
manifests/0000_30_cluster-api_03_rbac_roles.yaml
openshift-capi-controllers ClusterRole replaces wildcard with explicit rules for config.openshift.io resources (infrastructures, clusteroperators, clusteroperators/status, featuregates, clusterversions), apiextensions.k8s.io CRDs (customresourcedefinitions), and core nodes (get/list/watch, patch/update). capi-controllers Role in openshift-cluster-api grants coordination.k8s.io leases, cluster.x-k8s.io resources (clusters, machines, machinesets with status/finalizers), infrastructure.cluster.x-k8s.io provider resources (with deletecollection for templates), and core secrets/events. capi-controllers Role in openshift-machine-api grants machine.openshift.io machines/machinesets/controlplanemachinesets (with status), secrets (get), and events (create/patch). capi-controllers-kube-system Role in kube-system restricts to core secrets get/list/watch only.
RoleBindings for capi-controllers ServiceAccount
manifests/0000_30_cluster-api_04_rbac_bindings.yaml
RoleBinding capi-controllers in openshift-machine-api and RoleBinding capi-controllers-kube-system in kube-system bind their respective Roles to the capi-controllers ServiceAccount in openshift-cluster-api.
RBAC review skill and documentation
.claude/skills/rbac-review/SKILL.md, docs/rbac.md
SKILL.md documents the audit and regeneration workflow: prerequisites (oc/audit2rbac), e2e + audit2rbac baseline collection, static analysis of controller patterns (finalizers, VAP spec.paramRef, feature-gate informers), gap report structure, RBAC manifest update procedures (scoping principle, deployment via oc replace/apply), and verification. docs/rbac.md describes the scope-splitting model (ClusterRole for cluster-scoped, Roles for namespace-scoped) and directs to /rbac-review skill for ongoing RBAC maintenance.

🎯 4 (Complex) | ⏱️ ~45 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: scoping RBAC permissions from wildcards to least-privilege, which is the primary objective of the PR.
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.
Stable And Deterministic Test Names ✅ Passed This PR modifies only RBAC manifests (.yaml) and documentation (.md) files. No test files (*.go with Ginkgo patterns) are added or modified, so the "Stable and Deterministic Test Names" check is no...
Test Structure And Quality ✅ Passed PR modifies only YAML manifests and documentation files (RBAC roles, bindings, and docs), not Ginkgo test code. Check is not applicable to this PR.
Microshift Test Compatibility ✅ Passed PR does not add any new Ginkgo e2e tests; only modifies RBAC manifests and adds documentation. MicroShift test compatibility check is not applicable.
Single Node Openshift (Sno) Test Compatibility ✅ Passed This PR does not add any Ginkgo e2e tests. Changes are limited to RBAC manifests and documentation files, so SNO compatibility check is not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed PR modifies only RBAC manifests (ClusterRole, Role, RoleBinding) and documentation, which define permissions and do not contain scheduling constraints, pod affinity rules, replica counts, or topolo...
Ote Binary Stdout Contract ✅ Passed PR only changes YAML manifests and Markdown docs, no executable code or test binary changes, so OTE Binary Stdout Contract check is not applicable.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed This PR does not add any new Ginkgo e2e tests; it only modifies RBAC manifests and documentation files. The IPv6/disconnected network check applies only to new e2e tests.
No-Weak-Crypto ✅ Passed PR contains only RBAC manifests, documentation, and process guides with no cryptographic code or weak crypto implementations present.
Container-Privileges ✅ Passed PR modifies only RBAC role/binding definitions with no changes to container or Pod security configurations. No privileged: true, hostPID, hostNetwork, hostIPC, SYS_ADMIN, allowPrivilegeEscalation,...
No-Sensitive-Data-In-Logs ✅ Passed PR contains RBAC manifests, documentation, and supporting code files with no logging statements that expose sensitive data like passwords, tokens, API keys, PII, or customer information.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@stefanonardo

Copy link
Copy Markdown
Author

/jira refresh

@openshift-ci-robot

openshift-ci-robot commented Jun 8, 2026

Copy link
Copy Markdown

@stefanonardo: This pull request references OCPCLOUD-1645 which is a valid jira issue.

Details

In response to this:

/jira refresh

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.

@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.

🧹 Nitpick comments (1)
manifests/0000_30_cluster-api_03_rbac_roles.yaml (1)

246-256: 💤 Low value

Cluster-wide secrets access is intentional but worth documenting.

Trivy flags this rule because cluster-wide secrets management is a sensitive permission. However, this appears justified given:

  • Secret Sync Controller needs cross-namespace access (MAPI ↔ CAPI namespaces)
  • Kubeconfig Controller manages kubeconfig secrets
  • The delete verb is intentionally omitted, demonstrating least-privilege
  • This is a significant improvement over the previous wildcards

Consider adding a comment in the manifest documenting why cluster-wide scope is required, which helps future audits.

🤖 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 `@manifests/0000_30_cluster-api_03_rbac_roles.yaml` around lines 246 - 256, Add
an inline comment above the ClusterRole rule that grants resources: ["secrets"]
under apiGroups: [""] explaining why cluster-wide secrets access is required
(e.g., Secret Sync Controller must sync secrets between MAPI and CAPI namespaces
and the Kubeconfig Controller manages kubeconfig secrets), note that delete is
intentionally omitted to preserve least-privilege, and reference the controllers
(Secret Sync Controller, Kubeconfig Controller) so auditors can understand the
justification during reviews.

Source: Linters/SAST tools

🤖 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.

Nitpick comments:
In `@manifests/0000_30_cluster-api_03_rbac_roles.yaml`:
- Around line 246-256: Add an inline comment above the ClusterRole rule that
grants resources: ["secrets"] under apiGroups: [""] explaining why cluster-wide
secrets access is required (e.g., Secret Sync Controller must sync secrets
between MAPI and CAPI namespaces and the Kubeconfig Controller manages
kubeconfig secrets), note that delete is intentionally omitted to preserve
least-privilege, and reference the controllers (Secret Sync Controller,
Kubeconfig Controller) so auditors can understand the justification during
reviews.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 76c3409f-8bf9-49a3-a6ff-eeb8fc36df3c

📥 Commits

Reviewing files that changed from the base of the PR and between 8ea8125 and cfd7831.

📒 Files selected for processing (1)
  • manifests/0000_30_cluster-api_03_rbac_roles.yaml

@damdo

damdo commented Jun 8, 2026

Copy link
Copy Markdown
Member

/test ?

@stefanonardo

Copy link
Copy Markdown
Author

/test required

@mdbooth

mdbooth commented Jun 8, 2026

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 8, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aws-capi-disconnected-techpreview
/test e2e-aws-capi-techpreview
/test e2e-aws-capi-techpreview-post-install
/test e2e-aws-ovn
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-aws-ovn-techpreview
/test e2e-aws-ovn-techpreview-upgrade
/test e2e-azure-capi-techpreview
/test e2e-azure-ovn-techpreview
/test e2e-azure-ovn-techpreview-upgrade
/test e2e-gcp-capi-techpreview
/test e2e-gcp-ovn-techpreview
/test e2e-metal3-capi-techpreview
/test e2e-openstack-capi-techpreview
/test e2e-openstack-ovn-techpreview
/test e2e-vsphere-capi-techpreview
/test regression-clusterinfra-aws-ipi-techpreview-capi

@mdbooth

mdbooth commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

/lgtm cancel

Haven't actually looked at this, yet. Was just checking if it was waiting on the pipeline controller. Wasn't sure it was, as normally you see the pipeline jobs listed but 'Waiting', but they were not present at all.

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

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please ask for approval from mdbooth. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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

@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: 1

🤖 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 `@manifests/0000_30_cluster-api_03_rbac_roles.yaml`:
- Around line 254-264: The ClusterRole currently grants cluster-wide read/write
on Secrets (apiGroups: "", resources: secrets, verbs:
get/list/watch/create/update/patch) which is too permissive; remove secret
permissions from the ClusterRole and instead create namespace-scoped Role +
RoleBinding pairs that grant only the needed secret verbs in the exact
namespaces touched by the secret-sync/kubeconfig flows, bind those Roles to the
capi-controllers ServiceAccount used by openshift-capi-controllers, and where
the set of secrets is fixed use resourceNames to restrict to specific Secret
objects; update any references to the removed ClusterRole permissions
accordingly.
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 954effa5-a923-4230-8052-f53063758493

📥 Commits

Reviewing files that changed from the base of the PR and between cfd7831 and 44913ce.

📒 Files selected for processing (1)
  • manifests/0000_30_cluster-api_03_rbac_roles.yaml

Comment thread manifests/0000_30_cluster-api_03_rbac_roles.yaml
@stefanonardo stefanonardo force-pushed the OCPCLOUD-1645 branch 2 times, most recently from 947e14a to 39788fd Compare June 9, 2026 12:44
@damdo

damdo commented Jun 18, 2026

Copy link
Copy Markdown
Member

@stefanonardo if we could add some guidance like a README + reference to a skill on how this was done, so it is repeatable in the future, it'd be awesome!

@damdo

damdo commented Jun 19, 2026

Copy link
Copy Markdown
Member

/test e2e-aws-capi-techpreview

@damdo

damdo commented Jun 19, 2026

Copy link
Copy Markdown
Member

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Author

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Author

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Author

/test ci/prow/verify-deps

@stefanonardo

Copy link
Copy Markdown
Author

/test e2e-aws-capi-techpreview

@stefanonardo

Copy link
Copy Markdown
Author

/test verify-deps

@damdo

damdo commented Jun 23, 2026

Copy link
Copy Markdown
Member

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown
✅ 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 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: 1

🧹 Nitpick comments (1)
.claude/skills/rbac-review/SKILL.md (1)

19-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Minor style suggestion: Use "ask" instead of "tell."

The LanguageTool linter flagged this as more polite phrasing for user-facing guidance. If you're aligning skill documentation with a particular voice/tone standard, consider:

- If `oc whoami` fails, stop and tell the user to connect to a cluster first.
+ If `oc whoami` fails, stop and ask the user to connect to a cluster first.
🤖 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 @.claude/skills/rbac-review/SKILL.md at line 19, In the SKILL.md file, locate
the instruction that handles the case when oc whoami fails and currently states
"stop and tell the user to connect to a cluster first." Replace the word "tell"
with "ask" so it reads "stop and ask the user to connect to a cluster first" to
use more polite phrasing consistent with user-facing documentation standards.

Source: Linters/SAST tools

🤖 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 `@manifests/0000_30_cluster-api_03_rbac_roles.yaml`:
- Around line 183-189: The RBAC rule for azureclusteridentities is missing the
list and watch verbs required for the controller-runtime cached client to
initialize its informer. Locate the azureclusteridentities resource definition
in the apiGroups section for infrastructure.cluster.x-k8s.io and add list and
watch verbs to the existing verbs array that currently contains get and create.

---

Nitpick comments:
In @.claude/skills/rbac-review/SKILL.md:
- Line 19: In the SKILL.md file, locate the instruction that handles the case
when oc whoami fails and currently states "stop and tell the user to connect to
a cluster first." Replace the word "tell" with "ask" so it reads "stop and ask
the user to connect to a cluster first" to use more polite phrasing consistent
with user-facing documentation standards.
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 8bbb1a72-67c8-486d-bab2-f05961a19305

📥 Commits

Reviewing files that changed from the base of the PR and between 947e14a and b531611.

📒 Files selected for processing (4)
  • .claude/skills/rbac-review/SKILL.md
  • docs/rbac.md
  • manifests/0000_30_cluster-api_03_rbac_roles.yaml
  • manifests/0000_30_cluster-api_04_rbac_bindings.yaml
✅ Files skipped from review due to trivial changes (1)
  • docs/rbac.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • manifests/0000_30_cluster-api_04_rbac_bindings.yaml

Comment thread manifests/0000_30_cluster-api_03_rbac_roles.yaml
Comment on lines +20 to +30
- apiGroups:
- config.openshift.io
resources:
- clusteroperators
verbs:
- get
- list
- watch
- create
- update
- patch

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CVO creates this. I saw you noted there was some code which will create the CO if it doesn't exist. We should remove that and turn it into an error.

I would like to see:

  • remove the create/update/patch permissions (we only patch status, below)
  • restrict to the cluster-api object specifically

- apiGroups:
- cluster.x-k8s.io
resources:
- clusters

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think we need the same permissions for clusters, machines, machinesets. Lets just list them here so we DRY.

- apiGroups:
- infrastructure.cluster.x-k8s.io
resources:
- azureclusteridentities

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

azureclusteridentities sounds like a cluster-scoped resource? If so, I don't think this permission will be effective in a Role (would need to be ClusterRole).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

- apiGroups:
- machine.openshift.io
resources:
- machines

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Lets combine machines and machinesets

Comment on lines +360 to +361
resources:
- secrets

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

IIRC we can (and should) confine this to a specific named secret. All secrets in kube-system is a bit broad.

@stefanonardo stefanonardo force-pushed the OCPCLOUD-1645 branch 2 times, most recently from 78dd40c to a5de004 Compare June 23, 2026 14:36
@stefanonardo

Copy link
Copy Markdown
Author

/test e2e-aws-capi-techpreview

@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@stefanonardo: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/e2e-azure-ovn-techpreview cfd7831 link false /test e2e-azure-ovn-techpreview
ci/prow/regression-clusterinfra-aws-ipi-techpreview-capi cfd7831 link false /test regression-clusterinfra-aws-ipi-techpreview-capi
ci/prow/e2e-aws-capi-disconnected-techpreview cfd7831 link false /test e2e-aws-capi-disconnected-techpreview
ci/prow/e2e-azure-capi-techpreview cfd7831 link true /test e2e-azure-capi-techpreview
ci/prow/e2e-aws-capi-techpreview-post-install cfd7831 link true /test e2e-aws-capi-techpreview-post-install
ci/prow/e2e-vsphere-capi-techpreview cfd7831 link true /test e2e-vsphere-capi-techpreview
ci/prow/e2e-metal3-capi-techpreview cfd7831 link false /test e2e-metal3-capi-techpreview
ci/prow/e2e-aws-ovn cfd7831 link true /test e2e-aws-ovn
ci/prow/e2e-openstack-capi-techpreview cfd7831 link true /test e2e-openstack-capi-techpreview
ci/prow/e2e-gcp-capi-techpreview cfd7831 link true /test e2e-gcp-capi-techpreview
ci/prow/e2e-openstack-ovn-techpreview cfd7831 link false /test e2e-openstack-ovn-techpreview

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.

Replace wildcard RBAC rules with enumerated resources and verbs for
the capi-controllers ServiceAccount. Validated with audit2rbac and
e2e tests on an AWS cluster with MachineAPIMigration enabled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@stefanonardo

Copy link
Copy Markdown
Author

/test e2e-aws-capi-techpreview

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

Labels

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.

4 participants