Skip to content

Commit 1465f01

Browse files
authored
Merge pull request #50002 from sftim/20250303_csr_refactor_task
Move CSR for client certificate to tasks section
2 parents 091df8a + 2a3a72e commit 1465f01

File tree

3 files changed

+188
-127
lines changed

3 files changed

+188
-127
lines changed

content/en/docs/reference/access-authn-authz/authentication.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ presents a valid certificate signed by the cluster's certificate authority
3333
the username from the common name field in the 'subject' of the cert (e.g.,
3434
"/CN=bob"). From there, the role based access control (RBAC) sub-system would
3535
determine whether the user is authorized to perform a specific operation on a
36-
resource. For more details, refer to the normal users topic in
37-
[certificate request](/docs/reference/access-authn-authz/certificate-signing-requests/#normal-user)
38-
for more details about this.
36+
resource.
3937

4038
In contrast, service accounts are users managed by the Kubernetes API. They are
4139
bound to specific namespaces, and created automatically by the API server or
@@ -1815,5 +1813,6 @@ You can only make `SelfSubjectReview` requests if:
18151813

18161814
## {{% heading "whatsnext" %}}
18171815

1816+
* To learn about issuing certificates for users, read [Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequest](/docs/tasks/tls/certificate-issue-client-csr/)
18181817
* Read the [client authentication reference (v1beta1)](/docs/reference/config-api/client-authentication.v1beta1/)
18191818
* Read the [client authentication reference (v1)](/docs/reference/config-api/client-authentication.v1/)

content/en/docs/reference/access-authn-authz/certificate-signing-requests.md

Lines changed: 1 addition & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -489,133 +489,10 @@ signer-unlinked ClusterTrustBundles **must not** contain a colon (`:`).
489489
The contents of ClusterTrustBundles can be injected into the container filesystem, similar to ConfigMaps and Secrets.
490490
See the [clusterTrustBundle projected volume source](/docs/concepts/storage/projected-volumes#clustertrustbundle) for more details.
491491

492-
<!-- TODO this should become a task page -->
493-
## How to issue a certificate for a user {#normal-user}
494-
495-
A few steps are required in order to get a normal user to be able to
496-
authenticate and invoke an API. First, this user must have a certificate issued
497-
by the Kubernetes cluster, and then present that certificate to the Kubernetes API.
498-
499-
### Create private key
500-
501-
The following scripts show how to generate PKI private key and CSR. It is
502-
important to set CN and O attribute of the CSR. CN is the name of the user and
503-
O is the group that this user will belong to. You can refer to
504-
[RBAC](/docs/reference/access-authn-authz/rbac/) for standard groups.
505-
506-
```shell
507-
openssl genrsa -out myuser.key 2048
508-
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
509-
```
510-
511-
### Create a CertificateSigningRequest {#create-certificatessigningrequest}
512-
513-
Create a [CertificateSigningRequest](/docs/reference/kubernetes-api/authentication-resources/certificate-signing-request-v1/)
514-
and submit it to a Kubernetes Cluster via kubectl. Below is a script to generate the
515-
CertificateSigningRequest.
516-
517-
```shell
518-
cat <<EOF | kubectl apply -f -
519-
apiVersion: certificates.k8s.io/v1
520-
kind: CertificateSigningRequest
521-
metadata:
522-
name: myuser
523-
spec:
524-
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
525-
signerName: kubernetes.io/kube-apiserver-client
526-
expirationSeconds: 86400 # one day
527-
usages:
528-
- client auth
529-
EOF
530-
```
531-
532-
Some points to note:
533-
534-
- `usages` has to be '`client auth`'
535-
- `expirationSeconds` could be made longer (i.e. `864000` for ten days) or shorter (i.e. `3600` for one hour)
536-
- `request` is the base64 encoded value of the CSR file content.
537-
You can get the content using this command:
538-
539-
```shell
540-
cat myuser.csr | base64 | tr -d "\n"
541-
```
542-
543-
544-
### Approve the CertificateSigningRequest {#approve-certificate-signing-request}
545-
546-
Use kubectl to create a CSR and approve it.
547-
548-
Get the list of CSRs:
549-
550-
```shell
551-
kubectl get csr
552-
```
553-
554-
Approve the CSR:
555-
556-
```shell
557-
kubectl certificate approve myuser
558-
```
559-
560-
### Get the certificate
561-
562-
Retrieve the certificate from the CSR:
563-
564-
```shell
565-
kubectl get csr/myuser -o yaml
566-
```
567-
568-
The certificate value is in Base64-encoded format under `status.certificate`.
569-
570-
Export the issued certificate from the CertificateSigningRequest.
571-
572-
```shell
573-
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
574-
```
575-
576-
### Create Role and RoleBinding
577-
578-
With the certificate created it is time to define the Role and RoleBinding for
579-
this user to access Kubernetes cluster resources.
580-
581-
This is a sample command to create a Role for this new user:
582-
583-
```shell
584-
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
585-
```
586-
587-
This is a sample command to create a RoleBinding for this new user:
588-
589-
```shell
590-
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
591-
```
592-
593-
### Add to kubeconfig
594-
595-
The last step is to add this user into the kubeconfig file.
596-
597-
First, you need to add new credentials:
598-
599-
```shell
600-
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
601-
602-
```
603-
604-
Then, you need to add the context:
605-
606-
```shell
607-
kubectl config set-context myuser --cluster=kubernetes --user=myuser
608-
```
609-
610-
To test it, change the context to `myuser`:
611-
612-
```shell
613-
kubectl config use-context myuser
614-
```
615-
616492
## {{% heading "whatsnext" %}}
617493

618494
* Read [Manage TLS Certificates in a Cluster](/docs/tasks/tls/managing-tls-in-a-cluster/)
495+
* Read [Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequest](/docs/tasks/tls/certificate-issue-client-csr/)
619496
* View the source code for the kube-controller-manager built in
620497
[signer](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/signer/cfssl_signer.go)
621498
* View the source code for the kube-controller-manager built in
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
---
2+
title: Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequest
3+
api_metadata:
4+
- apiVersion: "certificates.k8s.io/v1"
5+
kind: "CertificateSigningRequest"
6+
override_link_text: "CSR v1"
7+
weight: 80
8+
9+
# Docs maintenance note
10+
#
11+
# If there is a future page /docs/tasks/tls/certificate-issue-client-manually/ then this page
12+
# should link there, and the new page should link back to this one.
13+
---
14+
15+
<!-- overview -->
16+
17+
Kubernetes lets you use a public key infrastructure (PKI) to authenticate to your cluster
18+
as a client.
19+
20+
A few steps are required in order to get a normal user to be able to
21+
authenticate and invoke an API. First, this user must have an [X.509](https://www.itu.int/rec/T-REC-X.509) certificate
22+
issued by an authority that your Kubernetes cluster trusts. The client must then present that certificate to the Kubernetes API.
23+
24+
You use a [CertificateSigningRequest](/concepts/security/certificate-signing-requests/)
25+
as part of this process, and either you or some other principal must approve the request.
26+
27+
28+
You will create a private key, and then get a certificate issued, and finally configure
29+
that private key for a client.
30+
31+
## {{% heading "prerequisites" %}}
32+
33+
* {{< include "task-tutorial-prereqs.md" >}}
34+
35+
* You need the `kubectl`, `openssl` and `base64` utilities.
36+
37+
This page assumes you are using Kubernetes {{< glossary_tooltip term_id="rbac" text="role based access control" >}} (RBAC).
38+
If you have alternative or additional security mechanisms around authorization, you need to account for those as well.
39+
40+
<!-- steps -->
41+
42+
## Create private key
43+
44+
In this step, you create a private key. You need to keep this document secret; anyone who has it can impersonate the user.
45+
46+
```shell
47+
# Create a private key
48+
openssl genrsa -out myuser.key 3072
49+
```
50+
51+
## Create an X.509 certificate signing request {#create-x.509-certificatessigningrequest}
52+
53+
{{< note >}}
54+
This is not the same as the similarly-named CertificateSigningRequest API; the file you generate here goes into the
55+
CertificateSigningRequest.
56+
{{< /note >}}
57+
58+
It is important to set CN and O attribute of the CSR. CN is the name of the user and O is the group that this user will belong to.
59+
You can refer to [RBAC](/docs/reference/access-authn-authz/rbac/) for standard groups.
60+
61+
```shell
62+
# Change the common name "myuser" to the actual username that you want to use
63+
openssl req -new -key myuser.key -out myuser.csr -subj "/CN=myuser"
64+
```
65+
66+
## Create a Kubernetes CertificateSigningRequest {#create-k8s-certificatessigningrequest}
67+
68+
Encode the CSR document using this command:
69+
70+
```shell
71+
cat myuser.csr | base64 | tr -d "\n"
72+
```
73+
74+
Create a [CertificateSigningRequest](/docs/reference/kubernetes-api/authentication-resources/certificate-signing-request-v1/)
75+
and submit it to a Kubernetes Cluster via kubectl. Below is a snippet of shell that you can use to generate the
76+
CertificateSigningRequest.
77+
78+
```shell
79+
cat <<EOF | kubectl apply -f -
80+
apiVersion: certificates.k8s.io/v1
81+
kind: CertificateSigningRequest
82+
metadata:
83+
name: myuser # example
84+
spec:
85+
# This is an encoded CSR. Change this to the base64-encoded contents of myuser.csr
86+
request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ1ZqQ0NBVDRDQVFBd0VURVBNQTBHQTFVRUF3d0dZVzVuWld4aE1JSUJJakFOQmdrcWhraUc5dzBCQVFFRgpBQU9DQVE4QU1JSUJDZ0tDQVFFQTByczhJTHRHdTYxakx2dHhWTTJSVlRWMDNHWlJTWWw0dWluVWo4RElaWjBOCnR2MUZtRVFSd3VoaUZsOFEzcWl0Qm0wMUFSMkNJVXBGd2ZzSjZ4MXF3ckJzVkhZbGlBNVhwRVpZM3ExcGswSDQKM3Z3aGJlK1o2MVNrVHF5SVBYUUwrTWM5T1Nsbm0xb0R2N0NtSkZNMUlMRVI3QTVGZnZKOEdFRjJ6dHBoaUlFMwpub1dtdHNZb3JuT2wzc2lHQ2ZGZzR4Zmd4eW8ybmlneFNVekl1bXNnVm9PM2ttT0x1RVF6cXpkakJ3TFJXbWlECklmMXBMWnoyalVnald4UkhCM1gyWnVVV1d1T09PZnpXM01LaE8ybHEvZi9DdS8wYk83c0x0MCt3U2ZMSU91TFcKcW90blZtRmxMMytqTy82WDNDKzBERHk5aUtwbXJjVDBnWGZLemE1dHJRSURBUUFCb0FBd0RRWUpLb1pJaHZjTgpBUUVMQlFBRGdnRUJBR05WdmVIOGR4ZzNvK21VeVRkbmFjVmQ1N24zSkExdnZEU1JWREkyQTZ1eXN3ZFp1L1BVCkkwZXpZWFV0RVNnSk1IRmQycVVNMjNuNVJsSXJ3R0xuUXFISUh5VStWWHhsdnZsRnpNOVpEWllSTmU3QlJvYXgKQVlEdUI5STZXT3FYbkFvczFqRmxNUG5NbFpqdU5kSGxpT1BjTU1oNndLaTZzZFhpVStHYTJ2RUVLY01jSVUyRgpvU2djUWdMYTk0aEpacGk3ZnNMdm1OQUxoT045UHdNMGM1dVJVejV4T0dGMUtCbWRSeEgvbUNOS2JKYjFRQm1HCkkwYitEUEdaTktXTU0xMzhIQXdoV0tkNjVoVHdYOWl4V3ZHMkh4TG1WQzg0L1BHT0tWQW9FNkpsYWFHdTlQVmkKdjlOSjVaZlZrcXdCd0hKbzZXdk9xVlA3SVFjZmg3d0drWm89Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
87+
signerName: kubernetes.io/kube-apiserver-client
88+
expirationSeconds: 86400 # one day
89+
usages:
90+
- client auth
91+
EOF
92+
```
93+
94+
Some points to note:
95+
96+
- `usages` has to be `client auth`
97+
- `expirationSeconds` could be made longer (i.e. `864000` for ten days) or shorter (i.e. `3600` for one hour).
98+
You cannot request a duration shorter than 10 minutes.
99+
- `request` is the base64 encoded value of the CSR file content.
100+
101+
## Approve the CertificateSigningRequest {#approve-certificate-signing-request}
102+
103+
Use kubectl to find the CSR you made, and manually approve it.
104+
105+
Get the list of CSRs:
106+
107+
```shell
108+
kubectl get csr
109+
```
110+
111+
Approve the CSR:
112+
113+
```shell
114+
kubectl certificate approve myuser
115+
```
116+
117+
## Get the certificate
118+
119+
Retrieve the certificate from the CSR, to check it looks OK.
120+
121+
```shell
122+
kubectl get csr/myuser -o yaml
123+
```
124+
125+
The certificate value is in Base64-encoded format under `.status.certificate`.
126+
127+
Export the issued certificate from the CertificateSigningRequest.
128+
129+
```shell
130+
kubectl get csr myuser -o jsonpath='{.status.certificate}'| base64 -d > myuser.crt
131+
```
132+
133+
## Configure the certificate into kubeconfig
134+
135+
The next step is to add this user into the kubeconfig file.
136+
137+
First, you need to add new credentials:
138+
139+
```shell
140+
kubectl config set-credentials myuser --client-key=myuser.key --client-certificate=myuser.crt --embed-certs=true
141+
142+
```
143+
144+
Then, you need to add the context:
145+
146+
```shell
147+
kubectl config set-context myuser --cluster=kubernetes --user=myuser
148+
```
149+
150+
To test it:
151+
152+
```shell
153+
kubectl --context myuser auth whoami
154+
```
155+
156+
You should see output confirming that you are “myuser“.
157+
158+
## Create Role and RoleBinding
159+
160+
{{< note >}}
161+
If you don't use Kubernetes RBAC, skip this step and make the appropriate changes for the authorization mechanism
162+
your cluster actually uses.
163+
{{< /note >}}
164+
165+
With the certificate created it is time to define the Role and RoleBinding for
166+
this user to access Kubernetes cluster resources.
167+
168+
This is a sample command to create a Role for this new user:
169+
170+
```shell
171+
kubectl create role developer --verb=create --verb=get --verb=list --verb=update --verb=delete --resource=pods
172+
```
173+
174+
This is a sample command to create a RoleBinding for this new user:
175+
176+
```shell
177+
kubectl create rolebinding developer-binding-myuser --role=developer --user=myuser
178+
```
179+
180+
## {{% heading "whatsnext" %}}
181+
182+
* Read [Manage TLS Certificates in a Cluster](/docs/tasks/tls/managing-tls-in-a-cluster/)
183+
* For details of X.509 itself, refer to [RFC 5280](https://tools.ietf.org/html/rfc5280#section-3.1) section 3.1
184+
* For information on the syntax of PKCS#10 certificate signing requests, refer to [RFC 2986](https://tools.ietf.org/html/rfc2986)
185+
* Read about [ClusterTrustBundles](/docs/reference/access-authn-authz/certificate-signing-requests/#cluster-trust-bundles)

0 commit comments

Comments
 (0)