Fix CVEs in multicloud-integrations - #591
Conversation
The ocm-managed-cluster annotation on an Application is tenant-controlled input, but Reconcile() used it verbatim as the ManifestWork target namespace with only a bare existence check on the ManagedCluster. A tenant with namespaced create on applications.argoproj.io could direct the controller (which holds cluster-wide manifestworks:create) to write a ManifestWork into any managed-cluster hub namespace, yielding cluster-admin on an arbitrary spoke via the spoke's openshift-gitops ArgoCD instance. This adds isClusterBoundToNamespace(): the controller now requires that a PlacementDecision in the Application's own namespace selects the target cluster. PlacementDecisions are written by the OCM placement controller and a Placement can only select clusters from ManagedClusterSets that an admin has bound to the namespace via ManagedClusterSetBinding, so a matching decision proves the namespace is authorized to target the cluster. CWEs: CWE-441, CWE-639 Signed-off-by: Ismail Ibrahim Quwarah <iquwarah@redhat.com>
spec.argoServer.argoNamespace is taken verbatim from the namespaced GitOpsCluster CR and used as the destination for managed-cluster bearer-token Secrets that the controller copies out of privileged managed-cluster namespaces. The only existing guard (VerifyArgocdNamespace, a Service-label probe) was both tenant-spoofable and bypassable via the tenant-settable skipArgoNamespaceVerify annotation, so a tenant could redirect spoke tokens into a namespace they read. reconcileGitOpsCluster now calls verifyArgoNamespaceAuthorized() before any other processing: same-namespace writes pass; cross-namespace writes are permitted only when a cluster admin has labelled the target Namespace with apps.open-cluster-management.io/gitops-argo-namespace=true. Namespace labels require cluster-scoped update on namespaces, which a namespaced tenant does not hold, so the opt-in cannot be self-granted. The skipArgoNamespaceVerify annotation continues to skip only the liveness probe and no longer bypasses authorization. CWEs: CWE-441, CWE-522 Signed-off-by: Ismail Ibrahim Quwarah <iquwarah@redhat.com>
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: falconizmi The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: stolostron/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
WalkthroughThe PR adds ArgoCD namespace authorization for GitOpsCluster reconciliation and PlacementDecision-based authorization for propagated Applications. It registers the cluster API scheme, adds PlacementDecision RBAC permissions, and extends tests and fixtures. ChangesAuthorization controls
Estimated code review effort: 4 (Complex) | ~45 minutes Mergeability Score: ⚪ Minimal · up to The pull request applies narrowly scoped CVE-related behavior changes, and no actionable merge-blocking risk remains beyond normal checks and review. Sequence Diagram(s)sequenceDiagram
participant GitOpsClusterReconciler
participant KubernetesNamespaceAPI
participant ArgoServerVerification
GitOpsClusterReconciler->>KubernetesNamespaceAPI: verify target namespace authorization
KubernetesNamespaceAPI-->>GitOpsClusterReconciler: namespace authorization result
GitOpsClusterReconciler->>ArgoServerVerification: verify liveness when authorized
sequenceDiagram
participant ApplicationReconciler
participant PlacementDecisionAPI
participant ManifestWorkAPI
ApplicationReconciler->>PlacementDecisionAPI: list PlacementDecisions
PlacementDecisionAPI-->>ApplicationReconciler: cluster selection result
ApplicationReconciler->>ManifestWorkAPI: reconcile ManifestWork when selected
Suggested reviewers: 🚥 Pre-merge checks | ✅ 9 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (9 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (1)
pkg/controller/gitopscluster/gitopscluster_controller.go (1)
656-669: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftMigrate to
klog/v2before using structured logging.Replace the import with
k8s.io/klog/v2, then replace bothklog.Errorfcalls withklog.ErrorSand recordnamespace,name, and the error as structured fields.🤖 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/controller/gitopscluster/gitopscluster_controller.go` around lines 656 - 669, Update the klog import to k8s.io/klog/v2, then convert both klog.Errorf calls in the GitOpsCluster rejection and status-update error paths to klog.ErrorS. Preserve their messages while passing namespace, name, and the relevant error as structured key-value fields.Source: Path instructions
🤖 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 `@pkg/controller/gitopscluster/gitopscluster_controller_test.go`:
- Around line 103-151: Add meaningful failure messages to the require.NoError
setup assertion and both authorization assertions in
TestVerifyArgoNamespaceAuthorized. Identify the specific namespace authorization
case using the table test name and state whether authorization was expected to
succeed or fail.
In `@pkg/controller/gitopscluster/gitopscluster_controller.go`:
- Around line 668-670: Wrap err2 with operation context before returning from
the Status().Update failure branch in the GitOpsCluster reconciliation flow.
Replace the direct return of err2 with a fmt.Errorf-wrapped error that preserves
err2 using %w, while leaving the existing logging and retry result unchanged.
- Around line 76-83: Update reconcileGitOpsCluster and
verifyArgoNamespaceAuthorized to accept and propagate the reconciliation
context, then replace context.TODO() in the Namespace r.Get lookup with that ctx
so cancellation reaches the Kubernetes API call.
- Around line 650-655: Move the verifyArgoNamespaceAuthorized gate in the
GitOpsCluster reconciliation flow before ensureArgoCDAgentJWTSecret, so
unauthorized configurations cannot create secrets in the tenant-selected
namespace. Add a test covering an unlabelled target with
skipArgoNamespaceVerify=true and assert that no secret is created in that target
namespace.
In `@propagation-controller/application/application_controller.go`:
- Around line 112-115: Update ApplicationReconciler.isClusterBoundToNamespace so
the PlacementDecision List call uses a bounded child context with a local
timeout, ensuring the deadline is released afterward. When the call fails, wrap
the error with the operation and namespace context using fmt.Errorf with %w
before returning it.
- Around line 493-506: Update SetupWithManager to watch PlacementDecision
resources and map each event to Applications in the PlacementDecision’s
namespace, so binding changes enqueue affected Applications for reconciliation.
Add or update tests covering PlacementDecision create/update events and verify
they enqueue Applications in the same namespace while preserving the existing
Application watch.
---
Nitpick comments:
In `@pkg/controller/gitopscluster/gitopscluster_controller.go`:
- Around line 656-669: Update the klog import to k8s.io/klog/v2, then convert
both klog.Errorf calls in the GitOpsCluster rejection and status-update error
paths to klog.ErrorS. Preserve their messages while passing namespace, name, and
the relevant error as structured key-value fields.
🪄 Autofix
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: stolostron/coderabbit/.coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: a9fdbfd4-eb33-4729-a4ea-59235fbe3bd1
📒 Files selected for processing (5)
cmd/propagation/main.gopkg/controller/gitopscluster/gitopscluster_controller.gopkg/controller/gitopscluster/gitopscluster_controller_test.gopropagation-controller/application/application_controller.gopropagation-controller/application/helper_test.go
|
/retest |
…t test verifyArgoNamespaceAuthorized requires the target argocd namespace to exist with LabelKeyAllowedArgoNamespace=true for cross-namespace configurations. Without it, reconcile is rejected before reaching the local-cluster-in-Placement check the test targets. Signed-off-by: Ismail Ibrahim Quwarah <iquwarah@redhat.com>
|
|
@falconizmi: The following test failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |


Summary by CodeRabbit
New Features
Bug Fixes