Trust Domain Operations
This guide covers the complete lifecycle of managing SPIFFE trust
domains with spirlctl, including creation, monitoring, deployments,
key management, and deletion.
Understanding Trust Domainsβ
A SPIFFE trust domain is the primary segment and "root of trust" for workload identities in your infrastructure. All workload identities (SVIDs) issued within a trust domain are signed by the trust domain's signing keys.
A real-world analogy is that an SVID is like a passport, and a trust domain is the country that issues it.
A trust domain could represent an organization, environment or department running their own independent infrastructure.
Managed vs. Self-Hosted Trust Domainsβ
Defakto supports two types of trust domains:
- Self-Hosted Trust Domains - You run the Defakto Server infrastructure in your own environment while using Defakto's cloud for configuration and management.
- Managed Trust Domains (default) - Defakto hosts and manages the trust domain server, as well as managing configuration.
Trust Bundlesβ
Every trust domain publishes what's known as "trust bundles", which is what applications use to verify SVIDs issued under that trust domain. There are two types of trust bundles
- An X.509 trust bundle containing at least one X.509 root certificate, for verifying X.509-SVIDs
- A JSON Web Key Set (JWKS) trust bundle containing at least one public key, for verifying JWT-SVDs.
For both self-hosted and Defakto-managed trust domains, trust bundles are published at public endpoints.
Trust bundles can be retrieved using the following URL patterns:
- X.509 trust bundle:
https://fed.spirl.org/<ORG_ID>/<TRUST_DOMAIN_ID>/bundle(also known as the SPIFFE bundle) - JWKS trust bundle:
https://fed.spirl.org/<ORG_ID>/<TRUST_DOMAIN_ID>/jwks
In addition, each trust domain has a public OpenID Connect discovery endpoint:
https://fed.spirl.org/<ORG_ID>/<TRUST_DOMAIN_ID>/.well-known/openid-configuration
Specific values can be found using the spirlctrl trust-domain info command:
$ spirlctl trust-domain info example.com
ID td-m36ckrte4e
Name: example.com
Status: available
Self-Managed: false
SPIRL Agent Endpoint: td-m36ckrte4e.agent.spirl.com:443
SPIFFE Bundle Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/bundle
JWT Issuer: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e
JWKS Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/jwks
OIDC Discovery Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/.well-known/openid-configuration
Created At: 2025-10-23 18:30:41.013 +0000 UTC
Last Updated At: 2025-10-23 18:31:36.906 +0000 UTC
Creating Trust Domainsβ
Create a Managed Trust Domainβ
The simplest way to create a trust domain:
spirlctl trust-domain create example.com
This provisions:
- A SPIFFE trust domain with the name
example.com - Defakto-hosted certificate authority infrastructure
- SPIFFE bundle endpoints
- Management APIs for workload registration
You can also add a description:
spirlctl trust-domain create prod.example.com \
--description "Production trust domain for customer workloads"
Create a Self-Hosted Trust Domainβ
For organizations that will run Defakto infrastructure on-premises:
spirlctl trust-domain create on-prem.example.com --self-hosted
Self-hosted trust domains require you to deploy and manage the Defakto Server components. After creating a self-hosted trust domain, you'll need to create deployments and keys to configure your servers.
Trust Domain Namingβ
Trust domain names must follow the SPIFFE specification. Typically, they follow DNS naming conventions:
example.com- Organization-wide trust domainprod.example.com- Production environmentdev.example.com- Development environmentteam-platform.example.com- Team-specific trust domain
Note that trust domain names are self-registered and need not correspond to public domain names.
Choose trust domain names carefully. They become part of all SPIFFE IDs and cannot be easily changed later.
Listing Trust Domainsβ
View all trust domains in your organization:
spirlctl trust-domain list
Example output:
Name ID State SPIRL-hosted Clusters Federations
example.com td-m36ckrte4e available true 0/0 0/0
prod.example.com td-888butgzdc available true 0/5 0/0
on-prem.example.com td-wyw33falzt available false 2/5 0/0
3 trust domains found.
Viewing Trust Domain Informationβ
Get detailed information about a specific trust domain:
spirlctl trust-domain info example.com
Example output:
ID td-m36ckrte4e
Name: example.com
Status: available
Self-Managed: false
SPIRL Agent Endpoint: td-m36ckrte4e.agent.spirl.com:443
SPIFFE Bundle Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/bundle
JWT Issuer: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e
JWKS Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/jwks
OIDC Discovery Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/.well-known/openid-configuration
View with Deployment Informationβ
To include deployment details:
spirlctl trust-domain info on-prem.example.com --show-deployments
This shows additional information about self-hosted deployments:
ID td-m36ckrte4e
Name: on-prem.example.com
Status: available
Self-Managed: false
SPIRL Agent Endpoint: td-m36ckrte4e.agent.spirl.com:443
SPIFFE Bundle Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/bundle
JWT Issuer: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e
JWKS Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/jwks
OIDC Discovery Endpoint: https://fed.spirl.org/t-o9cpowm5yo/td-m36ckrte4e/.well-known/openid-configuration
Created At: 2025-10-23 18:30:41.013 +0000 UTC
Last Updated At: 2025-10-23 18:31:36.906 +0000 UTC
Getting Trust Domain Infoβ ΉDeployments: 1
Name ID Configuration State Last Configured
us-west-2 tdd-5x4bd5nv5l Up to date 2025-10-23 18:55:25.212 +0000 UTC
Trust Domain Deploymentsβ
Deployments are used with self-hosted trust domains to manage multiple server instances across different locations, or different availability zones within a location.
Unlike self-hosted trust domains, Defakto-hosted trust domains are limited to a single deployment, which is present after trust domain creation.
Understanding Deploymentsβ
Each deployment represents a logical grouping of Defakto Server instances that share:
- Certificate authority keys
- Configuration
Common deployment patterns:
- One deployment per region (e.g.,
us-west-2,eu-central-1) - One deployment per availability zone (e.g.,
us-west-2a,us-west-2b) - One deployment per data center (e.g.,
dc1,dc2)
Create a Deploymentβ
spirlctl trust-domain deployment create us-west-2 \
--trust-domain on-prem.example.com
Example output:
Trust domain deployment 'us-west-2' created successfully.
Deployment name: us-west-2
Deployment ID: tdd-t6rml5zfg5
Trust domain name: on-prem.example.com
Trust domain ID: td-ro6d997e6n
Key id: tdk-pfze0ki4lt
Private Key:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIAJpHMcC1rJhcI0fPHTRoFGlazXYI0K/aIL3UkVe0p0w
-----END PRIVATE KEY-----
Save these credentials immediately! The private key is only shown once and cannot be retrieved later. You will need the deployment id, key ID and private key for later. Save the private key in a secure place.
The key returned here is used by the trust domain server to
authenticate to Defakto's control plane. It's usually passed in via
the server Helm
chart.
Using the example above, these are the relevant changes to values.yaml:
trustDomainDeployment:
id: tdd-t6rml5zfg5
trustDomainName: "us-west-2"
trustDomainID: "td-ro6d997e6n"
name: "us-west-2"
controlPlane:
auth:
key:
id: " tdk-pfze0ki4lt"
pem: |
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIAJpHMcC1rJhcI0fPHTRoFGlazXYI0K/aIL3UkVe0p0w
-----END PRIVATE KEY-----
List Deploymentsβ
List all deployments across all trust domains:
spirlctl trust-domain deployment list
Filter by specific trust domain:
spirlctl trust-domain deployment list --trust-domain on-prem.example.com
Example output:
Name ID Configuration State Last Configured
eu-central-1 tdd-nhlm0wbake Unknown 0001-01-01 00:00:00 +0000 UTC
us-west-2 tdd-t6rml5zfg5 Unknown 0001-01-01 00:00:00 +0000 UTC
2 trust domain deployments found.
Delete a Deploymentβ
Remove a deployment when it's no longer needed:
spirlctl trust-domain deployment delete us-west-2 \
--trust-domain on-prem.example.com
If the deployment has active keys, you'll receive an error. Use --force to override:
spirlctl trust-domain deployment delete us-west-2 \
--trust-domain on-prem.example.com \
--force
Force-deleting a deployment with active keys will immediately break Defakto server instances using those keys. Ensure servers are stopped or migrated before force-deleting.
Deployment Key Managementβ
Signing Keys vs. Deployment Keysβ
Signing keys are the keys used by a trust domain server to sign X.509-SVIDs and JWT-SVIDs. Both self-hosted and Defakto-hosted trust domain servers manage signing keys themselves, and rotate them automatically.
Deployment keys are used by self-hosted Defakto servers to authenticate with the Defakto control plane. These must be managed and deployed by the customer.
Deployment Key Lifecycleβ
- A new trust domain deployment is created.
- The deployment id, key id, and private key are provided to the server via the Helm chart.
- To start a trust domain deployment key rotation, first create a new key.
- Apply the new values to the server and restart.
- Verify that the server is using the new deployment key.
- Disable the old deployment key and verify that the server is running correctly.
- Delete the disabled deployment key.
Note that multiple deployment keys can be enabled at the same time.
Create Deployment Keyβ
Create a key for a specific deployment:
spirlctl trust-domain deployment key create \
--trust-domain on-prem.example.com \
--deployment-name us-west-2
The output includes critical credentials that must be saved securely:
Trust domain key 'tdk-w7rtaev6t3' created successfully
Deployment name: us-west-2
Trust domain name: on-prem.example.com
Key id: tdk-w7rtaev6t3
Private Key:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIAENQHTzsEO1vLui6cakRFLfdPEdqYukhiUVK2VFggGA
-----END PRIVATE KEY-----
Save these credentials immediately! The private key is only shown once and cannot be retrieved later. You will need the deployment id, key ID and private key for later. Save the private key in a secure place.
Output Formatβ
For programmatic processing, use JSON output:
spirlctl trust-domain deployment key create \
--trust-domain on-prem.example.com \
--deployment-name us-west-2 \
--output json
Example output:
{
"key_id": "tdk-af5aq6i39s",
"deployment_name": "us-west-2",
"trust_domain_name": "on-prem.example.com",
"private_key_pem": "-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIAw8mlSiSx6JKy3naCBomTtkJuwlNVjFjGpQ3sK7quEc\n-----END PRIVATE KEY-----\n"
}
List Deployment Keysβ
View all keys across all trust domains:
spirlctl trust-domain deployment key list
Example output:
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-af5aq6i39s
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEATTlFJyD9tRrlgr/CcczwDa0c3lIAHG6UJ6CDFVlsV9w=
-----END PUBLIC KEY-----
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-pfze0ki4lt
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAZGLJoJxSdBaBAJ7THGCehR6Q0UzBNPyD4Ks7akl76Xo=
-----END PUBLIC KEY-----
Trust Domain Name: dev.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-w7rtaev6t3
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAJxowKSzAbuaQTqs0jJqOH7VN9H6DpuJYONzVANEqH9g=
-----END PUBLIC KEY-----
3 trust domain keys found.
Filter by trust domain:β
spirlctl trust-domain deployment key list \
--trust-domain on-prem.example.com
Example output:
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-af5aq6i39s
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEATTlFJyD9tRrlgr/CcczwDa0c3lIAHG6UJ6CDFVlsV9w=
-----END PUBLIC KEY-----
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-pfze0ki4lt
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAZGLJoJxSdBaBAJ7THGCehR6Q0UzBNPyD4Ks7akl76Xo=
-----END PUBLIC KEY-----
2 trust domain keys found.
Filter by specific deployment:β
spirlctl trust-domain deployment key list \
--trust-domain on-prem.example.com \
--deployment-name us-west-2
Example output:
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-af5aq6i39s
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEATTlFJyD9tRrlgr/CcczwDa0c3lIAHG6UJ6CDFVlsV9w=
-----END PUBLIC KEY-----
Trust Domain Name: on-prem.example.com
Trust Domain ID: td-ro6d997e6n
Deployment Name: us-west-2
Trust Domain Key ID: tdk-pfze0ki4lt
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAZGLJoJxSdBaBAJ7THGCehR6Q0UzBNPyD4Ks7akl76Xo=
-----END PUBLIC KEY-----
2 trust domain keys found.
Disable Deployment Keyβ
Deactivate a key in advance of deletion:
spirlctl trust-domain deployment key disable tdk-pfze0ki4lt \
--trust-domain on-prem.example.com \
--deployment-name us-west-2
Example output:
Trust domain key tdk-pfze0ki4lt disabled.
Important! Existing credentials issued to the trust domain deployment are still valid for up to 24 hours.
A trust domain server using a deactivated key will eventually fail to connect to the Defakto control plane. After that, the server will be unable to pull new federation links, cluster configurations, or other updates.
Enable Deployment Keyβ
Activate a previously disabled deployment key:
spirlctl trust-domain deployment key enable tdk-pfze0ki4lt \
--trust-domain on-prem.example.com
Example output:
Trust domain key tdk-pfze0ki4lt enabled.
Delete Deployment Keyβ
To permanently remove a key:
spirlctl trust-domain deployment key delete tdk-pfze0ki4lt \
--trust-domain on-prem.example.com \
Example output:
Trust domain key tdk-pfze0ki4lt deleted.
Deleted deployment keys cannot be recovered. Only delete keys that are:
- Disabled
- No longer used by any server
Deleting Trust Domainsβ
Deleted trust domains cannot be recovered.
Prerequisitesβ
Before deleting a trust domain, you must:
- Remove all clusters from the trust domain
- Delete all deployments (for self-hosted trust domains)
Delete a Trust Domainβ
spirlctl trust-domain delete example.com
If clusters still exist, you'll receive an error listing the clusters that must be removed first:
Trust domain has clusters or node-groups in use; delete all clusters and node-groups (including ci-cd) before trying again.
Complete Cleanup Processβ
- List all clusters in the trust domain:
$ spirlctl cluster list --trust-domain example.com
Name ID Configs Created
production c-1qa5rgostn 1 2025-10-24T20:36:43Z
1 cluster found.
- Disable and delete each cluster:
$ spirlctl cluster disable production --trust-domain example.com
Cluster config cv-fqsqu187c5 disabled.
Cluster disabled.
$ spirlctl cluster delete production --trust-domain example.com
Deleted cluster version cv-fqsqu187c5.
Cluster deleted.
- For self-hosted servers: Disable and delete all deployments:
$ spirlctl trust-domain deployment key list --trust-domain example.com
Trust Domain Name: example.com
Trust Domain ID: td-cq5v0smscu
Deployment Name: eu-central-1
Trust Domain Key ID: tdk-psvgm5468a
State: active
Public Key:
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAm/8NNDSQ9wR622/rtKp37vkl7k/UDZNN9gi2U2x4aLw=
-----END PUBLIC KEY-----
1 trust domain key found.
$ spirlctl trust-domain deployment key disable tdk-psvgm5468a --trust-domain example.com
Trust domain key tdk-psvgm5468a disabled.
Important! Existing credentials issued to the trust domain deployment are still valid for up to 24 hours.
$ spirlctl trust-domain deployment delete eu-central-1 --trust-domain example.com
Trust domain deployment eu-central-1 deleted
- Delete the trust domain
$ spirlctl trust-domain delete example.com
Deleting SPIFFE Trust Domain β
Trust domain 'example.com' deleted successfully.
Common Workflowsβ
Multi-Region Self-Hosted Setupβ
Set up a self-hosted trust domain across multiple regions:
# Create the self-hosted trust domain
spirlctl trust-domain create global.example.com --self-hosted \
--description "Global self-hosted trust domain"
# Create deployments for each region
for region in us-west-2 us-east-1 eu-central-1; do
spirlctl trust-domain deployment create $region \
--trust-domain global.example.com
# Create a key for each deployment
spirlctl trust-domain deployment key create \
--trust-domain global.example.com \
--deployment-name $region \
--output json > ${region}-key.json
done
# List all deployments
spirlctl trust-domain deployment list --trust-domain global.example.com
Environment Separationβ
Create separate trust domains for different environments:
# Create trust domains for each environment
for env in dev staging prod; do
spirlctl trust-domain create ${env}.example.com --self-hosted \
--description "${env} environment trust domain"
done
# Verify creation
spirlctl trust-domain list
Troubleshootingβ
Cannot Create Trust Domainβ
Domain name already exists:
- Trust domain names must be unique across your organization
- Check existing trust domains with
spirlctl trust-domain list - Consider using subdomains (e.g.,
prod.example.cominstead ofexample.com)
Permission denied:
- Verify you're logged in:
spirlctl whoami - Check your IAM permissions for trust domain creation
- Contact your organization administrator
Cannot Delete Trust Domainβ
Deleted trust domains cannot be recovered.
Error: Trust domain has active clusters:
# List clusters
spirlctl cluster list --trust-domain example.com
# Remove each cluster first
spirlctl cluster disable cluster-name --trust-domain example.com
spirlctl cluster delete cluster-name --trust-domain example.com
# Then delete trust domain
spirlctl trust-domain delete example.com
Error: Trust domain has active deployments:
# List deployments
spirlctl trust-domain deployment list --trust-domain example.com
# Remove each deployment
spirlctl trust-domain deployment key list --trust-domain example.com
# In this example we only have one active deployment key
spirlctl trust-domain deployment key disable tdk-wt24ygybin --trust-domain example.com
spirlctl trust-domain deployment delete us-west-2 --trust-domain example.com
# Then delete trust domain
spirlctl trust-domain delete example.com
Lost Private Keyβ
If you lose a trust domain key's private key:
- Create a new key for the deployment
- Deploy the new key to your servers
- Disable the lost key to prevent its use
- Delete the lost key after certificates expire
There is no way to retrieve a lost private key. Always store keys securely.
Key Rotation Caused Outageβ
If key rotation causes issues:
- Re-enable the old key immediately:
spirlctl trust-domain deployment key enable tdk-old-key \
--trust-domain example.com \ - Verify servers can access both keys
- Wait for services to recover
- Investigate the issue before attempting rotation again
Best Practicesβ
Trust Domain Designβ
- Use DNS-based naming - Follow DNS naming conventions for clarity
- Separate environments - Use different trust domains for dev, staging, prod
- Plan for federation - Consider federation requirements when naming
- Document ownership - Add descriptions to track ownership and purpose
Deployment Key Managementβ
- Store keys securely - Use a vault or secrets management system (e.g. AWS Secrets Manager)
- Rotate regularly - Rotate keys every 90-180 days
- Automate rotation - Manual rotation will lead to errors and outages.
- Test rotation - Practice key rotation in non-production first
Deployment Strategyβ
- One deployment per region - Start simple with one deployment per region
- Scale to availability zones - Add AZ-specific deployments for higher availability
- Plan for disaster recovery - Maintain deployments across multiple regions
- Monitor deployment health - Track key status and server connectivity
- Automate provisioning - Use infrastructure-as-code (e.g. Terraform) for deployment management
Operationsβ
- Regular audits - Periodically review trust domains, deployments, and keys
- Clean up unused resources - Remove old deployments and keys
- Document procedures - Maintain runbooks for key rotation and incident response
- Test disaster recovery - Regularly test trust domain recovery procedures
Command Referenceβ
Trust Domain Commandsβ
| Command | Description |
|---|---|
trust-domain create | Create a new trust domain |
trust-domain list | List all trust domains |
trust-domain info | Get detailed trust domain information |
trust-domain delete | Delete a trust domain |
Deployment Commandsβ
| Command | Description |
|---|---|
trust-domain deployment create | Create a new deployment |
trust-domain deployment list | List all deployments |
trust-domain deployment delete | Delete a deployment |
Deployment Key Commandsβ
| Command | Description |
|---|---|
trust-domain deployment key create | Create a new deployment key |
trust-domain deployment key list | List all deployment keys |
trust-domain deployment key enable | Enable a deployment key |
trust-domain deployment key disable | Disable a deployment key |
trust-domain deployment key delete | Delete a deployment key |