Skip to content

feat(repo-server): Declare custom trust certs for repo-server and plugins#1876

Merged
svghadi merged 24 commits intoargoproj-labs:masterfrom
olivergondza:ClusterTrustBundle
Feb 11, 2026
Merged

feat(repo-server): Declare custom trust certs for repo-server and plugins#1876
svghadi merged 24 commits intoargoproj-labs:masterfrom
olivergondza:ClusterTrustBundle

Conversation

@olivergondza
Copy link
Copy Markdown
Collaborator

@olivergondza olivergondza commented Sep 18, 2025

What type of PR is this?

/kind enhancement

What does this PR do / why we need it:

Permit users to trust CAs on a repo-server system level

Have you updated the necessary documentation?

  • Documentation update is required by this PR.
  • Documentation has been updated.
Screenshot From 2025-09-23 13-17-05

Which issue(s) this PR fixes:

Fixes #1830

How to test changes / Special notes to the reviewer:

Can be tested against:

k3d cluster create localtest \
              --k3s-arg "--kube-apiserver-arg=feature-gates=ClusterTrustBundle=true,ClusterTrustBundleProjection=true@server:*" \
              --k3s-arg "--kube-apiserver-arg=runtime-config=certificates.k8s.io/v1beta1/clustertrustbundles=true@server:*" \
              --k3s-arg "--kubelet-arg=feature-gates=ClusterTrustBundle=true,ClusterTrustBundleProjection=true@agent:*" \
              --image rancher/k3s:v1.33.0-k3s1

Summary by CodeRabbit

  • New Features

    • System CA trust injection for the repo server and plugins via ClusterTrustBundles, Secrets, and ConfigMaps; supports mounting, optional dropping of image certificates, init-container CA installation, and automatic rollouts when trust changes.
  • Documentation

    • New reference pages and YAML examples for SystemCATrust configuration and merging behavior.
  • Tests

    • Large E2E suite and new test helpers validating trust projection, updates, and reconciliations.
  • Chores

    • CI matrix expanded for additional k3s versions; operator RBAC and permissions updated to support ClusterTrustBundle access.

@olivergondza olivergondza changed the title feat(repo-server): Declare custom trust anchors to use by repo-server or plugins feat(repo-server): Declare custom trust anchors to used by repo-server or plugins Sep 18, 2025
@olivergondza
Copy link
Copy Markdown
Collaborator Author

Compared to the proposal in #1876, it turned out 1 init container is enough. Also, this implements DropImageAnchors to suppress whatever CAs was in the image originally.

@olivergondza
Copy link
Copy Markdown
Collaborator Author

/ok-to-test

@olivergondza olivergondza changed the title feat(repo-server): Declare custom trust anchors to used by repo-server or plugins feat(repo-server): Declare custom trust certs for repo-server and plugins Sep 22, 2025
@olivergondza
Copy link
Copy Markdown
Collaborator Author

The "Code scans / Run golangci-lint and gosec (pull_request)" failure to be adressed by #1880

@olivergondza
Copy link
Copy Markdown
Collaborator Author

The test failures are related to the fact the code depends on a tech-preview features. Any advise on how to handle such functionality?

https://github.com/argoproj-labs/argocd-operator/actions/runs/17917840047/job/50944661583?pr=1876#step:11:45

@olivergondza olivergondza force-pushed the ClusterTrustBundle branch 6 times, most recently from 93a8f75 to 2e5afb6 Compare September 24, 2025 13:58
Comment thread api/v1beta1/argocd_types.go
Comment thread .github/workflows/ci-build.yaml Outdated
@olivergondza olivergondza force-pushed the ClusterTrustBundle branch 2 times, most recently from de515ac to 448e641 Compare September 30, 2025 13:09
@olivergondza olivergondza marked this pull request as draft September 30, 2025 14:43
@olivergondza olivergondza force-pushed the ClusterTrustBundle branch 6 times, most recently from c0a9ad2 to 448e641 Compare October 4, 2025 07:01
@olivergondza olivergondza marked this pull request as ready for review October 10, 2025 12:52
@olivergondza olivergondza force-pushed the ClusterTrustBundle branch 3 times, most recently from 198d41d to 9c3639c Compare October 27, 2025 11:12
@olivergondza
Copy link
Copy Markdown
Collaborator Author

@jannfis, after your review, this is the added feature of change detection: 9c3639c

Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
… CTB support

Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
…rustBundles to repo-server automatically

Signed-off-by: Oliver Gondža <ogondza@gmail.com>
…rest

