Skip to main content

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.

info

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

ValueRequiredDefaultDescription
aws.kmsKeyARNYes""ARN of the AWS KMS symmetric encryption key used to wrap signing keys.
aws.endpoints.kmsNoAWS SDK defaultCustom 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:Encrypt and kms:Decrypt calls appear in CloudTrail with the caller identity and key ID.