Skip to content

Conversation

@ahmedtd
Copy link
Contributor

@ahmedtd ahmedtd commented Jul 2, 2025

This change breaks apart the "Certificates" reference documentation (which currently lives under the API Access, Authentication, and Authorization section of the reference documentation. It becomes:

  • reference/access-authn-authz/certificate-signing-requests.md (The current doc) --- narrowly focused on using client certificates to authenticate to the Kubernetes API.
  • concepts/security/certificates.md: (most of the content from the current doc) A deep-dive on signers, CertificateSigningRequests, PodCertificateRequests, ClusterTrustBundles, and the built-in signers.
  • tasks/extend-kubernetes/custom-signer.md: A guide to creating your own custom signer.

@k8s-ci-robot k8s-ci-robot added this to the 1.34 milestone Jul 2, 2025
@netlify
Copy link

netlify bot commented Jul 2, 2025

👷 Deploy Preview for kubernetes-io-vnext-staging processing.

Name Link
🔨 Latest commit 3400449
🔍 Latest deploy log https://app.netlify.com/projects/kubernetes-io-vnext-staging/deploys/689420bd5c2e770008d93c55

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Jul 2, 2025
@k8s-ci-robot k8s-ci-robot requested a review from enj July 2, 2025 22:06
@k8s-ci-robot k8s-ci-robot added the language/en Issues or PRs related to English language label Jul 2, 2025
@k8s-ci-robot k8s-ci-robot requested a review from mikedanese July 2, 2025 22:06
@k8s-ci-robot k8s-ci-robot added the size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. label Jul 2, 2025
@netlify
Copy link

netlify bot commented Jul 2, 2025

Pull request preview available for checking

Built without sensitive environment variables

Name Link
🔨 Latest commit 8ba16fc
🔍 Latest deploy log https://app.netlify.com/projects/kubernetes-io-main-staging/deploys/6894337d4c3d40000900723f
😎 Deploy Preview https://deploy-preview-51487--kubernetes-io-main-staging.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@lmktfy
Copy link
Member

lmktfy commented Jul 3, 2025

/retitle [WIP] Document Pod certificate requests

@k8s-ci-robot k8s-ci-robot changed the title Pod Certificate Requests: Placeholder update [WIP] Document Pod certificate requests Jul 3, 2025
@k8s-ci-robot k8s-ci-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 3, 2025
@k8s-ci-robot k8s-ci-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels Jul 22, 2025
@k8s-ci-robot k8s-ci-robot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Jul 23, 2025
@ahmedtd ahmedtd force-pushed the podcertificates branch 2 times, most recently from 79b343d to 6ce8b70 Compare July 23, 2025 05:01
@ahmedtd ahmedtd changed the title [WIP] Document Pod certificate requests [WIP] Document PodCertificateRequests, PodCertificate Projections, and Reorganize Certificate/Signer Documentation Jul 23, 2025
@ahmedtd
Copy link
Contributor Author

ahmedtd commented Jul 23, 2025

/assign stlaz

@ahmedtd ahmedtd force-pushed the podcertificates branch 2 times, most recently from f35bb0a to 8363ffd Compare July 23, 2025 07:38
@michellengnx
Copy link
Contributor

Hello @ahmedtd 👋 please take a look at Documenting for a release - PR Ready for Review to get your PR ready for review before Tuesday July 29th 2025 18:00 PST. Thank you!

@ahmedtd ahmedtd force-pushed the podcertificates branch 3 times, most recently from 4268852 to 9a8f68c Compare July 24, 2025 20:02
@ahmedtd ahmedtd changed the title [WIP] Document PodCertificateRequests, PodCertificate Projections, and Reorganize Certificate/Signer Documentation Document PodCertificateRequests, PodCertificate Projections, and Reorganize Certificate/Signer Documentation Jul 24, 2025
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign nate-double-u for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@enj enj added this to SIG Auth Aug 7, 2025
@enj enj moved this to Needs Triage in SIG Auth Aug 7, 2025
@windsonsea
Copy link
Member

/remove-language es hi id ja pt ru uk zh
/remove-area localization web-development

@k8s-ci-robot k8s-ci-robot removed language/es Issues or PRs related to Spanish language language/hi Issues or PRs related to Hindi language language/id Issues or PRs related to Indonesian language language/ja Issues or PRs related to Japanese language language/pt Issues or PRs related to Portuguese language language/ru Issues or PRs related to Russian language language/uk Issues or PRs related to Ukrainian language language/zh Issues or PRs related to Chinese language area/localization General issues or PRs related to localization area/web-development Issues or PRs related to the kubernetes.io's infrastructure, design, or build processes labels Aug 8, 2025
@lmktfy
Copy link
Member

lmktfy commented Aug 9, 2025

/label refactor

@k8s-ci-robot k8s-ci-robot added the refactor Indicates a PR with large refactoring changes e.g. removes files or moves content label Aug 9, 2025
override_link_text: "CSR v1"
- apiVersion: "certificates.k8s.io/v1beta1"
kind: "ClusterTrustBundle"
- apiVersion: "certificates.k8s.io/v1alpha1"
Copy link
Member

Choose a reason for hiding this comment

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

For a PR targeting main we can't accept this yet.
Docs are continuously deployed and main should document the latest (released) minor release, ie v1.33 at time of writing.

/hold
We can't merge this yet but we can do everything bar that.

client certificate.

<!-- body -->

Copy link
Member

Choose a reason for hiding this comment

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

Here, let's do a stub that mentions two common certificate tasks, and signposts people to go there:

A stub is all it needs.

this 15-minute limit.


## ClusterTrustBundles {#cluster-trust-bundles}
Copy link
Member

Choose a reason for hiding this comment

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

I would introduce these before the other API kinds in this document. They are in away useful without any of the other concepts: you can use them to distribute trust anchors to your workloads. That's a common need.


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
Copy link
Member

Choose a reason for hiding this comment

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

nit: could hyperlink to the RFC that standardized certs in PEM format.

kubectl get clustertrustbundles --as='system:serviceaccount:mynamespace:default'
```

### Signer-linked ClusterTrustBundles {#ctb-signer-linked}
Copy link
Member

Choose a reason for hiding this comment

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

We can have this even if we haven't fully explained what signers are. An initial outline and are hyperlink could be enough.

See the [clusterTrustBundle projected volume source](/docs/concepts/storage/projected-volumes#clustertrustbundle) for more details.


## Kubernetes built-in signers {#kubernetes-signers}
Copy link
Member

@lmktfy lmktfy Aug 9, 2025

Choose a reason for hiding this comment

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

I would have this list of signers in the reference section of the docs.

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.
Copy link
Member

Choose a reason for hiding this comment

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

nit: optionally, make "selectors" a glossary_tooltip

@k8s-ci-robot k8s-ci-robot added the do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. label Aug 9, 2025
Copy link
Member

@micahhausler micahhausler left a comment

Choose a reason for hiding this comment

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

I think the biggest thing missing in the projected volume docs is details on private key generation. Users who are regulated or just care about PKI will want to know what process is generating it, where its located, and any options on key size/algo/if you can use hardware generation/etc

---
reviewers:
- liggitt
- mikedanese
Copy link
Member

Choose a reason for hiding this comment

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

Is this autogenerated based on OWNERS? I'm happy to be a reviewer here instead of Mike

Copy link
Member

Choose a reason for hiding this comment

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

I think it's been copy and pasted. There's no automatic maintenance that I know of.

* 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.
Copy link
Member

Choose a reason for hiding this comment

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

nit:

Suggested change
certificates to inject into a Pod.
certificates to mount into a Pod.

Copy link
Member

Choose a reason for hiding this comment

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

I think inject is better, actually. Today it's only supported using a mount, but in a future minor release we might offer other ways to use the cert and private key (example: your sandbox sees it in a kernel-provided keyring).


{{< feature-state feature_gate_name="ClusterTrustBundleProjection" >}}

The contents of ClusterTrustBundles can be injected into the container filesystem, similar to ConfigMaps and Secrets.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
The contents of ClusterTrustBundles can be injected into the container filesystem, similar to ConfigMaps and Secrets.
The contents of ClusterTrustBundles can be mounted into the container filesystem, similar to ConfigMaps and Secrets.

Comment on lines +33 to +35
* 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.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* 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.
* ClusterTrustBundle: (beta) A list of certificates (typically CA root
certificates) that can be used as a root of trust for verifying a server or
client certificate.

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.
Copy link
Member

Choose a reason for hiding this comment

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

nit: 'installed' typically implies a pod running in the cluster, but a signer just needs to be an API client, and can be hosted externally

Suggested change
signers may also be freely installed into a cluster.
signers may also be used with a cluster.

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
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
that are available in every cluster. It is also possible to install (or build
that are available in every cluster. It is also possible to use (or build


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
Copy link
Member

Choose a reason for hiding this comment

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

nit: My understanding is that you wouldn't have 2 contradictory conditions in the same list, I'd suggest making it "either" or just "These conditions..."

Suggested change
indicated by adding a `Denied` entry to `status.conditions`. Both of these
indicated by adding a `Denied` entry to `status.conditions`. These


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
Copy link
Member

Choose a reason for hiding this comment

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

We might want to specify how to configure this. I can think of very large clusters where this timeout might be an issue

Copy link
Member

Choose a reason for hiding this comment

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

IIRC this currently cannot be configured.


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
Copy link
Member

Choose a reason for hiding this comment

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

😬 Is this a removable RBAC permission?

Copy link
Member

Choose a reason for hiding this comment

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

You can edit the clusterrolebinding and opt-out of its auto-reconcile per https://kubernetes.io/docs/reference/access-authn-authz/rbac/#auto-reconciliation.
Just curious - what's the use case? Are you trying to prevent undesired trust, perhaps?


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.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
installed.
used.

@github-project-automation github-project-automation bot moved this from Needs Triage to Changes Requested in SIG Auth Aug 11, 2025
* 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.
Copy link
Member

Choose a reason for hiding this comment

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

I think inject is better, actually. Today it's only supported using a mount, but in a future minor release we might offer other ways to use the cert and private key (example: your sandbox sees it in a kernel-provided keyring).

{{< 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.
Copy link
Member

Choose a reason for hiding this comment

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

I think that depends on exactly which client library you use, and we can't confidently assume every user has picked the one we were thinking of.

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
Copy link
Member

Choose a reason for hiding this comment

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

Don't hardcode feature maturity, find a way to incorporate {{< feature-state feature_gate_name="NAME_HERE" >}}. This is otherwise hard to find and replace when the feature matures further.

Copy link
Member

@lmktfy lmktfy Aug 14, 2025

Choose a reason for hiding this comment

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

We can go too far with making maintenance low toil. Here's how I'd strike a balance.

  • keep this wording; leave in “(alpha)”
  • just afterwards, add an HTML comment that mentions the feature gate name (which is PodCertificateRequests, plural)
  • edit content/en/docs/reference/command-line-tools-reference/feature-gates/PodCertificateRequests.md with another HTML comment to search for the feature gates in the English docs and tidy up any matches, on graduation

That's enough of a hint to make maintenance easy, but also makes live comfortable for readers. For the K8s docs, we have many many more readers than writers, so we should prefer choices that impose lower costs on readers, provided the effort to do so is reasonable.

HTML comments are an easily-understood way to leave notes for contributors, that don't harm the end user experience. And they work in Markdown.


Bear in mind that my suggestion won't 100% work out, yet, because this PR is a work in progress (either it targets the wrong branch, or it shouldn't mention PodCertificateRequest yet). But you get the idea.

Comment on lines +22 to +26
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).
Copy link
Member

Choose a reason for hiding this comment

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

This paragraph is a little odd. In short it reads as "Kubernetes cert/trust bundle APIs enable credential provisioning by providing APIs for clients of these APIs". Try to rephrase somehow, please.

Comment on lines +78 to +84
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.
Copy link
Member

Choose a reason for hiding this comment

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

Should we leave specific fields docs here to the API reference and only mention what the CSR object is capable of? Alternatively mention that this list is not exhaustive and ref the docs from above for further details.

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.
Copy link
Member

Choose a reason for hiding this comment

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

This should probably mention the "Failed" condition, otherwise the terminal state is not properly defined.

{{< /note >}}

Signer implementations are encouraged to:
* Document whether or not they consider manual approval decisions on
Copy link
Member

Choose a reason for hiding this comment

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

This?

Suggested change
* Document whether or not they consider manual approval decisions on
* Document whether or not they require manual approval decisions on

They would always consider manual approvals, right? Maybe unless they approve and issue in a single step?

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
Copy link
Member

Choose a reason for hiding this comment

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

nit

Suggested change
they get close to expiration. The application just has to make sure that it
they get close to expiration. The application needs to be able to react to these file changes

Comment on lines +9 to +10
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
Copy link
Member

Choose a reason for hiding this comment

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

If this is its own page, the "similar prefixed name" gets confusing as you don't know what it should be similar to.

Suggested change
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
Kubernetes lets you introduce your own custom signer that should have a similar (?)
prefixed name but using your own domain name. For example, if you represent an


#### CertificateSigningRequests {#useful-cluster-roles-csr}

CertificateSigningRequests have three roles &mdash; requesters, approvers, and
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
CertificateSigningRequests have three roles &mdash; requesters, approvers, and
There are three roles to consider with CertificateSigningRequests &mdash; requesters, approvers, and

Comment on lines +28 to +29
Allowing broad read access to CSRs is not a security issue, because the CSRs
only contain public (not private) keys.
Copy link
Member

Choose a reason for hiding this comment

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

It's not on us to decide what is and isn't a security issue. Some might even consider being able to see who requests which certs as a security issue. Think leaking service hostnames in a multi-tenant cluster, for example.

Comment on lines +97 to +110
{{< mermaid >}}
stateDiagram-v2

direction LR

Initial --> Wait
Wait --> Fresh
Wait --> Failed
Wait --> Denied
Fresh --> WaitRefresh
WaitRefresh --> Failed
WaitRefresh --> Denied

{{< /mermaid >}}
Copy link
Member

Choose a reason for hiding this comment

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

do we want to highlight start/final states? Does that work in our docs?

@lmktfy

This comment was marked as off-topic.

@k8s-ci-robot k8s-ci-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Aug 18, 2025
@k8s-ci-robot
Copy link
Contributor

PR needs rebase.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.


{{< feature-state feature_gate_name="ClusterTrustBundle" >}}

This signer does not issue any certificates. It purely serves to distribute the
Copy link
Member

Choose a reason for hiding this comment

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

It still issues certificates but that is all done externally, not automated by the vanilla platform.


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`.
Copy link
Member

Choose a reason for hiding this comment

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

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:
Copy link
Member

Choose a reason for hiding this comment

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

You should mention all the other expectations that we have on the certs signed by this signer. While they are all not necessarily enforced, they could still be considered best practice, which is worth documenting. See what I had in #48492, I believe most of the doc there was agreed on when I was updating the KEP.

kamothi pushed a commit to kamothi/website that referenced this pull request Oct 2, 2025
The "Certificates" page is creaking under its own weight, and is due to
be split up.  This is being pursued in a separate PR:

  kubernetes#51487
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/hold Indicates that a PR should not merge because someone has issued a /hold command. kind/api-change Categorizes issue or PR as related to adding, removing, or otherwise changing an API language/en Issues or PRs related to English language needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. refactor Indicates a PR with large refactoring changes e.g. removes files or moves content sig/auth Categorizes an issue or PR as relevant to SIG Auth. sig/docs Categorizes an issue or PR as relevant to SIG Docs. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

Status: Changes Requested

Development

Successfully merging this pull request may close these issues.