- Use default image pull policy
- Use default security context
- Propagate proxy env vars

Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@controllers/argocd/repo_server.go`:
- Around line 628-649: The CA trust mounts are only applied when a container's
image equals argoImage (from getArgoContainerImage), which skips repo-server
when a custom repo image is set; update the injection logic in the repo-server
deployment to also consider the repo image (from getRepoServerContainerImage) —
i.e., compute both expected images (argoImage and repoImage or a set of allowed
images), then in the loop over deploy.Spec.Template.Spec.Containers (the same
loop that appends prodVolumeMounts() and records containerNames) compare
container.Image against both images (or the image set) so repo-server and any
sidecars inheriting the repo image receive the volume mounts; keep
caTrustInitContainer and prodVolumeMounts usage as-is.
🧹 Nitpick comments (4)
tests/ginkgo/fixture/utils/fixtureUtils.go (1)

6-6: Consider grouping with other k8s.io/api/* imports.

The certificatesv1beta1 import is placed separately from the other k8s.io/api/* imports (lines 18-24). For consistency, consider moving it to that group. However, this may be addressed by the linter fix in PR #1880.

deploy/olm-catalog/argocd-operator/0.18.0/argoproj.io_argocds.yaml (1)

21958-22030: Add CEL validation for mutually exclusive clusterTrustBundles selectors in the source CRD.

The schema documents that name is mutually exclusive with signerName/labelSelector, but it isn't enforced. Since this file is auto-generated from the source CRD at config/crd/bases/argoproj.io_argocds.yaml, add x-kubernetes-validations (CEL) rules to the source to ensure invalid combinations fail fast instead of silently no-oping. Other fields in the CRD already use this pattern (e.g., TLS termination validations).

config/crd/bases/argoproj.io_argocds.yaml (1)

21938-22020: Consider adding CRD CEL validations to enforce mutually exclusive selector fields.

The schema documents that name is mutually exclusive with signerName, and labelSelector only works with signerName, but the CRD doesn't enforce these constraints at admission time. For Kubernetes 1.25+, you can add x-kubernetes-validations rules to catch these invalid combinations early.

Proposed schema validation additions
                            signerName:
                              description: |-
                                Select all ClusterTrustBundles that match this signer name.
                                Mutually-exclusive with name.  The contents of all selected
                                ClusterTrustBundles will be unified and deduplicated.
                              type: string
+                          x-kubernetes-validations:
+                            - rule: "(has(self.name) && self.name != '') || (has(self.signerName) && self.signerName != '')"
+                              message: "Set either name or signerName."
+                            - rule: "!(has(self.name) && self.name != '' && has(self.signerName) && self.signerName != '')"
+                              message: "name and signerName are mutually exclusive."
+                            - rule: "!(has(self.labelSelector) && (!has(self.signerName) || self.signerName == ''))"
+                              message: "labelSelector requires signerName."
                           required:
                           - path
                           type: object
controllers/argocd/util.go (1)

1033-1033: Consider consolidating mapper parameters into a struct.

The function signature now accepts 7 mapper functions, which is getting unwieldy. Consider grouping these into a configuration struct for better maintainability:

type ResourceWatchConfig struct {
    ClusterResourceMapper                      handler.MapFunc
    TLSSecretMapper                            handler.MapFunc
    NamespaceResourceMapper                    handler.MapFunc
    ClusterSecretResourceMapper                handler.MapFunc
    ApplicationSetGitlabSCMTLSConfigMapMapper  handler.MapFunc
    NMMapper                                   handler.MapFunc
    SystemCATrustMapper                        handler.MapFunc
}

This would make the function signature cleaner and easier to extend in the future.

Comment thread controllers/argocd/repo_server.go Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@controllers/argocd/repo_server.go`:
- Around line 695-701: The code in caTrustVolumes currently panics on List
errors (panic(err)) which will crash the controller; change caTrustVolumes to
return an error instead of panicking and propagate that error to the caller so
transient API errors can be retried/handled. Specifically, replace panic(err) in
the ClusterTrustBundle List block and the other panic sites referenced in
caTrustVolumes with returned errors (e.g., fmt.Errorf("listing
ClusterTrustBundles: %w", err)) and update the callers of caTrustVolumes to
check and return or handle the error appropriately. Ensure the function
signature of caTrustVolumes is updated to include an error return and adapt any
callers to propagate or log the error so controller reconciliation can retry
rather than crash.

Comment thread controllers/argocd/repo_server.go
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@controllers/argocd/repo_server.go`:
- Around line 742-747: The log call inside the ConfigMap lookup error handling
uses the wrong structured field key ("secret"); update the call to log.Error in
the block that handles err from r.Get (the ConfigMap fetch using
cmProjection.Name and cr.Namespace) to use "configmap" instead of "secret" so
the fields accurately reflect the resource (i.e., keep the same message and
variables but change the field key to "configmap" for cmProjection.Name).

Comment thread controllers/argocd/repo_server.go
…n checksum change

Signed-off-by: Oliver Gondža <ogondza@gmail.com>
Copy link
Copy Markdown
Collaborator

@svghadi svghadi left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks

@anandf , @jgwest , @jannfis - Any objections to merging this?

@svghadi svghadi merged commit 4c05ef8 into argoproj-labs:master Feb 11, 2026
9 checks passed
@olivergondza olivergondza deleted the ClusterTrustBundle branch February 12, 2026 09:30
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.

Proposal: Populate repo-server container with ClusterTrustBundle CA certificates

5 participants