@@ -20,28 +20,28 @@ The agent component uses certificates for two primary purposes:
2020graph TB
2121 Principal[Principal<br/>argocd-agent-principal-tls]
2222 CA[Certificate Authority<br/>argocd-agent-ca]
23-
23+
2424 Agent1[Agent 1<br/>Workload Cluster 1]
2525 Agent2[Agent 2<br/>Workload Cluster 2]
26-
26+
2727 CA --> Agent1CA[CA Certificate<br/>argocd-agent-ca]
2828 CA --> Agent2CA[CA Certificate<br/>argocd-agent-ca]
29-
29+
3030 CA --> Agent1Cert[Client Certificate<br/>argocd-agent-client-tls]
3131 CA --> Agent2Cert[Client Certificate<br/>argocd-agent-client-tls]
32-
32+
3333 Agent1CA --> Agent1
3434 Agent1Cert --> Agent1
3535 Agent2CA --> Agent2
3636 Agent2Cert --> Agent2
37-
37+
3838 Agent1 -.->|TLS Connection| Principal
3939 Agent2 -.->|TLS Connection| Principal
40-
40+
4141 classDef agent fill:#e1f5fe
4242 classDef cert fill:#f3e5f5
4343 classDef ca fill:#e8f5e8
44-
44+
4545 class Agent1,Agent2 agent
4646 class Agent1Cert,Agent2Cert cert
4747 class CA,Agent1CA,Agent2CA ca
@@ -153,6 +153,148 @@ argocd-agent-ca Opaque 1 5m
153153argocd-agent-client-tls kubernetes.io/tls 2 4m
154154```
155155
156+ ## Using cert-manager
157+
158+ The cert-manager operator can be used to manage PKI certificates, this section assumes the steps
159+ for the Principal PKI using cert-manager have been completed.
160+
161+ To register Agents, Agent specific certificates for both the Principal and Agent need to be minted for
162+ use with [ Mutual TLS] ( https://www.cloudflare.com/learning/access-management/what-is-mutual-tls/ )
163+
164+ ### Step 1: Register the Agent on the Principal
165+
166+ To register the Agent on the Principal a certificate must be minted for the Principal to provide
167+ to the Agent as part of mTLS. Note the ` dnsNames ` used is not important
168+ but a consistent method should be used, for example ` <cluster-name>.<CA-ROOT-DOMAIN> `
169+
170+ Replace the ` <cluster-name> ` and ` <Organizational Unit> ` tokens to match your requirements:
171+
172+ ```
173+ apiVersion: cert-manager.io/v1
174+ kind: Certificate
175+ metadata:
176+ name: <cluster-name>-principal
177+ namespace: argocd
178+ spec:
179+ secretName: <cluster-name>
180+ issuerRef:
181+ name: argocd-agent-ca
182+ kind: Issuer
183+ commonName: managed-cluster
184+ subject:
185+ organizationalUnits:
186+ - <Organizational Unit>
187+ dnsNames:
188+ - <cluster-name>.<CA-ROOT-DOMAIN>
189+ ```
190+
191+ Create the cluster secret, note that you cannot directly use the previously created certificate
192+ but need to transpose it into the cluster secret.
193+
194+ Extract the fields we need into environment variables:
195+
196+ ```
197+ export PRINCIPAL_AGENT_CA=$(kubectl get secret <cluster-name>-principal -o jsonpath='{.data.ca\.crt}')
198+ export PRINCIPAL_AGENT_TLS=$(kubectl get secret <cluster-name>-principal -o jsonpath='{.data.tls\.crt}')
199+ export PRINCIPAL_AGENT_KEY=$(kubectl get secret <cluster-name>-principal -o jsonpath='{.data.tls\.key}')
200+ ```
201+
202+ To create the ` <cluster-name>-cluster ` secret that is needed we must first create the ` config ` block
203+ with the certs:
204+
205+ ```
206+ cat << EOF > config
207+ {
208+ "username": "foo",
209+ "password": "bar",
210+ "tlsClientConfig": {
211+ "insecure": false,
212+ "certData": "${PRINCIPAL_AGENT_TLS}",
213+ "keyData": "${PRINCIPAL_AGENT_KEY}",
214+ "caData": "${PRINCIPAL_AGENT_CA}"
215+ }
216+ }
217+ EOF
218+ ```
219+
220+ Now create the secret:
221+
222+ ```
223+ kubectl create secret generic <cluster-name>-cluster -n argocd --from-literal=name=<cluster-name> --from-literal=server=argocd-agent-resource-proxy.argocd.svc.cluster.local --from-file=config=./config
224+ ```
225+
226+ Then label the secret as a cluster secret:
227+
228+ ```
229+ oc label secret <cluster-name>-cluster argocd.argoproj.io/secret-type=cluster
230+ ```
231+
232+ ### Step 2: Mint Certificate for Agent
233+
234+ The Agent requires it's own certificate which will be provided to the Principal for mTLS, this will
235+ be minted on the Principal where the Issuer is available and then moved to the Agent.
236+
237+ !!!note
238+ It is possible to mint this certificate on the Agent itself by simply using cert-manager
239+ with the identical CA secret on the Agent. However this has security implications since
240+ if any cluster is compromised the CA with its key could be retrieved and a hacker could mint their own certs. Generally
241+ the Agents will at times run in less secure locations/networks then the Principle so isolating
242+ the CA to one location, the principal, is beneficial.
243+
244+ ```
245+ apiVersion: cert-manager.io/v1
246+ kind: Certificate
247+ metadata:
248+ name: <cluster-name>-agent
249+ namespace: argocd
250+ spec:
251+ secretName: <cluster-name>-agent
252+ issuerRef:
253+ name: argocd-agent-ca
254+ kind: Issuer
255+ commonName: managed-cluster
256+ subject:
257+ organizationalUnits:
258+ - <Organizational Unit>
259+ dnsNames:
260+ - <cluster-name>.<CA-ROOT-DOMAIN>
261+ ```
262+
263+ Output the secret to a file as we need to install it on the cluster where the Agent resides:
264+
265+ ```
266+ kubectl get secret managed-cluster-agent -o yaml -n argocd | oc neat > <cluster-name>-agent.yaml
267+ ```
268+
269+ !!!note
270+ The [ kubectl-neat] ( https://github.com/itaysk/kubectl-neat ) plugin is used to clean the YAML, if you do not have access to this simply omit it
271+ and edit the secret after it is exported to remove the cruft:
272+
273+ The secret ` argocd-agent-ca ` is also required for the Agent however want it without the key for
274+ the security reasons discussed earlier.
275+
276+ !!!note
277+ The command ` yq ` is used to modify the secret, if ` yq ` is not available simply edit the secret as needed.
278+
279+ ```
280+ kubectl get secret argocd-agent-ca -o yaml -n argocd | yq 'del(.data.["tls.key"])' -y | oc neat > argocd-agent-ca.yaml
281+ ```
282+
283+ Change the secret type to ` Opaque ` since a Kubernetes TLS secret requires a key, additionally change the name of the exported secret from ` <cluster-name>-agent ` to
284+ to ` argocd-agent-client-tls ` .
285+
286+ ```
287+ yq -i '.type = "Opaque"' ./argocd-agent-ca.yaml -y
288+ yq -i '.metadata.name = "argocd-agent-client-tls"' <path-to-secret>/managed-cluster-agent.yaml -y
289+ ```
290+
291+ On the Agent cluster apply the two secrets:
292+
293+ ```
294+ kubectl apply -f ./argocd-agent-ca.yaml
295+ kubectl apply -f <cluster-name>-agent.yaml
296+ ```
297+
156298## Manual Certificate Management
157299
158300For production environments or when integrating with existing PKI infrastructure, you can manually create and manage the required certificates and secrets.
@@ -346,10 +488,10 @@ data:
346488 agent.tls.secret-name: "argocd-agent-client-tls"
347489 agent.tls.client.cert-path: ""
348490 agent.tls.client.key-path: ""
349-
491+
350492 # Authentication
351493 agent.creds: "userpass:/app/config/creds/userpass.creds"
352-
494+
353495 # Connection
354496 agent.server.address: "<principal-address>"
355497 agent.server.port: "8443"
@@ -672,4 +814,4 @@ spec:
672814# # Related Documentation
673815
674816- [Principal PKI Configuration](../principal/pki-certificates.md) - PKI setup for the principal component
675- - [Adding New Agents](../../user-guide/adding-agents.md) - Complete agent setup guide
817+ - [Adding New Agents](../../user-guide/adding-agents.md) - Complete agent setup guide
0 commit comments