diff --git a/content/en/docs/concepts/security/certificates.md b/content/en/docs/concepts/security/certificates.md new file mode 100644 index 0000000000000..7fab5dff94fad --- /dev/null +++ b/content/en/docs/concepts/security/certificates.md @@ -0,0 +1,578 @@ +--- +reviewers: +- liggitt +- mikedanese +- munnerz +- enj +title: Certificate Provisioning and Trust Distribution +api_metadata: +- apiVersion: "certificates.k8s.io/v1" + kind: "CertificateSigningRequest" + override_link_text: "CSR v1" +- apiVersion: "certificates.k8s.io/v1beta1" + kind: "ClusterTrustBundle" +- apiVersion: "certificates.k8s.io/v1alpha1" + kind: "PodCertificateRequest" +content_type: concept +weight: 60 +--- + + + +Kubernetes certificate and trust bundle APIs enable automation of +[X.509](https://www.itu.int/rec/T-REC-X.509) credential provisioning by +providing a programmatic interface for clients of the Kubernetes API to request +and obtain X.509 {{< glossary_tooltip term_id="certificate" text="certificates" +>}} from a Certificate Authority (CA). + +The three API types for requesting and trusting certificates are: +* CertificateSigningRequest: An API type that lets you request an arbitrary + certificate from a signer. +* PodCertificateRequest: (alpha) An API type that lets `kubelet` request + certificates to inject into a Pod. +* ClusterTrustBundle: (beta) A group of certificates (typically CA root + certificates) that should be used as roots of trust for verifying a server or + client certificate. + + + + +## Signers {#signers} + +Kubernetes organizes its certificate provisioning features around the concept of +a signer. + +Each signer is identified by a qualified name built from a DNS name (for +example, `kubernetes.io/foo`). Each signer uniquely identifies a category of +certificates that can be issued within the scope of a particular cluster. +Kubernetes offers some [built-in signers](#kubernetes-signers), and third-party +signers may also be freely installed into a cluster. + +Note that signers are not a concrete concept in the Kubernetes API — there +is no Signer object that you create. Instead, several types in the +`certificates.k8s.io` API group have a `signerName` field, and there is special +authorization logic that lets signers handle all objects that are addressed to a +particular signer. + +Each signer is backed by a set of {{< glossary_tooltip text="controllers" +term_id="controller" >}} that do one or more of the following things to let +pods, users, and external workloads provision and verify certificates issued by +the signer. +* Certificate issuance: The signer responds to CertificateSigningRequests and + PodCertificateRequests addressed to the signer's name. +* Trust anchor distribution: The controller publishes the trust anchors (root + certificates) of the signer for consumption by workloads using either + signer-linked ClusterTrustBundles or ConfigMaps + +The Kubernetes project provides a set of [built-in signers](#kubernetes-signers) +that are available in every cluster. It is also possible to install (or build +your own) [third-party signers](#third-party-signers). + + +## Certificate signing requests {#certificate-signing-requests} + +A +[CertificateSigningRequest](/docs/reference/kubernetes-api/authentication-resources/certificate-signing-request-v1/) +(CSR) is used to request a certificate from a particular signer. + +The CSR flow begins when a requester creates a CSR object: +* `spec.signerName` says which signer should process the CSR. +* `spec.request` contains a PEM-wrapped PKCS#10 signing request. +* `spec.expirationSeconds` (optional) allows the requester to ask for a specific + lifetime for the issued certificate. +* `spec.usages` contains the key usages that the requester wants on the issued + certificate. + +Once created, a CSR must be approved before it can be signed. Approval is +indicated by adding an `Approved` entry to `status.conditions`. Denial is +indicated by adding a `Denied` entry to `status.conditions`. Both of these +conditions must always have `status` set to `True`. These conditions are +mutually-exclusive. + +Different signers have different expectations around their approval workflows, +so signer authors are encouraged to document whether and how they expect CSRs to +be approved. Broadly speaking: +* Some signers automatically approve conforming CSRs, and will refuse to issue a + certificate to a non-conforming CSR. These signers will move an approved, but + non-conforming CSR into the `Failed` terminal state, rather than issuing it. + For example, a signer might only want to issue SPIFFE certificates, and so + will fail any CSR that requests a non-SPIFFE-formatted CSR. +* Some signers expect a human reviewer to inspect and approve all + CSRs. The `kubectl certificate approve/deny` + convenience commands may be used for this purpose. +* Some signers operate in a blended mode, where some CSRs are automatically + approved and issued, but the signer will also issue certificates to + manually-approved CSRs. + +Special permissions are required to approve or deny a CSR: +* Verbs: **update**, group: `certificates.k8s.io`, resource: + `certificatesigningrequests/approval` +* Verbs: **approve**, group: `certificates.k8s.io`, resource: `signers`, + resourceName: `/` or `/*` + +Once a CSR is approved, the next step is for the signer's controller to either +issue a certificate or fail the CSR. + +To issue a certificate to a CSR, the controller creates an X.509 certificate +chain and stores it in the `status.certificate` field of the CSR, encoded as a +series of PEM `CERTIFICATE` blocks. The signer implementation may, but does not +have to, consider the CSR's `spec.request` field. It is free to issue an +entirely different certificate. + +{{< note >}} +When encoded in JSON or YAML, `status.certificate` field is base-64 encoded, so +it is not directly readable. This is handled transparently when using a client +library. +{{< /note >}} + +Signer implementations are encouraged to: +* Document whether or not they consider manual approval decisions on + CertificateSigningRequests. +* Document which parts, if any, of the PKCS#10 request they consider. +* Document the concrete format of the certificates they issue. + +Once the `status.certificate` field has been populated, the request has been +completed and clients can now fetch the signed certificate PEM data from the +CSR. + +If the signer controller does not wish to issue the certificate, even if it has +been approved, then it can add the `Failed` condition to the CSR, which is a +terminal state. + +Special permissions are required to sign or fail a CSR: +* Verbs: **update**, group: `certificates.k8s.io`, resource: + `certificatesigningrequests/status` +* Verbs: **sign**, group: `certificates.k8s.io`, resource: `signers`, + resourceName: `/` or `/*` + +Like all conditions, the `status.conditions[].reason` field is meant to contain +a machine-readable code describing the condition in TitleCase. The +`status.conditions[].message` field is meant for a free-form explanation for +human consumption. + +In order to reduce the number of old CSR objects left in a cluster, a garbage +collection controller runs periodically. The garbage collection removes CSRs +that have not changed state for some duration: + +* Approved requests: automatically deleted after 1 hour +* Denied requests: automatically deleted after 1 hour +* Failed requests: automatically deleted after 1 hour +* Pending requests: automatically deleted after 24 hours +* All requests: automatically deleted after the issued certificate has expired + + +## PodCertificateRequests {#pod-certificate-requests} + +{{< feature-state feature_gate_name="PodCertificateRequest" >}} + +{{< note >}} +In Kubernetes {{< skew currentVersion >}}, you must enable support for Pod +Certificates using the `PodCertificateRequest` [feature +gate](/docs/reference/command-line-tools-reference/feature-gates/) and the +`--runtime-config=certificates.k8s.io/v1alpha1/podcertificaterequests=true` +kube-apiserver flag. +{{< /note >}} + +PodCertificateRequests are API objects tailored to provisioning certificates to +workloads running as Pods within a cluster. The user typically does not +interact with PodCertificateRequests directly, but uses [podCertificate +projected volume sources]( +/docs/concepts/storage/projected-volumes#podcertificate), which are a `kubelet` +feature that handles secure key provisioning and automatic certificate refresh. +The application inside the pod only needs to know how to read the certificates +from the filesystem. + +PodCertificateRequests are similar to CertificateSigningRequests, but have a +simpler format enabled by their narrower use case. + +A PodCertificateRequest has the following spec fields: +* `signerName`: The signer to which this request is addressed. +* `podName` and `podUID`: The Pod that Kubelet is requesting a certificate for. +* `serviceAccountName` and `serviceAccountUID`: The ServiceAccount corresponding to the Pod. +* `nodeName` and `nodeUID`: The Node corresponding to the Pod. +* `maxExpirationSeconds`: The maximum lifetime that the workload author will + accept for this certificate. Defaults to 24 hours if not specified. +* `pkixPublicKey`: The public key for which the certificate should be issued. +* `proofOfPossession`: A signature demonstrating that the requester controls the + private key corresponding to `pkixPublicKey`. + +Nodes automatically receive permissions to create PodCertificateRequests and +read PodCertificateRequests related to them (as determined by the +`spec.nodeName` field). The [NodeRestriction admission +plugin](/docs/reference/access-authn-authz/admission-controllers#noderestriction), +if enabled, ensures that nodes can only create PodCertificateRequests that +correspond to a real pod that is currently running on the node. + +After creation, the `spec` of a PodCertificateRequest is immutable. + +Unlike CSRs, PodCertificateRequests do not have an +approval phase. Once the PodCertificateRequest is created, the signer's +controller directly decides to issue or deny the request. It also has the +option to mark the request as failed, if it encountered a permanent error when +attempting to issue the request. + +To take any of these actions, the signing controller needs to have the +appropriate permissions on both the PodCertificateRequest type, as well as on +the signer name: +* Verbs: **update**, group: `certificates.k8s.io`, resource: + `podcertificaterequests/status` +* Verbs: **sign**, group: `certificates.k8s.io`, resource: `signers`, + resourceName: `/` or `/*` + +The signing controller is free to consider other information beyond what's +contained in the request, but it can rely on the information in the request to +be accurate. For example, the signing controller might load the Pod and read +annotations set on it, or perform a SubjectAccessReview on the ServiceAccount. + +To issue a certificate in response to a request, the signing controller: +* Adds an `Issued` condition to `status.conditions`. +* Puts the issued certificate in `status.certificateChain` +* Puts the `NotBefore` and `NotAfter` fields of the certificate in the + `status.notBefore` and `status.notAfter` fields — these fields are + denormalized into the Kubernetes API in order to aid debugging +* Suggests a time to begin attempting to refresh the certificate using + `status.beginRefreshAt`. + +To deny a request, the signing controller adds a "Denied" condition to +`status.conditions[]`. + +To mark a request failed, the signing controller adds a "Failed" condition to +`status.conditions[]`. + +All of these conditions are mutually-exclusive, and must have status "True". No +other condition types are permitted on PodCertificateRequests. In addition, +once any of these conditions are set, the `status` field becomes immutable. + +Like all conditions, the `status.conditions[].reason` field is meant to contain +a machine-readable code describing the condition in TitleCase. The +`status.conditions[].message` field is meant for a free-form explanation for +human consumption. + +To ensure that terminal PodCertificateRequests do not build up in the cluster, a +`kube-controller-manager` controller deletes all PodCertificateRequests older +than 15 minutes. All certificate issuance flows are expected to complete within +this 15-minute limit. + + +## ClusterTrustBundles {#cluster-trust-bundles} + +{{< feature-state feature_gate_name="ClusterTrustBundle" >}} + +{{< note >}} +In Kubernetes {{< skew currentVersion >}}, you must enable the `ClusterTrustBundle` +[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) +_and_ the `certificates.k8s.io/v1beta1` +{{< glossary_tooltip text="API group" term_id="api-group" >}} in order to use +this API. +{{< /note >}} + +A ClusterTrustBundle is a cluster-scoped object for distributing X.509 trust +anchors (root certificates) to workloads within the cluster. They're designed +to work well with the [signer](#signers) concept from CertificateSigningRequests. + +ClusterTrustBundles can be used in two modes: +[signer-linked](#ctb-signer-linked) and [signer-unlinked](#ctb-signer-unlinked). + +### Common properties and validation {#ctb-common} + +All ClusterTrustBundle objects have strong validation on the contents of their +`trustBundle` field. That field must contain one or more X.509 certificates, +DER-serialized, each wrapped in a PEM `CERTIFICATE` block. The certificates +must parse as valid X.509 certificates. + +Esoteric PEM features like inter-block data and intra-block headers are either +rejected during object validation, or can be ignored by consumers of the object. +Additionally, consumers are allowed to reorder the certificates in +the bundle with their own arbitrary but stable ordering. + +ClusterTrustBundle objects should be considered world-readable within the +cluster. If your cluster uses [RBAC](/docs/reference/access-authn-authz/rbac/) +authorization, all ServiceAccounts have a default grant that allows them to +**get**, **list**, and **watch** all ClusterTrustBundle objects. +If you use your own authorization mechanism and you have enabled +ClusterTrustBundles in your cluster, you should set up an equivalent rule to +make these objects public within the cluster, so that they work as intended. + +If you do not have permission to list cluster trust bundles by default in your +cluster, you can impersonate a service account you have access to in order to +see available ClusterTrustBundles: + +```bash +kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default' +``` + +### Signer-linked ClusterTrustBundles {#ctb-signer-linked} + +Signer-linked ClusterTrustBundles are associated with a _signer name_, like this: + +```yaml +apiVersion: certificates.k8s.io/v1beta1 +kind: ClusterTrustBundle +metadata: + name: example.com:mysigner:foo +spec: + signerName: example.com/mysigner + trustBundle: "<... PEM data ...>" +``` + +These ClusterTrustBundles are intended to be maintained by a signer-specific +controller in the cluster, so they have several security features: + +* To create or update a signer-linked ClusterTrustBundle, you must be permitted + to **attest** on the signer (custom authorization verb `attest`, + API group `certificates.k8s.io`; resource path `signers`). You can configure + authorization for the specific resource name + `/` or match a pattern such as + `/*`. +* Signer-linked ClusterTrustBundles **must** be named with a prefix derived from + their `spec.signerName` field. Slashes (`/`) are replaced with colons (`:`), + and a final colon is appended. This is followed by an arbitrary name. For + example, the signer `example.com/mysigner` can be linked to a + ClusterTrustBundle `example.com:mysigner:`. + +Signer-linked ClusterTrustBundles will typically be consumed in workloads +by a combination of a +[field selector](/docs/concepts/overview/working-with-objects/field-selectors/) on the signer name, and a separate +[label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors). + +### Signer-unlinked ClusterTrustBundles {#ctb-signer-unlinked} + +Signer-unlinked ClusterTrustBundles have an empty `spec.signerName` field, like this: + +```yaml +apiVersion: certificates.k8s.io/v1beta1 +kind: ClusterTrustBundle +metadata: + name: foo +spec: + # no signerName specified, so the field is blank + trustBundle: "<... PEM data ...>" +``` + +They are primarily intended for cluster configuration use cases. +Each signer-unlinked ClusterTrustBundle is an independent object, in contrast to the +customary grouping behavior of signer-linked ClusterTrustBundles. + +Signer-unlinked ClusterTrustBundles have no `attest` verb requirement. +Instead, you control access to them directly using the usual mechanisms, +such as role-based access control. + +To distinguish them from signer-linked ClusterTrustBundles, the names of +signer-unlinked ClusterTrustBundles **must not** contain a colon (`:`). + +### Accessing ClusterTrustBundles from pods {#ctb-projection} + +{{< feature-state feature_gate_name="ClusterTrustBundleProjection" >}} + +The contents of ClusterTrustBundles can be injected into the container filesystem, similar to ConfigMaps and Secrets. +See the [clusterTrustBundle projected volume source](/docs/concepts/storage/projected-volumes#clustertrustbundle) for more details. + + +## Kubernetes built-in signers {#kubernetes-signers} + +Kubernetes provides some built-in signers that should be present in every +cluster. + +{{< caution >}} +Signer names with domain prefix `kubernetes.io` (including any subdomains) are +reserved by the Kubernetes project. +{{< /caution >}} + +### `kubernetes.io/kube-apiserver-client` {#built-in-signer-kube-apiserver-client} + +This signer issues certificates that will be honored as client certificates by +the API server. + +This signer responds only to CertificateSigningRequests, not +PodCertificateRequests. + +There is no built-in auto-approval controller for this signer; all certificates +must be manually approved, or a third-party auto-approval controller must be +installed. + +This signer does not distribute its trust bundle, since no party besides the API +server is intended to verify the certificates it issues. + +When this signer's signing controller sees an approved +CertificateSigningRequest, it will check the following conditions: +* The `spec.usages` field includes at least "client auth" and at most "client auth", "digital + signature", and "key encipherment". + +If the conditions are true, the signing controller will issue the certificate. +Otherwise it will mark the CSR as failed. + +The issued certificate has the following properties: +* The X.509 Subject field Subject Alternate Names extension are copied verbatim + from `spec.request`. +* The "Key Usage" and "Extended Key Usage" extensions are set according to the key + usages named in `spec.usages`. +* No other extensions are included. +* NotBefore is set to the present time, with reasonable backdating to + account for clock skew. +* NotAfter is set to the present time plus the minimum of `spec.expirationSeconds` + and the certificate TTL configured for `kube-controller-manager` (365 days, by + default), with reasonable backdating to account for clock skew. +* The CA bit to false. + +{{< caution >}} + +Because the API server treats `Subject.CommonName` and `Subject.Organization` as +the username and groups of the user, you must take care when approving CSRs +addressed to this signer. If you approve CSRs that request identities that are +internal to the function of your Kubernetes distribution, the user that gets the +certificate can compromise your cluster. + +The `CertificateSubjectRestriction` admission plugin (enabled by default) +prevents creation of CSRs that would assert membership in the `system:masters` +group, but this is typically not the only highly-privileged identity present in +a cluster. + +{{}} + +### `kubernetes.io/kube-apiserver-client-kubelet` {#built-in-signer-kube-apiserver-client-kubelet} + +This signer issues certificates that will be honored as `kubelet` client +certificates by the API server. It offers no further guarantees on what the +certificates may be used for. + +This signer responds only to CertificateSigningRequests, not +PodCertificateRequests. + +There is a built-in auto-approval controller for this signer. + +This signer does not distribute its trust bundle, since no party besides the API +server is intended to verify the certificates it issues. + +When this signer's signing controller sees an approved +CertificateSigningRequest, it will check the following conditions: +* The `Subject.CommonName` field has the prefix `system:node:` +* There is one `Subject.Organization` entry, exactly equal to `system:nodes` +* There are no entries in the Subject Alternate Name extension +* The CSR `spec.usages` field is either: + * `digital signature` and `client auth`, or + * `digital signature`, `client auth`, and `key encipherment`. + +If the conditions are true, the signing controller will issue the certificate. +Otherwise it will mark the CSR as failed. + +The issued certificate has the following properties: +* The X.509 Subject field Subject Alternate Names extension are copied verbatim + from `spec.request`. +* The "Key Usage" and "Extended Key Usage" extensions are set according to the key + usages named in `spec.usages`. +* No other extensions are included. +* NotBefore is set to the present time, with reasonable backdating to + account for clock skew. +* NotAfter is set to the present time plus the minimum of `spec.expirationSeconds` + and the certificate TTL configured for `kube-controller-manager` (365 days, by + default), with reasonable backdating to account for clock skew. +* The CA bit to false. + +### `kubernetes.io/kubelet-serving` {#built-in-signer-kube-apiserver-client-kubelet-serving} + +This signer issues certificates that the API server will honor as valid +`kubelet` serving certificates. It offers no further guarantees on what the +certificates may be used for. + +This signer responds only to CertificateSigningRequests, not +PodCertificateRequests. + +There is no built-in auto-approval controller for this signer. + +This signer does not distribute its trust bundle, since no party besides the API +server is intended to verify the certificates it issues. + +When this signer's signing controller sees an approved +CertificateSigningRequest, it will check the following conditions: +* The `Subject.CommonName` field has the prefix `system:node:` +* There is one `Subject.Organization` entry, exactly equal to `system:nodes` +* There is at least one DNS or IP entry in Subject Alternate Name extension. +* There are no Email or URI entries in the Subject Alternate Name extension. +* The CSR `spec.usages` field is either: + * `digital signature` and `server auth`, or + * `digital signature`, `server auth`, and `key encipherment`. + +If the conditions are true, the signing controller will issue the certificate. +Otherwise it will mark the CSR as failed. + +The issued certificate has the following properties: +* The X.509 Subject field Subject Alternate Names extension are copied verbatim + from `spec.request`. +* The "Key Usage" and "Extended Key Usage" extensions are set according to the key + usages named in `spec.usages`. +* No other extensions are included. +* NotBefore is set to the present time, with reasonable backdating to + account for clock skew. +* NotAfter is set to the present time plus the minimum of `spec.expirationSeconds` + and the certificate TTL configured for `kube-controller-manager` (365 days, by + default), with reasonable backdating to account for clock skew. +* The CA bit to false. + +### `kubernetes.io/kube-apiserver-serving` {#built-in-signer-kube-apiserver-serving} + +{{< feature-state feature_gate_name="ClusterTrustBundle" >}} + +This signer does not issue any certificates. It purely serves to distribute the +trust anchors that allow workloads within the cluster to verify the API server's +server certificate when they connect to `kubernetes.default.svc`. + +There are three built-in distribution mechanisms for these trust anchors: +* A built-in controller writes them into the `.data[ca.crt]` field of + ServiceAccount token secrets. +* A built-in controller creates a ConfigMap named `kube-root-ca.crt` in each + namespace. The `.data["ca.crt"]` field of this configmap contains the trust + anchors of this signer. +* (Only when ClusterTrustBundles are enabled) A built-in controller creates a + set of signer-linked ClusterTrustBundles for this signer. Workloads can + access them directly, or using `clusterTrustBundle` projected volumes sources + (`signerName="kubernetes.io/kube-apiserver-serving"` and + `labelSelector.matchLabels={}`). + +### `kubernetes.io/legacy-unknown` {#built-in-signer-legacy-unknown} + +This signer issues certificates that are not guaranteed to be suitable for any +purpose. In some third-party distributions of Kubernetes, the API server may +accept certificates it issues as client certificates, but this is not a +standard. + +This signer only responds to CertificateSigningRequests, not +PodCertificateRequests. + +There is not built-in auto-approval controller for this signer. + +The stable CertificateSigningRequest API (version `certificates.k8s.io/v1` and +later) does not allow to set the `signerName` as `kubernetes.io/legacy-unknown`. + +This signer does not distribute its trust bundle. + +When this signer's signing controller sees an approved +CertificateSigningRequest, it will immediately attempt to issue the certificate +with no further checks. + +The issued certificate has the following properties: +* The X.509 Subject field Subject Alternate Names extension are copied verbatim + from `spec.request`. +* The "Key Usage" and "Extended Key Usage" extensions are set according to the key + usages named in `spec.usages`. +* No other extensions are included. +* NotBefore is set to the present time, with reasonable backdating to + account for clock skew. +* NotAfter is set to the present time plus the minimum of `spec.expirationSeconds` + and the certificate TTL configured for `kube-controller-manager` (365 days, by + default), with reasonable backdating to account for clock skew. +* The CA bit to false. + + +## Third-party signers {#third-party-signers} + +You can also introduce your own custom signer, which should have a similar +prefixed name but using your own domain name. For example, if you represent an +open source project that uses the domain `open-fictional.example` then you might +use `issuer.open-fictional.example/service-mesh` as a signer name. + +To implement your custom signer, you need to provide a set of controllers that +use the Kubernetes API to interact with CertificateSigningRequests, +PodCertificateRequests, and ClusterTrustBundles that are linked to your signer's +name. + +See [Develop a Custom Signer](/docs/tasks/tls/extend-kubernetes/custom-signer) for more details. diff --git a/content/en/docs/concepts/storage/projected-volumes.md b/content/en/docs/concepts/storage/projected-volumes.md index 509b4cc31f15a..35c85177363f4 100644 --- a/content/en/docs/concepts/storage/projected-volumes.md +++ b/content/en/docs/concepts/storage/projected-volumes.md @@ -25,6 +25,7 @@ Currently, the following types of volume sources can be projected: * [`configMap`](/docs/concepts/storage/volumes/#configmap) * [`serviceAccountToken`](#serviceaccounttoken) * [`clusterTrustBundle`](#clustertrustbundle) +* [`podCertificate`](#podcertificate) All sources are required to be in the same namespace as the Pod. For more details, see the [all-in-one volume](https://git.k8s.io/design-proposals-archive/node/all-in-one-volume.md) design document. @@ -96,6 +97,60 @@ By default, the kubelet will prevent the pod from starting if the named ClusterT {{% code_sample file="pods/storage/projected-clustertrustbundle.yaml" %}} +## podCertificate projected volumes {#podcertificate} + +{{< feature-state feature_gate_name="PodCertificateRequest" >}} + +{{< note >}} +In Kubernetes {{< skew currentVersion >}}, you must enable support for Pod +Certificates using the `PodCertificateRequest` [feature +gate](/docs/reference/command-line-tools-reference/feature-gates/) and the +`--runtime-config=certificates.k8s.io/v1alpha1/podcertificaterequests=true` +kube-apiserver flag. +{{< /note >}} + +The `podCertificate` projected volumes source securely provisions a private key +and X.509 certificate chain for pod to use as client or server credentials. +Kubelet will then handle refreshing the private key and certificate chain when +they get close to expiration. The application just has to make sure that it +reloads the file promptly when it changes, with a mechanism like `inotify` or +polling. + +Each `podCertificate` projection supports the following configuration fields: +* `signerName`: The + [signer](/docs/reference/access-authn-authz/certificate-signing-requests#signers) + you want to issue the certificate. Note that signers may have their own + access requirements, and may refuse to issue certificates to your pod. +* `keyType`: The type of private key that should be generated. Valid values are + `ED25519`, `ECDSAP256`, `ECDSAP384`, `ECDSAP521`, `RSA3072`, and `RSA4096`. +* `maxExpirationSeconds`: The maximum lifetime you will accept for the + certificate issued to the pod. If not set, will be defaulted to `86400` (24 + hours). Must be at least `3600` (1 hour), and at most `7862400` (91 days). + The signer is allowed to issue a certificate with a lifetime shorter than what + you've specified. +* `credentialBundlePath`: Relative path within the projection where the + credential bundle should be written. The credential bundle is a PEM-formatted + file, where the first block is a "PRIVATE KEY" block that contains a + PKCS#8-serialized private key, and the remaining blocks are "CERTIFICATE" + blocks that comprise the certificate chain (leaf certificate and any + intermediates). +* `keyPath` and `certificateChainPath`: Separate paths where Kubelet should + write *just* the private key or certificate chain. + +{{< note >}} + +Most applications should prefer using `credentialBundlePath` unless they need +the key and certificates in separate files for compatibility reasons. Kubelet +uses an atomic writing strategy based on symlinks to make sure that when you +open the files it projects, you read either the old content or the new content. +However, if you read the key and certificate chain from separate files, Kubelet +may rotate the credentials after your first read and before your second read, +resulting in your application loading a mismatched key and certificate. + +{{< /note >}} + +{{% code_sample file="pods/storage/projected-podcertificate.yaml" %}} + ## SecurityContext interactions The [proposal](https://git.k8s.io/enhancements/keps/sig-storage/2451-service-account-token-volumes#proposal) for file permission handling in projected service account volume enhancement introduced the projected files having the correct owner permissions set. diff --git a/content/en/docs/reference/access-authn-authz/authentication.md b/content/en/docs/reference/access-authn-authz/authentication.md index 5534ac6bab442..2ddc9b7f90975 100644 --- a/content/en/docs/reference/access-authn-authz/authentication.md +++ b/content/en/docs/reference/access-authn-authz/authentication.md @@ -380,7 +380,7 @@ command line arguments, and use the configuration file instead. # CAUTION: this is an example configuration. # Do not use this for your own cluster! # -apiVersion: apiserver.config.k8s.io/v1beta1 +apiVersion: apiserver.config.k8s.io/v1 kind: AuthenticationConfiguration # list of authenticators to authenticate Kubernetes users using JWT compliant tokens. # the maximum number of allowed authenticators is 64. @@ -513,7 +513,7 @@ jwt: {{< tabs name="example_configuration" >}} {{% tab name="Valid token" %}} ```yaml - apiVersion: apiserver.config.k8s.io/v1beta1 + apiVersion: apiserver.config.k8s.io/v1 kind: AuthenticationConfiguration jwt: - issuer: @@ -574,7 +574,7 @@ jwt: {{% /tab %}} {{% tab name="Fails claim validation" %}} ```yaml - apiVersion: apiserver.config.k8s.io/v1beta1 + apiVersion: apiserver.config.k8s.io/v1 kind: AuthenticationConfiguration jwt: - issuer: @@ -625,7 +625,7 @@ jwt: {{% /tab %}} {{% tab name="Fails user validation" %}} ```yaml - apiVersion: apiserver.config.k8s.io/v1beta1 + apiVersion: apiserver.config.k8s.io/v1 kind: AuthenticationConfiguration jwt: - issuer: @@ -1095,7 +1095,7 @@ A sample authentication configuration file is below: # CAUTION: this is an example configuration. # Do not use this for your own cluster! # -apiVersion: apiserver.config.k8s.io/v1beta1 +apiVersion: apiserver.config.k8s.io/v1 kind: AuthenticationConfiguration anonymous: enabled: true diff --git a/content/en/docs/reference/access-authn-authz/authorization.md b/content/en/docs/reference/access-authn-authz/authorization.md index 292bf6f8ae4e8..204ac36bf473a 100644 --- a/content/en/docs/reference/access-authn-authz/authorization.md +++ b/content/en/docs/reference/access-authn-authz/authorization.md @@ -219,11 +219,23 @@ authorizers: # Same as setting `--authorization-webhook-cache-authorized-ttl` flag # Default: 5m0s authorizedTTL: 30s + # If set to false, 'authorized' responses from the webhook are not cached + # and the specified authorizedTTL is ignored/has no effect. + # Same as setting `--authorization-webhook-cache-authorized-ttl` flag to `0`. + # Note: Setting authorizedTTL to `0` results in its default value being used. + # Default: true + cacheAuthorizedRequests: true # The duration to cache 'unauthorized' responses from the webhook # authorizer. # Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag # Default: 30s unauthorizedTTL: 30s + # If set to false, 'unauthorized' responses from the webhook are not cached + # and the specified unauthorizedTTL is ignored/has no effect. + # Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag to `0`. + # Note: Setting unauthorizedTTL to `0` results in its default value being used. + # Default: true + cacheUnauthorizedRequests: true # Timeout for the webhook request # Maximum allowed is 30s. # Required, with no default. diff --git a/content/en/docs/reference/access-authn-authz/certificate-signing-requests.md b/content/en/docs/reference/access-authn-authz/certificate-signing-requests.md index 58bcae9b840f8..da2e80845bc86 100644 --- a/content/en/docs/reference/access-authn-authz/certificate-signing-requests.md +++ b/content/en/docs/reference/access-authn-authz/certificate-signing-requests.md @@ -4,500 +4,26 @@ reviewers: - mikedanese - munnerz - enj -title: Certificates and Certificate Signing Requests -api_metadata: -- apiVersion: "certificates.k8s.io/v1" - kind: "CertificateSigningRequest" - override_link_text: "CSR v1" -- apiVersion: "certificates.k8s.io/v1alpha1" - kind: "ClusterTrustBundle" +title: Authenticating to the Kubernetes API with Client Certificates content_type: concept weight: 60 --- -Kubernetes certificate and trust bundle APIs enable automation of -[X.509](https://www.itu.int/rec/T-REC-X.509) credential provisioning by providing -a programmatic interface for clients of the Kubernetes API to request and obtain -X.509 {{< glossary_tooltip term_id="certificate" text="certificates" >}} from a Certificate Authority (CA). +The Kubernetes API supports optional client certificate authentication. To make use of it, you must: +* Ensure that `kube-apiserver` has client certificate authentication enabled, +* Generate a private key and request a client certificate using the Kubernetes API. +* Configure your client to use the private key and certificate for authentication. -There is also experimental (alpha) support for distributing [trust bundles](#cluster-trust-bundles). +Before you begin, [read about the mechanisms for requesting certificates](/docs/concepts/security/certificates). -## Certificate signing requests -{{< feature-state for_k8s_version="v1.19" state="stable" >}} +## Configuring client certificate authentication on kube-apiserver +TODO: List flags -A [CertificateSigningRequest](/docs/reference/kubernetes-api/authentication-resources/certificate-signing-request-v1/) -(CSR) resource is used to request that a certificate be signed -by a denoted signer, after which the request may be approved or denied before -finally being signed. - -### Request signing process - -The CertificateSigningRequest resource type allows a client to ask for an X.509 certificate -be issued, based on a signing request. -The CertificateSigningRequest object includes a PEM-encoded PKCS#10 signing request in -the `spec.request` field. The CertificateSigningRequest denotes the signer (the -recipient that the request is being made to) using the `spec.signerName` field. -Note that `spec.signerName` is a required key after API version `certificates.k8s.io/v1`. -In Kubernetes v1.22 and later, clients may optionally set the `spec.expirationSeconds` -field to request a particular lifetime for the issued certificate. The minimum valid -value for this field is `600`, i.e. ten minutes. - -Once created, a CertificateSigningRequest must be approved before it can be signed. -Depending on the signer selected, a CertificateSigningRequest may be automatically approved -by a {{< glossary_tooltip text="controller" term_id="controller" >}}. -Otherwise, a CertificateSigningRequest must be manually approved either via the REST API (or client-go) -or by running `kubectl certificate approve`. Likewise, a CertificateSigningRequest may also be denied, -which tells the configured signer that it must not sign the request. - -For certificates that have been approved, the next step is signing. The relevant signing controller -first validates that the signing conditions are met and then creates a certificate. -The signing controller then updates the CertificateSigningRequest, storing the new certificate into -the `status.certificate` field of the existing CertificateSigningRequest object. The -`status.certificate` field is either empty or contains a X.509 certificate, encoded in PEM format. -The CertificateSigningRequest `status.certificate` field is empty until the signer does this. - -Once the `status.certificate` field has been populated, the request has been completed and clients can now -fetch the signed certificate PEM data from the CertificateSigningRequest resource. -The signers can instead deny certificate signing if the approval conditions are not met. - -In order to reduce the number of old CertificateSigningRequest resources left in a cluster, a garbage collection -controller runs periodically. The garbage collection removes CertificateSigningRequests that have not changed -state for some duration: - -* Approved requests: automatically deleted after 1 hour -* Denied requests: automatically deleted after 1 hour -* Failed requests: automatically deleted after 1 hour -* Pending requests: automatically deleted after 24 hours -* All requests: automatically deleted after the issued certificate has expired - -### Certificate signing authorization {#authorization} - -To allow creating a CertificateSigningRequest and retrieving any CertificateSigningRequest: - -* Verbs: `create`, `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests` - -For example: - -{{% code_sample file="access/certificate-signing-request/clusterrole-create.yaml" %}} - -To allow approving a CertificateSigningRequest: - -* Verbs: `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests` -* Verbs: `update`, group: `certificates.k8s.io`, resource: `certificatesigningrequests/approval` -* Verbs: `approve`, group: `certificates.k8s.io`, resource: `signers`, resourceName: `/` or `/*` - -For example: - -{{% code_sample file="access/certificate-signing-request/clusterrole-approve.yaml" %}} - -To allow signing a CertificateSigningRequest: - -* Verbs: `get`, `list`, `watch`, group: `certificates.k8s.io`, resource: `certificatesigningrequests` -* Verbs: `update`, group: `certificates.k8s.io`, resource: `certificatesigningrequests/status` -* Verbs: `sign`, group: `certificates.k8s.io`, resource: `signers`, resourceName: `/` or `/*` - -{{% code_sample file="access/certificate-signing-request/clusterrole-sign.yaml" %}} - - -## Signers - -Signers abstractly represent the entity or entities that might sign, or have -signed, a security certificate. - -Any signer that is made available for outside a particular cluster should provide information -about how the signer works, so that consumers can understand what that means for CertifcateSigningRequests -and (if enabled) [ClusterTrustBundles](#cluster-trust-bundles). -This includes: - -1. **Trust distribution**: how trust anchors (CA certificates or certificate bundles) are distributed. -1. **Permitted subjects**: any restrictions on and behavior when a disallowed subject is requested. -1. **Permitted x509 extensions**: including IP subjectAltNames, DNS subjectAltNames, - Email subjectAltNames, URI subjectAltNames etc, and behavior when a disallowed extension is requested. -1. **Permitted key usages / extended key usages**: any restrictions on and behavior - when usages different than the signer-determined usages are specified in the CSR. -1. **Expiration/certificate lifetime**: whether it is fixed by the signer, configurable by the admin, determined by the CSR `spec.expirationSeconds` field, etc - and the behavior when the signer-determined expiration is different from the CSR `spec.expirationSeconds` field. -1. **CA bit allowed/disallowed**: and behavior if a CSR contains a request a for a CA certificate when the signer does not permit it. - -Commonly, the `status.certificate` field of a CertificateSigningRequest contains a -single PEM-encoded X.509 certificate once the CSR is approved and the certificate is issued. -Some signers store multiple certificates into the `status.certificate` field. In -that case, the documentation for the signer should specify the meaning of -additional certificates; for example, this might be the certificate plus -intermediates to be presented during TLS handshakes. - -If you want to make the _trust anchor_ (root certificate) available, this should be done -separately from a CertificateSigningRequest and its `status.certificate` field. For example, -you could use a ClusterTrustBundle. - -The PKCS#10 signing request format does not have a standard mechanism to specify a -certificate expiration or lifetime. The expiration or lifetime therefore has to be set -through the `spec.expirationSeconds` field of the CSR object. The built-in signers -use the `ClusterSigningDuration` configuration option, which defaults to 1 year, -(the `--cluster-signing-duration` command-line flag of the kube-controller-manager) -as the default when no `spec.expirationSeconds` is specified. When `spec.expirationSeconds` -is specified, the minimum of `spec.expirationSeconds` and `ClusterSigningDuration` is -used. - -{{< note >}} -The `spec.expirationSeconds` field was added in Kubernetes v1.22. Earlier versions of Kubernetes do not honor this field. -Kubernetes API servers prior to v1.22 will silently drop this field when the object is created. -{{< /note >}} - -### Kubernetes signers - -Kubernetes provides built-in signers that each have a well-known `signerName`: - -1. `kubernetes.io/kube-apiserver-client`: signs certificates that will be honored as client certificates by the API server. - Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}. - 1. Trust distribution: signed certificates must be honored as client certificates by the API server. The CA bundle is not distributed by any other means. - 1. Permitted subjects - no subject restrictions, but approvers and signers may choose not to approve or sign. - Certain subjects like cluster-admin level users or groups vary between distributions and installations, - but deserve additional scrutiny before approval and signing. - The `CertificateSubjectRestriction` admission plugin is enabled by default to restrict `system:masters`, - but it is often not the only cluster-admin subject in a cluster. - 1. Permitted x509 extensions - honors subjectAltName and key usage extensions and discards other extensions. - 1. Permitted key usages - must include `["client auth"]`. Must not include key usages beyond `["digital signature", "key encipherment", "client auth"]`. - 1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum - of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object. - 1. CA bit allowed/disallowed - not allowed. - -1. `kubernetes.io/kube-apiserver-client-kubelet`: signs client certificates that will be honored as client certificates by the - API server. - May be auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}. - 1. Trust distribution: signed certificates must be honored as client certificates by the API server. The CA bundle - is not distributed by any other means. - 1. Permitted subjects - organizations are exactly `["system:nodes"]`, common name is "`system:node:${NODE_NAME}`". - 1. Permitted x509 extensions - honors key usage extensions, forbids subjectAltName extensions and drops other extensions. - 1. Permitted key usages - `["key encipherment", "digital signature", "client auth"]` or `["digital signature", "client auth"]`. - 1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum - of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object. - 1. CA bit allowed/disallowed - not allowed. - -1. `kubernetes.io/kubelet-serving`: signs serving certificates that are honored as a valid kubelet serving certificate - by the API server, but has no other guarantees. - Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}. - 1. Trust distribution: signed certificates must be honored by the API server as valid to terminate connections to a kubelet. - The CA bundle is not distributed by any other means. - 1. Permitted subjects - organizations are exactly `["system:nodes"]`, common name is "`system:node:${NODE_NAME}`". - 1. Permitted x509 extensions - honors key usage and DNSName/IPAddress subjectAltName extensions, forbids EmailAddress and - URI subjectAltName extensions, drops other extensions. At least one DNS or IP subjectAltName must be present. - 1. Permitted key usages - `["key encipherment", "digital signature", "server auth"]` or `["digital signature", "server auth"]`. - 1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum - of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object. - 1. CA bit allowed/disallowed - not allowed. - -1. `kubernetes.io/legacy-unknown`: has no guarantees for trust at all. Some third-party distributions of Kubernetes - may honor client certificates signed by it. The stable CertificateSigningRequest API (version `certificates.k8s.io/v1` and later) - does not allow to set the `signerName` as `kubernetes.io/legacy-unknown`. - Never auto-approved by {{< glossary_tooltip term_id="kube-controller-manager" >}}. - 1. Trust distribution: None. There is no standard trust or distribution for this signer in a Kubernetes cluster. - 1. Permitted subjects - any - 1. Permitted x509 extensions - honors subjectAltName and key usage extensions and discards other extensions. - 1. Permitted key usages - any - 1. Expiration/certificate lifetime - for the kube-controller-manager implementation of this signer, set to the minimum - of the `--cluster-signing-duration` option or, if specified, the `spec.expirationSeconds` field of the CSR object. - 1. CA bit allowed/disallowed - not allowed. - -The kube-controller-manager implements [control plane signing](#signer-control-plane) for each of the built in -signers. Failures for all of these are only reported in kube-controller-manager logs. - -{{< note >}} -The `spec.expirationSeconds` field was added in Kubernetes v1.22. Earlier versions of Kubernetes do not honor this field. -Kubernetes API servers prior to v1.22 will silently drop this field when the object is created. -{{< /note >}} - -Distribution of trust happens out of band for these signers. Any trust outside of those described above are strictly -coincidental. For instance, some distributions may honor `kubernetes.io/legacy-unknown` as client certificates for the -kube-apiserver, but this is not a standard. -None of these usages are related to ServiceAccount token secrets `.data[ca.crt]` in any way. That CA bundle is only -guaranteed to verify a connection to the API server using the default service (`kubernetes.default.svc`). - -### Custom signers - -You can also introduce your own custom signer, which should have a similar prefixed name but using your -own domain name. For example, if you represent an open source project that uses the domain `open-fictional.example` -then you might use `issuer.open-fictional.example/service-mesh` as a signer name. - -A custom signer uses the Kubernetes API to issue a certificate. See [API-based signers](#signer-api). - -## Signing - -### Control plane signer {#signer-control-plane} - -The Kubernetes control plane implements each of the -[Kubernetes signers](/docs/reference/access-authn-authz/certificate-signing-requests/#kubernetes-signers), -as part of the kube-controller-manager. - -{{< note >}} -Prior to Kubernetes v1.18, the kube-controller-manager would sign any CSRs that -were marked as approved. -{{< /note >}} - -{{< note >}} -The `spec.expirationSeconds` field was added in Kubernetes v1.22. -Earlier versions of Kubernetes do not honor this field. -Kubernetes API servers prior to v1.22 will silently drop this field when the object is created. -{{< /note >}} - -### API-based signers {#signer-api} - -Users of the REST API can sign CSRs by submitting an UPDATE request to the `status` -subresource of the CSR to be signed. - -As part of this request, the `status.certificate` field should be set to contain the -signed certificate. This field contains one or more PEM-encoded certificates. - -All PEM blocks must have the "CERTIFICATE" label, contain no headers, -and the encoded data must be a BER-encoded ASN.1 Certificate structure -as described in [section 4 of RFC5280](https://tools.ietf.org/html/rfc5280#section-4.1). - -Example certificate content: - -``` ------BEGIN CERTIFICATE----- -MIIDgjCCAmqgAwIBAgIUC1N1EJ4Qnsd322BhDPRwmg3b/oAwDQYJKoZIhvcNAQEL -BQAwXDELMAkGA1UEBhMCeHgxCjAIBgNVBAgMAXgxCjAIBgNVBAcMAXgxCjAIBgNV -BAoMAXgxCjAIBgNVBAsMAXgxCzAJBgNVBAMMAmNhMRAwDgYJKoZIhvcNAQkBFgF4 -MB4XDTIwMDcwNjIyMDcwMFoXDTI1MDcwNTIyMDcwMFowNzEVMBMGA1UEChMMc3lz -dGVtOm5vZGVzMR4wHAYDVQQDExVzeXN0ZW06bm9kZToxMjcuMC4wLjEwggEiMA0G -CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDne5X2eQ1JcLZkKvhzCR4Hxl9+ZmU3 -+e1zfOywLdoQxrPi+o4hVsUH3q0y52BMa7u1yehHDRSaq9u62cmi5ekgXhXHzGmm -kmW5n0itRECv3SFsSm2DSghRKf0mm6iTYHWDHzUXKdm9lPPWoSOxoR5oqOsm3JEh -Q7Et13wrvTJqBMJo1GTwQuF+HYOku0NF/DLqbZIcpI08yQKyrBgYz2uO51/oNp8a -sTCsV4OUfyHhx2BBLUo4g4SptHFySTBwlpRWBnSjZPOhmN74JcpTLB4J5f4iEeA7 -2QytZfADckG4wVkhH3C2EJUmRtFIBVirwDn39GXkSGlnvnMgF3uLZ6zNAgMBAAGj -YTBfMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDAjAMBgNVHRMB -Af8EAjAAMB0GA1UdDgQWBBTREl2hW54lkQBDeVCcd2f2VSlB1DALBgNVHREEBDAC -ggAwDQYJKoZIhvcNAQELBQADggEBABpZjuIKTq8pCaX8dMEGPWtAykgLsTcD2jYr -L0/TCrqmuaaliUa42jQTt2OVsVP/L8ofFunj/KjpQU0bvKJPLMRKtmxbhXuQCQi1 -qCRkp8o93mHvEz3mTUN+D1cfQ2fpsBENLnpS0F4G/JyY2Vrh19/X8+mImMEK5eOy -o0BMby7byUj98WmcUvNCiXbC6F45QTmkwEhMqWns0JZQY+/XeDhEcg+lJvz9Eyo2 -aGgPsye1o3DpyXnyfJWAWMhOz7cikS5X2adesbgI86PhEHBXPIJ1v13ZdfCExmdd -M1fLPhLyR54fGaY+7/X8P9AZzPefAkwizeXwe9ii6/a08vWoiE4= ------END CERTIFICATE----- -``` - -Non-PEM content may appear before or after the CERTIFICATE PEM blocks and is unvalidated, -to allow for explanatory text as described in [section 5.2 of RFC7468](https://www.rfc-editor.org/rfc/rfc7468#section-5.2). - -When encoded in JSON or YAML, this field is base-64 encoded. -A CertificateSigningRequest containing the example certificate above would look like this: - -```yaml -apiVersion: certificates.k8s.io/v1 -kind: CertificateSigningRequest -... -status: - certificate: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JS..." -``` - -## Approval or rejection {#approval-rejection} - -Before a [signer](#signers) issues a certificate based on a CertificateSigningRequest, -the signer typically checks that the issuance for that CSR has been _approved_. - -### Control plane automated approval {#approval-rejection-control-plane} - -The kube-controller-manager ships with a built-in approver for certificates with -a signerName of `kubernetes.io/kube-apiserver-client-kubelet` that delegates various -permissions on CSRs for node credentials to authorization. -The kube-controller-manager POSTs SubjectAccessReview resources to the API server -in order to check authorization for certificate approval. - -### Approval or rejection using `kubectl` {#approval-rejection-kubectl} - -A Kubernetes administrator (with appropriate permissions) can manually approve -(or deny) CertificateSigningRequests by using the `kubectl certificate -approve` and `kubectl certificate deny` commands. - -To approve a CSR with kubectl: - -```shell -kubectl certificate approve -``` - -Likewise, to deny a CSR: - -```shell -kubectl certificate deny -``` - -### Approval or rejection using the Kubernetes API {#approval-rejection-api-client} - -Users of the REST API can approve CSRs by submitting an UPDATE request to the `approval` -subresource of the CSR to be approved. For example, you could write an -{{< glossary_tooltip term_id="operator-pattern" text="operator" >}} that watches for a particular -kind of CSR and then sends an UPDATE to approve them. - -When you make an approval or rejection request, set either the `Approved` or `Denied` -status condition based on the state you determine: - -For `Approved` CSRs: - -```yaml -apiVersion: certificates.k8s.io/v1 -kind: CertificateSigningRequest -... -status: - conditions: - - lastUpdateTime: "2020-02-08T11:37:35Z" - lastTransitionTime: "2020-02-08T11:37:35Z" - message: Approved by my custom approver controller - reason: ApprovedByMyPolicy # You can set this to any string - type: Approved -``` - -For `Denied` CSRs: - -```yaml -apiVersion: certificates.k8s.io/v1 -kind: CertificateSigningRequest -... -status: - conditions: - - lastUpdateTime: "2020-02-08T11:37:35Z" - lastTransitionTime: "2020-02-08T11:37:35Z" - message: Denied by my custom approver controller - reason: DeniedByMyPolicy # You can set this to any string - type: Denied -``` - -It's usual to set `status.conditions.reason` to a machine-friendly reason -code using TitleCase; this is a convention but you can set it to anything -you like. If you want to add a note for human consumption, use the -`status.conditions.message` field. - - -## Cluster trust bundles {#cluster-trust-bundles} - -{{< feature-state feature_gate_name="ClusterTrustBundle" >}} - -{{< note >}} -In Kubernetes {{< skew currentVersion >}}, you must enable the `ClusterTrustBundle` -[feature gate](/docs/reference/command-line-tools-reference/feature-gates/) -_and_ the `certificates.k8s.io/v1alpha1` -{{< glossary_tooltip text="API group" term_id="api-group" >}} in order to use -this API. -{{< /note >}} - -A ClusterTrustBundles is a cluster-scoped object for distributing X.509 trust -anchors (root certificates) to workloads within the cluster. They're designed -to work well with the [signer](#signers) concept from CertificateSigningRequests. - -ClusterTrustBundles can be used in two modes: -[signer-linked](#ctb-signer-linked) and [signer-unlinked](#ctb-signer-unlinked). - -### Common properties and validation {#ctb-common} - -All ClusterTrustBundle objects have strong validation on the contents of their -`trustBundle` field. That field must contain one or more X.509 certificates, -DER-serialized, each wrapped in a PEM `CERTIFICATE` block. The certificates -must parse as valid X.509 certificates. - -Esoteric PEM features like inter-block data and intra-block headers are either -rejected during object validation, or can be ignored by consumers of the object. -Additionally, consumers are allowed to reorder the certificates in -the bundle with their own arbitrary but stable ordering. - -ClusterTrustBundle objects should be considered world-readable within the -cluster. If your cluster uses [RBAC](/docs/reference/access-authn-authz/rbac/) -authorization, all ServiceAccounts have a default grant that allows them to -**get**, **list**, and **watch** all ClusterTrustBundle objects. -If you use your own authorization mechanism and you have enabled -ClusterTrustBundles in your cluster, you should set up an equivalent rule to -make these objects public within the cluster, so that they work as intended. - -If you do not have permission to list cluster trust bundles by default in your -cluster, you can impersonate a service account you have access to in order to -see available ClusterTrustBundles: - -```bash -kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default' -``` - -### Signer-linked ClusterTrustBundles {#ctb-signer-linked} - -Signer-linked ClusterTrustBundles are associated with a _signer name_, like this: - -```yaml -apiVersion: certificates.k8s.io/v1alpha1 -kind: ClusterTrustBundle -metadata: - name: example.com:mysigner:foo -spec: - signerName: example.com/mysigner - trustBundle: "<... PEM data ...>" -``` - -These ClusterTrustBundles are intended to be maintained by a signer-specific -controller in the cluster, so they have several security features: - -* To create or update a signer-linked ClusterTrustBundle, you must be permitted - to **attest** on the signer (custom authorization verb `attest`, - API group `certificates.k8s.io`; resource path `signers`). You can configure - authorization for the specific resource name - `/` or match a pattern such as - `/*`. -* Signer-linked ClusterTrustBundles **must** be named with a prefix derived from - their `spec.signerName` field. Slashes (`/`) are replaced with colons (`:`), - and a final colon is appended. This is followed by an arbitrary name. For - example, the signer `example.com/mysigner` can be linked to a - ClusterTrustBundle `example.com:mysigner:`. - -Signer-linked ClusterTrustBundles will typically be consumed in workloads -by a combination of a -[field selector](/docs/concepts/overview/working-with-objects/field-selectors/) on the signer name, and a separate -[label selector](/docs/concepts/overview/working-with-objects/labels/#label-selectors). - -### Signer-unlinked ClusterTrustBundles {#ctb-signer-unlinked} - -Signer-unlinked ClusterTrustBundles have an empty `spec.signerName` field, like this: - -```yaml -apiVersion: certificates.k8s.io/v1alpha1 -kind: ClusterTrustBundle -metadata: - name: foo -spec: - # no signerName specified, so the field is blank - trustBundle: "<... PEM data ...>" -``` - -They are primarily intended for cluster configuration use cases. -Each signer-unlinked ClusterTrustBundle is an independent object, in contrast to the -customary grouping behavior of signer-linked ClusterTrustBundles. - -Signer-unlinked ClusterTrustBundles have no `attest` verb requirement. -Instead, you control access to them directly using the usual mechanisms, -such as role-based access control. - -To distinguish them from signer-linked ClusterTrustBundles, the names of -signer-unlinked ClusterTrustBundles **must not** contain a colon (`:`). - -### Accessing ClusterTrustBundles from pods {#ctb-projection} - -{{< feature-state feature_gate_name="ClusterTrustBundleProjection" >}} - -The contents of ClusterTrustBundles can be injected into the container filesystem, similar to ConfigMaps and Secrets. -See the [clusterTrustBundle projected volume source](/docs/concepts/storage/projected-volumes#clustertrustbundle) for more details. - -## {{% heading "whatsnext" %}} - -* Read [Manage TLS Certificates in a Cluster](/docs/tasks/tls/managing-tls-in-a-cluster/) -* Read [Issue a Certificate for a Kubernetes API Client Using A CertificateSigningRequest](/docs/tasks/tls/certificate-issue-client-csr/) -* View the source code for the kube-controller-manager built in - [signer](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/signer/cfssl_signer.go) -* View the source code for the kube-controller-manager built in - [approver](https://github.com/kubernetes/kubernetes/blob/32ec6c212ec9415f604ffc1f4c1f29b782968ff1/pkg/controller/certificates/approver/sarapprove.go) -* For details of X.509 itself, refer to [RFC 5280](https://tools.ietf.org/html/rfc5280#section-3.1) section 3.1 -* For information on the syntax of PKCS#10 certificate signing requests, refer to [RFC 2986](https://tools.ietf.org/html/rfc2986) -* Read about the ClusterTrustBundle API: - * {{< page-api-reference kind="ClusterTrustBundle" >}} +## Requesting a client certificate. diff --git a/content/en/docs/reference/access-authn-authz/node.md b/content/en/docs/reference/access-authn-authz/node.md index dd144d7fa1403..3397c5a90722f 100644 --- a/content/en/docs/reference/access-authn-authz/node.md +++ b/content/en/docs/reference/access-authn-authz/node.md @@ -29,10 +29,7 @@ Read operations: {{< feature-state feature_gate_name="AuthorizeNodeWithSelectors" >}} -When the `AuthorizeNodeWithSelectors` feature is enabled -(along with the pre-requisite `AuthorizeWithSelectors` feature), -kubelets are only allowed to read their own Node objects, -and are only allowed to read pods bound to their node. +Kubelets are limited to reading their own Node objects, and only reading pods bound to their node. Write operations: diff --git a/content/en/docs/reference/access-authn-authz/webhook.md b/content/en/docs/reference/access-authn-authz/webhook.md index cb91ac34c60a3..e24d525b9f2bf 100644 --- a/content/en/docs/reference/access-authn-authz/webhook.md +++ b/content/en/docs/reference/access-authn-authz/webhook.md @@ -166,8 +166,9 @@ Access to non-resource paths are sent as: {{< feature-state feature_gate_name="AuthorizeWithSelectors" >}} -With the `AuthorizeWithSelectors` feature enabled, field and label selectors in the request -are passed to the authorization webhook. The webhook can make authorization decisions +When calling out to an authorization webhook, Kubernetes passes +label and field selectors in the request to the authorization webhook. +The authorization webhook can make authorization decisions informed by the scoped field and label selectors, if it wishes. The [SubjectAccessReview API documentation](/docs/reference/kubernetes-api/authorization-resources/subject-access-review-v1/) diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/AnonymousAuthConfigurableEndpoints.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/AnonymousAuthConfigurableEndpoints.md index f731f04625a33..08ca121519305 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/AnonymousAuthConfigurableEndpoints.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/AnonymousAuthConfigurableEndpoints.md @@ -13,6 +13,11 @@ stages: - stage: beta defaultValue: true fromVersion: "1.32" + toVersion: "1.33" + - stage: stable + defaultValue: true + fromVersion: "1.34" + locked: true --- Enable [configurable endpoints for anonymous auth](/docs/reference/access-authn-authz/authentication/#anonymous-authenticator-configuration) for the API server. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeNodeWithSelectors.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeNodeWithSelectors.md index db45f7ec27dbd..d4911cdd59b24 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeNodeWithSelectors.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeNodeWithSelectors.md @@ -13,6 +13,9 @@ stages: - stage: beta defaultValue: true fromVersion: "1.32" + toVersion: "1.33" + - stage: stable + defaultValue: true + fromVersion: "1.34" --- Make the [Node authorizer](/docs/reference/access-authn-authz/node/) use fine-grained selector authorization. -Requires `AuthorizeWithSelectors` to be enabled. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeWithSelectors.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeWithSelectors.md index d53ff8d6305ea..12ef546e869fd 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeWithSelectors.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/AuthorizeWithSelectors.md @@ -13,6 +13,10 @@ stages: - stage: beta defaultValue: true fromVersion: "1.32" + toVersion: "1.33" + - stage: stable + defaultValue: true + fromVersion: "1.34" --- Allows authorization to use field and label selectors. Enables `fieldSelector` and `labelSelector` fields in the [SubjectAccessReview API](/docs/reference/kubernetes-api/authorization-resources/subject-access-review-v1/), diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/OrderedNamespaceDeletion.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/OrderedNamespaceDeletion.md index 7ed57df3161ff..3593e45348aaf 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/OrderedNamespaceDeletion.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/OrderedNamespaceDeletion.md @@ -13,5 +13,9 @@ stages: - stage: beta defaultValue: true fromVersion: "1.33" + toVersion: "1.33" + - stage: stable + defaultValue: true + fromVersion: "1.34" --- -Enables the pods being deleted before the rest of resources while namespace deletion. +While deleting namespace, the pods resources is going to be deleted before the rest of resources. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/PodCertificateRequest.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/PodCertificateRequest.md new file mode 100644 index 0000000000000..74b7a83473797 --- /dev/null +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/PodCertificateRequest.md @@ -0,0 +1,15 @@ +--- +title: PodCertificateRequest +content_type: feature_gate +_build: + list: never + render: false + +stages: + - stage: alpha + defaultValue: false + fromVersion: "1.34" + toVersion: "1.37" +--- +Enable PodCertificateRequest objects and podCertificate projected volume +sources. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/PodDisruptionConditions.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/PodDisruptionConditions.md index bd2fc3a40ae2d..99e0e56efaaa0 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/PodDisruptionConditions.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/PodDisruptionConditions.md @@ -17,5 +17,8 @@ stages: - stage: stable defaultValue: true fromVersion: "1.31" + toVersion: "1.33" + +removed: true --- -Enables support for appending a dedicated pod condition indicating that the pod is being deleted due to a disruption. +Enabled support for appending a dedicated pod condition indicating that the pod is being deleted due to a disruption. diff --git a/content/en/docs/reference/command-line-tools-reference/feature-gates/StructuredAuthenticationConfiguration.md b/content/en/docs/reference/command-line-tools-reference/feature-gates/StructuredAuthenticationConfiguration.md index 11c4f11ab09b5..976e21ad85b5a 100644 --- a/content/en/docs/reference/command-line-tools-reference/feature-gates/StructuredAuthenticationConfiguration.md +++ b/content/en/docs/reference/command-line-tools-reference/feature-gates/StructuredAuthenticationConfiguration.md @@ -6,13 +6,17 @@ _build: render: false stages: - - stage: alpha + - stage: alpha defaultValue: false fromVersion: "1.29" toVersion: "1.29" - stage: beta defaultValue: true - fromVersion: "1.30" + fromVersion: "1.30" + toVersion: "1.33" + - stage: stable + defaultValue: true + fromVersion: "1.34" --- -Enable [structured authentication configuration](/docs/reference/access-authn-authz/authentication/#configuring-the-api-server) +Enable [structured authentication configuration](/docs/reference/access-authn-authz/authentication/#configuring-the-api-server) for the API server. diff --git a/content/en/docs/reference/kubectl/_index.md b/content/en/docs/reference/kubectl/_index.md index 1396981bfd06d..4924dde922d41 100644 --- a/content/en/docs/reference/kubectl/_index.md +++ b/content/en/docs/reference/kubectl/_index.md @@ -270,9 +270,10 @@ Output format | Description `-o json` | Output a JSON formatted API object. `-o jsonpath=