Skip to content

Commit d3c9fc6

Browse files
authored
Merge pull request #1081 from maelvls/document-vault-bound-serviceaccount
Vault: document the new field "serviceAccountRef"
2 parents 0b5d7e2 + 32a3e8b commit d3c9fc6

File tree

5 files changed

+209
-69
lines changed

5 files changed

+209
-69
lines changed

.spelling

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,10 @@ NetworkPolicy
553553
mjudeikis
554554
rgl
555555
1password
556+
secretless
557+
TokenRequest
558+
v1.12.0
559+
v1.12.0.
556560

557561
# TEMPORARY
558562
# these are temporarily ignored because the spellchecker

content/docs/configuration/vault.md

Lines changed: 117 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,125 @@ spec:
144144
key: token
145145
```
146146

147+
<a id="authenticating-with-kubernetes-service-accounts"></a>
148+
147149
### Authenticating with Kubernetes Service Accounts
148150

149-
Vault can be configured so that applications can authenticate using Kubernetes
150-
[`Service Account
151-
Tokens`](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin).
152-
You find documentation on how to configure Vault to authenticate using Service
153-
Account Tokens [here](https://www.vaultproject.io/docs/auth/kubernetes.html).
151+
The [Vault Kubernetes
152+
Auth](https://developer.hashicorp.com/vault/docs/auth/kubernetes) allows
153+
cert-manager to authenticate to Vault using a Kubernetes Service Account Token
154+
in order to issue certificates using Vault as a certification authority. The
155+
Kubernetes service account token can be provided in two ways:
156+
157+
- [Secretless Authentication with a Service Account](#secretless-authentication-with-a-service-account) (recommended),
158+
- [Authentication with a Static Service Account Token](#static-service-account-token).
159+
160+
#### Secretless Authentication with a Service Account
161+
162+
ℹ️ This feature is available in cert-manager >= v1.12.0.
163+
164+
With the secretless authentication with a service account, cert-manager creates
165+
an ephemeral service account token using the TokenRequest API and uses it to
166+
authenticate with Vault. These tokens are short-lived (10 minutes) and are
167+
never stored to disk.
168+
169+
This is the recommended authentication method because it does not rely on the
170+
deprecated static service account tokens. The static service account tokens pose
171+
a threat due to their infinite lifetime. Static service account tokens have been
172+
disabled by default on Kubernetes 1.24.
173+
174+
The first step is to create a `ServiceAccount` resource:
175+
176+
```sh
177+
kubectl create serviceaccount -n sandbox vault-issuer
178+
```
179+
180+
Then add an RBAC Role so that cert-manager can get tokens for the
181+
ServiceAccount:
182+
183+
```yaml
184+
apiVersion: rbac.authorization.k8s.io/v1
185+
kind: Role
186+
metadata:
187+
name: vault-issuer
188+
namespace: sandbox
189+
rules:
190+
- apiGroups: ['']
191+
resources: ['serviceaccounts/token']
192+
resourceNames: ['vault-issuer']
193+
verbs: ['create']
194+
---
195+
apiVersion: rbac.authorization.k8s.io/v1
196+
kind: RoleBinding
197+
metadata:
198+
name: vault-issuer
199+
namespace: sandbox
200+
subjects:
201+
- kind: ServiceAccount
202+
name: cert-manager
203+
namespace: cert-manager
204+
roleRef:
205+
apiGroup: rbac.authorization.k8s.io
206+
kind: Role
207+
name: vault-issuer
208+
```
209+
210+
Finally, create the Issuer resource:
211+
212+
```yaml
213+
apiVersion: cert-manager.io/v1
214+
kind: Issuer
215+
metadata:
216+
name: vault-issuer
217+
namespace: sandbox
218+
spec:
219+
vault:
220+
path: pki_int/sign/example-dot-com
221+
server: https://vault.local
222+
auth:
223+
kubernetes:
224+
role: my-app-1
225+
mountPath: /v1/auth/kubernetes
226+
serviceAccountRef:
227+
name: vault-issuer
228+
```
229+
230+
> **Issuer vs. ClusterIssuer:** With an Issuer resource, you can only refer to a
231+
> service account located in the same namespace as the Issuer. With a
232+
> ClusterIssuer, the service account must be located in the namespace that is
233+
> configured by the flag `--cluster-resource-namespace`.
234+
235+
To create the role in Vault, you can use the following command:
236+
237+
```bash
238+
vault write auth/kubernetes/role/vault-issuer \
239+
bound_service_account_names=vault-issuer \
240+
bound_service_account_namespaces=sandbox \
241+
audience="vault://sandbox/vault-issuer" \
242+
policies=vault-issuer \
243+
ttl=1m
244+
```
245+
246+
It is recommended to use a different Vault role each per Issuer or
247+
ClusterIssuer. The `audience` allows you to restrict the Vault role to a single
248+
Issuer or ClusterIssuer. The syntax is the following:
249+
250+
```yaml
251+
"vault://<namespace>/<issuer-name>" # For an Issuer.
252+
"vault://<cluster-issuer-name>" # For a ClusterIssuer.
253+
```
254+
255+
The expiration duration for the Kubernetes tokens that are requested is
256+
hard-coded to 10 minutes (that's the minimum accepted). The `ttl` field can be
257+
as short as possible, since cert-manager requests a new token every time it
258+
needs to talks to Vault.
259+
260+
Although it is not recommended, you can also use the same Vault role for all of
261+
your Issuers and ClusterIssuers by omitting the `audience` field and re-using
262+
the same service account.
263+
<a name="static-service-account-token"></a>
264+
265+
#### Authentication with a Static Service Account Token
154266

155267
For the Vault issuer to use this authentication, cert-manager must get access to
156268
the token that is stored in a Kubernetes `Secret`. Kubernetes Service Account

content/docs/manifest.json

Lines changed: 68 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"path": "/docs/README.md"
99
},
1010
{
11-
"title": "Getting Started",
12-
"path": "/docs/getting-started/README.md"
11+
"title": "Getting Started",
12+
"path": "/docs/getting-started/README.md"
1313
},
1414
{
1515
"title": "Installation",
@@ -70,8 +70,8 @@
7070
"path": "/docs/installation/upgrading/upgrading-1.10-1.11.md"
7171
},
7272
{
73-
"title": "v1.9 to v1.10",
74-
"path": "/docs/installation/upgrading/upgrading-1.9-1.10.md"
73+
"title": "v1.9 to v1.10",
74+
"path": "/docs/installation/upgrading/upgrading-1.9-1.10.md"
7575
},
7676
{
7777
"title": "v1.8 to v1.9",
@@ -353,12 +353,12 @@
353353
"title": "trust-manager",
354354
"routes": [
355355
{
356-
"title": "Introduction",
357-
"path": "/docs/projects/trust-manager/README.md"
356+
"title": "Introduction",
357+
"path": "/docs/projects/trust-manager/README.md"
358358
},
359359
{
360-
"title": "API Reference",
361-
"path": "/docs/projects/trust-manager/api-reference.md"
360+
"title": "API Reference",
361+
"path": "/docs/projects/trust-manager/api-reference.md"
362362
}
363363
]
364364
}
@@ -372,20 +372,20 @@
372372
"path": "/docs/tutorials/README.md"
373373
},
374374
{
375-
"title": "Securing NGINX-ingress",
376-
"path": "/docs/tutorials/acme/nginx-ingress.md"
375+
"title": "Securing NGINX-ingress",
376+
"path": "/docs/tutorials/acme/nginx-ingress.md"
377377
},
378378
{
379-
"title": "GKE + Ingress + Let's Encrypt",
380-
"path": "/docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md"
379+
"title": "GKE + Ingress + Let's Encrypt",
380+
"path": "/docs/tutorials/getting-started-with-cert-manager-on-google-kubernetes-engine-using-lets-encrypt-for-ingress-ssl/README.md"
381381
},
382382
{
383-
"title": "AKS + LoadBalancer + Let's Encrypt",
384-
"path": "/docs/tutorials/getting-started-aks-letsencrypt/README.md"
383+
"title": "AKS + LoadBalancer + Let's Encrypt",
384+
"path": "/docs/tutorials/getting-started-aks-letsencrypt/README.md"
385385
},
386386
{
387-
"title": "Migrating from Kube-LEGO",
388-
"path": "/docs/tutorials/acme/migrating-from-kube-lego.md"
387+
"title": "Migrating from Kube-LEGO",
388+
"path": "/docs/tutorials/acme/migrating-from-kube-lego.md"
389389
},
390390
{
391391
"title": "Backup and Restore Resources",
@@ -421,22 +421,22 @@
421421
}
422422
]
423423
},
424-
{
425-
"title": "Troubleshooting",
426-
"routes": [
427-
{
428-
"title": "Introduction",
429-
"path": "/docs/troubleshooting/README.md"
424+
{
425+
"title": "Troubleshooting",
426+
"routes": [
427+
{
428+
"title": "Introduction",
429+
"path": "/docs/troubleshooting/README.md"
430430
},
431431
{
432-
"title": "Troubleshooting ACME / Let's Encrypt Certificates",
433-
"path": "/docs/troubleshooting/acme.md"
432+
"title": "Troubleshooting ACME / Let's Encrypt Certificates",
433+
"path": "/docs/troubleshooting/acme.md"
434434
},
435435
{
436-
"title": "Troubleshooting webhook",
437-
"path": "/docs/troubleshooting/webhook.md"
436+
"title": "Troubleshooting webhook",
437+
"path": "/docs/troubleshooting/webhook.md"
438438
}
439-
]
439+
]
440440
},
441441
{
442442
"title": "FAQ",
@@ -544,13 +544,17 @@
544544
"title": "Introduction",
545545
"path": "/docs/release-notes/README.md"
546546
},
547+
{
548+
"title": "v1.12",
549+
"path": "/docs/release-notes/release-notes-1.12.md"
550+
},
547551
{
548552
"title": "v1.11",
549553
"path": "/docs/release-notes/release-notes-1.11.md"
550554
},
551555
{
552-
"title": "v1.10",
553-
"path": "/docs/release-notes/release-notes-1.10.md"
556+
"title": "v1.10",
557+
"path": "/docs/release-notes/release-notes-1.10.md"
554558
},
555559
{
556560
"title": "v1.9",
@@ -691,56 +695,56 @@
691695
}
692696
]
693697
},
694-
{
695-
"title": "Reference",
696-
"routes": [
698+
{
699+
"title": "Reference",
700+
"routes": [
697701
{
698-
"title": "Introduction",
699-
"path": "/docs/reference/README.md"
702+
"title": "Introduction",
703+
"path": "/docs/reference/README.md"
700704
},
701705
{
702-
"title": "Command Line Tool (cmctl)",
703-
"path": "/docs/reference/cmctl.md"
706+
"title": "Command Line Tool (cmctl)",
707+
"path": "/docs/reference/cmctl.md"
704708
},
705-
{
706-
"title": "TLS Terminology",
707-
"path": "/docs/reference/tls-terminology.md"
709+
{
710+
"title": "TLS Terminology",
711+
"path": "/docs/reference/tls-terminology.md"
708712
},
709713

714+
{
715+
"title": "Components / Docker Images",
716+
"routes": [
710717
{
711-
"title": "Components / Docker Images",
712-
"routes": [
713-
{
714-
"title": "Introduction",
715-
"path": "/docs/cli/README.md"
718+
"title": "Introduction",
719+
"path": "/docs/cli/README.md"
716720
},
717-
{
718-
"title": "acmesolver",
719-
"path": "/docs/cli/acmesolver.md"
721+
{
722+
"title": "acmesolver",
723+
"path": "/docs/cli/acmesolver.md"
720724
},
721-
{
722-
"title": "cainjector",
723-
"path": "/docs/cli/cainjector.md"
725+
{
726+
"title": "cainjector",
727+
"path": "/docs/cli/cainjector.md"
724728
},
725-
{
726-
"title": "cmctl",
727-
"path": "/docs/cli/cmctl.md"
729+
{
730+
"title": "cmctl",
731+
"path": "/docs/cli/cmctl.md"
728732
},
729-
{
730-
"title": "controller",
731-
"path": "/docs/cli/controller.md"
733+
{
734+
"title": "controller",
735+
"path": "/docs/cli/controller.md"
732736
},
733-
{
734-
"title": "webhook",
735-
"path": "/docs/cli/webhook.md"
737+
{
738+
"title": "webhook",
739+
"path": "/docs/cli/webhook.md"
736740
}
737-
]
741+
]
738742
},
739-
{
740-
"title": "API Reference",
741-
"path": "/docs/reference/api-docs.md"
743+
{
744+
"title": "API Reference",
745+
"path": "/docs/reference/api-docs.md"
742746
}
743-
]
747+
]
744748
}
745749
]
746750
}

content/docs/release-notes/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ title: Release Notes
33
description: 'cert-manager release notes: Overview'
44
---
55

6+
- [`v1.12`](./release-notes-1.12.md)
67
- [`v1.11`](./release-notes-1.11.md)
78
- [`v1.10`](./release-notes-1.10.md)
89
- [`v1.9`](./release-notes-1.9.md)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: Release 1.12
3+
description: 'cert-manager release notes: cert-manager 1.12'
4+
---
5+
6+
## Major Themes
7+
8+
### Support for ephemeral service account tokens in Vault
9+
10+
cert-manager can now authenticate to Vault using ephemeral service account
11+
tokens. cert-manager already knew to authenticate to Vault using the [Vault
12+
Kubernetes Auth
13+
Method](https://developer.hashicorp.com/vault/docs/auth/kubernetes) but relied
14+
on insecure service account tokens stored in Secrets. You can now configure
15+
cert-manager in a secretless manner. With this new feature, cert-manager will
16+
create an ephemeral service account token on your behalf and use that to
17+
authenticate to Vault.
18+
19+
> 📖 Read about [Secretless Authentication with a Service Account](../configuration/vault.md#secretless-authentication-with-a-service-account).

0 commit comments

Comments
 (0)