Skip to main content

X.509-SVID Customization

Defakto allows customization of X.509-SVID fields on a per-cluster basis, including TTL, certificate Subject, and Subject Alternative Names (SANs).

X.509-SVID TTL, Subject, and SANs

Set a custom X.509-SVID TTL, certificate Subject, and Subject Alternative Names using the SVIDIssuancePolicy managed configuration:

section: SVIDIssuancePolicy
schema: v1
spec:
policy:
pathTemplate: "/{{cluster.name}}/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"
x509:
ttl: "24h"
subject: "O=Acme Corp,OU=Engineering"
dnsNames:
- "{{kubernetes.pod.service_account}}.{{kubernetes.pod.namespace}}.svc.cluster.local"
ipAddresses:
- "10.0.0.1"

Apply it with spirlctl:

spirlctl config set cluster --id <cluster-id> svid-issuance-policy.yaml

Or with Terraform:

resource "spirl_cluster_config" "example" {
cluster_id = spirl_cluster.my_cluster.id
sections = {
SVIDIssuancePolicy = <<-YAML
section: SVIDIssuancePolicy
schema: v1
spec:
policy:
pathTemplate: "/{{cluster.name}}/ns/{{kubernetes.pod.namespace}}/sa/{{kubernetes.pod.service_account}}"
x509:
ttl: "24h"
subject: "O=Acme Corp,OU=Engineering"
YAML
}
}
FieldTypeNotes
x509.ttldurationX.509-SVID TTL (1h168h).
x509.subjectstringRFC 4514 distinguished name. Becomes the certificate Subject, replacing the default in full.
x509.dnsNameslist of stringsDNS SAN entries. Each entry may reference attributes.
x509.ipAddresseslist of stringsIP SAN entries. Each entry is a literal IP address or an attribute reference that renders to one.

subject, dnsNames, and ipAddresses may reference attributes, in the same {{attribute.name}} form as path templates. Deprecated attribute names, such as provider.aws.*, are rejected in these fields even where a path template still accepts them. Attribute values are escaped for the distinguished-name grammar, so a value containing , or = cannot inject extra Subject components. A dnsNames or ipAddresses list must have at least one entry. Omit the field to leave it unset. An ipAddresses entry that references an attribute is checked at issuance, so a value that does not render to an IP address fails the mint rather than the save. That failure is an issuance error, not a policy denial: The workload sees InvalidArgument, and the Trust Domain Server records status_code = template_error on spirl_server_mint_svid_total with the SVID error category issuance_error. A policy denial is FailedPrecondition and policy_denied, so the two are distinguishable in both telemetry and the workload's error.

A policy that leaves x509.ttl unset falls back to the Trust Domain Server's --x509-svid-ttl flag, and then to the 24h default. A policy that leaves x509.subject unset falls back to --x509-svid-subject, and then to the default SVID subject.

To apply different X.509 settings to specific workloads within the same cluster, use per-workload overrides.

X.509 Customization Templates

Behavior change in spirl-server 0.39.0

From 0.39.0, the legacy X509CustomizationTemplate applies only to clusters with no SVIDIssuancePolicy. On a cluster that has a policy, the policy's x509 fields are the only cluster configuration that customizes the Subject and SANs, including for the fields the policy leaves unset. The gate is the presence of a policy on the cluster, not what any individual policy section sets.

Earlier versions fall back field by field: The legacy template fills in the Subject when the policy sets no x509.subject, and supplies the DNS or IP SAN entries for whichever of x509.dnsNames and x509.ipAddresses the policy leaves unset. So a cluster that leans on a customization template alongside a policy keeps its Subject and SANs today and loses them on upgrade, with no configuration change of its own.

Before upgrading, express the template's Subject and SAN entries as x509.subject, x509.dnsNames, and x509.ipAddresses. Read Migrating a Subject first. A Subject does not carry across as directly as the SAN entries do.

Migrating a Subject

A legacy template's Subject fields are merged into the default SVID subject, so CN={{kubernetes.pod.service_account}} produces a Subject that still carries the default's other components. A policy's x509.subject replaces the whole distinguished name instead. Copying the template across verbatim therefore drops everything the default contributed:

Subject
Legacy template CN={{kubernetes.pod.service_account}}CN=<service account>,O=SPIRL,C=US,<UniqueID>
Policy x509.subject: "CN={{kubernetes.pod.service_account}}"CN=<service account>

Spell out every component the certificate needs. The UniqueID attribute (OID 2.5.4.45) is the one component you cannot restore. UniqueID is derived from the workload's SPIFFE ID, and no template attribute produces it.

Leaving x509.subject unset is the other option. The Subject then comes from the Trust Domain Server's --x509-svid-subject where set, and otherwise from the default SVID subject, which does include the UniqueID.

Template Format

The template can customize Subject fields and Subject Alternative Names (SANs) of type DNS and IP. Here's an example that overrides the Common Name and Organization fields of the certificate Subject:

CN=CustomCN,O=BestCompany Inc.

You can customize any standard Subject field by referencing it directly in the template.

To customize DNS names and IP addresses in the SAN extension, use this notation:

SAN.DNS=dns1.example.com,SAN.DNS=dns2.example.com,SAN.IP=1.1.1.1

You can specify multiple DNS names or IP addresses - all instances will be included in the resulting SVID.

Special Characters

The following characters must be escaped with a backslash when used in field values:

, ; # " + < > = \

Using Attributes

You can use the same attributes in the customization template as those available for path templates. For more information, see the SPIFFE ID templates documentation.

Example with Attributes

You can use attributes in the template similar to how they are used in path templates:

CN=pod-{{kubernetes.pod.name}}

This example sets the Common Name to the pod name.

Legacy configuration

Setting the Template for a New Cluster

You can also control the customization template using the spirlctl CLI. From spirl-server 0.39.0 the template is ignored on clusters that have an SVIDIssuancePolicy.

By default, clusters have an empty X.509 customization template. You can set a template when adding a cluster to the trust domain:

spirlctl cluster add production --trust-domain spirl.example.com \
--platform k8s \
--x509-customization-template "CN=CustomCN"

Setting the Template for an Existing Cluster

To set or update the X.509 customization template for an existing cluster, use the change-x509-template subcommand:

spirlctl cluster config --trust-domain spirl.example.com \
change-x509-template ClusterName "CN=CustomCN"

This creates a new cluster version with the specified customization template.

Removing the Template

To remove the customization template from a cluster, set it to an empty string:

spirlctl cluster config --trust-domain spirl.example.com \
change-x509-template ClusterName ""