AWS KMS Key Wrapping
Use AWS KMS to protect the Trust Domain Server's signing key material at rest. Signing keys are encrypted before being written to the Kubernetes CRD, with a KMS-held key acting as the Key Encrypting Key (KEK). The KEK never leaves AWS infrastructure.
This page covers key wrapping — encrypting stored signing keys at rest. If you want signing keys to live entirely inside KMS so they never enter server memory, see AWS KMS Key Manager instead.
How it works
The Trust Domain Server uses envelope encryption. When it needs to persist a signing key, the server generates a fresh AES-256-GCM data-encryption key (DEK) and uses it to encrypt the signing key locally. It then asks AWS KMS to wrap the DEK with the KEK. The CRD stores the encrypted signing key alongside the wrapped DEK. To decrypt, the server asks AWS KMS to unwrap the DEK, then decrypts the signing key locally with it.
The KMS key acts as the KEK and never leaves AWS infrastructure. AWS KMS only ever sees DEKs, and the signing-key plaintext never leaves the Trust Domain Server.
How to Deploy
Step 1 — Create a symmetric KMS key
Create a symmetric encryption key in your preferred region. The key must be a symmetric encrypt/decrypt key (the default type):
aws kms create-key \
--description "Defakto signing key wrapping" \
--key-usage ENCRYPT_DECRYPT \
--key-spec SYMMETRIC_DEFAULT \
--region us-east-1
Note the key ARN from the output — you will need it in Step 3.
Step 2 — Set up IAM permissions
The Trust Domain Server needs an IAM role with kms:Encrypt and kms:Decrypt on the wrapping key:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"kms:Encrypt",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/example-key-id"
}
]
}
For EKS deployments, use IRSA (IAM Roles for Service Accounts) to associate this role with the Trust Domain Server's Kubernetes service account.
Step 3 — Update Helm values
Set the KMS key ARN in your spirl-system Helm values:
aws:
kmsKeyARN: "arn:aws:kms:us-east-1:123456789012:key/example-key-id"
Optionally, if you use a custom KMS endpoint (for example, a VPC endpoint):
aws:
kmsKeyARN: "arn:aws:kms:us-east-1:123456789012:key/example-key-id"
endpoints:
kms: "https://kms.us-east-1.amazonaws.com"
Apply the Helm release:
helm upgrade spirl-system spirl/spirl-system \
-f values.yaml \
--namespace <namespace>
Step 4 — Verify
On successful startup, the Trust Domain Server logs the following:
Key wrapping via KMS keyARN=arn:aws:kms:us-east-1:123456789012:key/example-key-id
If the server cannot reach KMS or the IAM role lacks permissions, startup fails with a clear error.
Helm Values Reference
| Value | Required | Default | Description |
|---|---|---|---|
aws.kmsKeyARN | Yes | "" | ARN of the AWS KMS symmetric encryption key used to wrap signing keys. |
aws.endpoints.kms | No | AWS SDK default | Custom KMS endpoint URL. Useful for VPC endpoints or non-standard regions. |
When to configure
Key wrapping must be configured before the Trust Domain Server stores any signing key material. Configure it as part of your initial Helm installation.
Switching key wrapping providers on an existing deployment is not supported. Data the Trust Domain Server has already persisted is encrypted with the current KEK, and the server cannot decrypt it with a different provider's key. If you need to change providers, contact Defakto support for guidance on your specific deployment.
Security Considerations
- Symmetric key required. The wrapping key must be a symmetric encrypt/decrypt key (
SYMMETRIC_DEFAULT). Asymmetric keys are not supported. - KMS availability. The Trust Domain Server calls KMS at startup and during key rotation. In steady state, SVID issuance does not require KMS calls; the decrypted signing key is held in server memory.
- IAM scoping. Restrict the IAM policy to the specific key ARN rather than using
Resource: "*". - CloudTrail audit.
kms:Encryptandkms:Decryptcalls appear in CloudTrail with the caller identity and key ID.