Skip to main content

Restricting Issuance to specific Kubernetes Namespaces

This guide covers restricting SVID issuance to an explicit set of Kubernetes namespaces, keyed on namespace labels.

The approach rests on an assumption about your cluster: Writing a namespace label is a more privileged operation than authoring a pod spec. That is how RBAC is usually arranged, but Kubernetes does not enforce it. Confirm it holds for your cluster before relying on the gate.

Whether to restrict issuance​

Whether every workload in a cluster should hold a credential is a question of deployment.

In an environment with strong authorization ownership and governance, letting every actor in the system receive an SVID is fine. An SVID on its own grants no access, and authorization still happens at the receiving end, so a workload holding an unused identity costs little.

Where that ownership and governance are weaker, gating issuance to specific namespaces or workloads is a reasonable defensive measure, and some teams prefer it regardless. For example, some namespaces are handed to developers as sandboxes, or the cluster is shared with unrelated tenants.

This guide is for the second posture. If you are content to issue to every workload, none of it is needed.

Why namespace labels​

A restriction is only meaningful if the signal it keys on is one the workload cannot set for itself.

Pod labels and annotations are written by whoever authors the pod spec, so they are deliberately not eligible for Issuance Policy. A workload could otherwise forge them to claim a more privileged policy.

Namespace labels are usually different. Writing one requires update, patch or create on the cluster-scoped Namespace object, a permission most clusters grant to platform administrators and to the tooling that provisions namespaces rather than to the developers who deploy into them. Pod Security Admission leans on the same arrangement. Where the arrangement holds, a namespace label is a reasonable place to put platform-owned facts (env, team, data-classification) that a workload cannot claim for itself.

Confirm the privilege separation in your cluster

Kubernetes does not guarantee that labeling a namespace is more privileged than deploying into it. The separation is a convention, and it does not survive every RBAC layout. A per-team namespace-admin role, a GitOps controller reconciling namespace manifests from a repository developers can commit to, or developers holding edit or a wildcard verb at cluster scope all defeat it. Anyone who can label a namespace can grant issuance to it.

Check the subjects you care about before relying on it.

Restrict issuance based on a namespace label​

To issue SVIDs only to workloads in namespaces labeled defakto.security/authorized: true (example), use the "Implicit Deny" feature of the SVIDIssuancePolicy to only allow issuance when the label is set. For example:

section: SVIDIssuancePolicy
schema: v1
spec:
# No top-level `policy:` - workloads in namespaces without the label don't receive SVID
policyOverrides:
- when:
kubernetes.namespace.label."defakto.security/authorized": "true"
policy:
pathTemplate: "/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"

A workload matching the override receives an SVID. When overrides exist, none match, and no base policy is set, issuance is denied.

The defakto.security/authorized label is an example. Any other label name and value can be used.

Appendix​

Rollout order on existing deployments​

Follow the following steps on existing deployments to ensure that issuance is not impacted:

  1. Upgrade the spirl-system chart to at least version 0.46.0 and ensure that agent.namespaceRBAC is set to true, so the agent ClusterRole grants get, list, and watch on namespaces.
  2. Confirm kubernetes.namespace.label.* is actually present in attestation.
  3. Label every namespace that needs credentials, including infrastructure namespaces.
  4. Add policy overwrites to give each labeled namespace an identity.
  5. Only then remove the base policy. This converts the override into a gate.