SVID Issuance Policy
The SVIDIssuancePolicy managed configuration section centralizes per-cluster SVID issuance settings and adds an optional list of workload-specific overrides. It is the preferred way to configure:
- SPIFFE ID path templates — the path structure of issued SPIFFE IDs
- X.509-SVID customization — X.509 certificate TTL and Subject
- JWT-SVID customization — JWT-SVID TTL and additional claims
See those pages for field-level documentation and examples.
Why use it?
- Single configuration source: Manage TTLs, subjects, and path templates per cluster from a single managed-config document instead of separate CLI flags.
- Per-workload variations: Issue shorter-lived certificates for specific namespaces, distinct path templates for sensitive workloads, or different subjects for one service account — without writing a separate cluster.
- Live updates: Configuration changes propagate to servers without restart.
Per-Workload Overrides
policyOverrides is an ordered list of conditional policy variations. When a workload's attested attributes match an override's when clause, that override's policy applies in place of the base policy. The first match wins; later overrides and the base policy are skipped for that workload.
section: SVIDIssuancePolicy
schema: v1
spec:
policy:
pathTemplate: "/{{cluster.name}}/default/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"
x509:
ttl: "24h"
policyOverrides:
- when:
kubernetes.pod.namespace: production
policy:
pathTemplate: "/{{cluster.name}}/prod/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"
x509:
ttl: "4h"
- when:
kubernetes.pod.service_account: critical-service
policy:
pathTemplate: "/{{cluster.name}}/critical/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"
x509:
ttl: "1h"
In this example:
- A pod in the
productionnamespace receives a SPIFFE ID under/prod/...with a 4h TTL. - A pod whose service account is
critical-service(in any namespace exceptproduction) receives a SPIFFE ID under/critical/...with a 1h TTL. - Every other pod receives the base policy:
/default/...with a 24h TTL.
When-Clause Match Semantics
Each entry in a when map is one condition. All conditions in a single when clause must match (logical AND).
| Entry | Match Type |
|---|---|
key: value | Exact match — the workload must carry that attribute with that exact string value. |
key: (no value) | Presence match — the workload must carry that attribute with any value. |
Allowed When Keys
when keys are restricted to attributes whose values represent a real authorization boundary — that is, attributes a pod author or process launcher cannot freely pick to claim a more privileged policy.
| Source | Attribute | Set by |
|---|---|---|
| Agent / cluster identity | agent.id | SPIRL agent provisioning |
| Kubernetes admission | kubernetes.pod.namespace | Kubernetes RBAC |
kubernetes.pod.service_account | Kubernetes RBAC | |
| Workload Attestation | jwt.claim.iss | OIDC JWT Issuer |
Attributes that look like identity but are pod-spec- or process-launcher-chosen — including kubernetes.pod.name, kubernetes.pod.node.name, kubernetes.container.name, kubernetes.container.image.name, linux.user.*, and linux.binary.path — are not on the allowlist. Anyone with create pod permission can pick those values, so matching on them adds no security restriction beyond what the underlying RBAC already provides.
Workload-supplied or content-addressed attributes (custom.*, pod annotations, pod labels, JWT claims, kubernetes.container.image.id, linux.binary.sha256) are also excluded: when-clause matching is scoped to platform-set identity, not workload content.
Override Semantics
When an override's when clause matches at issuance time, the override's policy fully replaces the base policy for that workload; there is no merging of fields. Each override must therefore be self-contained. It must declare its own pathTemplate, and any of x509 / jwt it wants to apply. This keeps the model easy to reason about.
| Base declares | Override declares | Effective for matching workload |
|---|---|---|
pathTemplate, x509, jwt | pathTemplate, x509, jwt | All from override |
pathTemplate, x509, jwt | pathTemplate, x509: {ttl: 4h} | Override's pathTemplate and x509. JWT not configured for matching workload. |
pathTemplate, x509, jwt | (no pathTemplate) | Rejected at admission — overrides must carry their own pathTemplate. |
SVID Key Type
The svidKeyType field requires spirl-system v0.42.0 or above.
svidKeyType configures the key algorithm agents use when generating SVID key pairs. Unlike policy and policyOverrides, it is an agent-level setting that applies uniformly to all workloads on the cluster and cannot be varied per workload.
section: SVIDIssuancePolicy
schema: v1
spec:
svidKeyType:
x509: ec-p256
X.509 key type
This setting controls the key pair generated by the agent for each X.509 SVID. It does not affect the root CA signing key algorithm used by the Trust Domain Server.
Supported values:
| Value | Algorithm |
|---|---|
rsa-2048 | RSA 2048-bit (default when not set) |
rsa-3072 | RSA 3072-bit |
rsa-4096 | RSA 4096-bit |
ec-p256 | ECDSA P-256 |
ec-p384 | ECDSA P-384 |
Validation
The control plane rejects configurations that:
- Set neither
policynorpolicyOverrides. - Include an override with an empty
whenclause. - Include an override whose
policydeclares no fields. - Use a
whenkey not on the allow-list above, or awhenkey that isn't a valid attribute name. - Contain two overrides with identical
whenclauses. - Omit
pathTemplateon any override (overrides do not inherit from the base policy). - Use a
jwt.additionalClaimstemplate that is malformed or references reserved JWT claim names (iss,sub,aud,exp,nbf,iat,jti).
Path-template syntax and platform-specific allowed tags are validated the same way they are for SPIFFE ID templates, against both the base policy and each override.