TPM Endorsement Key
The TPM Endorsement Key (TPM EK) method attests agents running on hosts equipped with a Trusted Platform Module. Unlike certificate-based methods, TPM EK attestation anchors trust directly in the TPM hardware: the agent proves it is running on a specific TPM chip whose Endorsement Key (EK) is trusted by the Trust Domain Server.
The Trust Domain Server issues a hardware-rooted challenge that can only be answered by the exact TPM on the host — no software emulation or key copy can satisfy it.
What Is EK Attestation?
Every TPM ships with an Endorsement Key — a key pair generated during manufacturing and permanently bound to that physical chip. The private part never leaves the TPM. Manufacturers typically issue an EK Certificate tying the key to the chip's identity (manufacturer, model, firmware version), with a certificate chain rooted to the manufacturer's CA (Intel, AMD, Infineon, etc.).
The attestation flow:
- The Trust Domain Server generates a random secret and encrypts it in a credential bound to both the agent's EK and a fresh Attestation Key (AK) the agent just generated. Only the exact TPM that holds both keys can open it.
- The agent passes the encrypted credential to its TPM. The TPM opens it and returns the secret.
- The Trust Domain Server confirms the returned secret matches. A correct response proves the agent is running on the genuine TPM — not a different machine or software emulation.
Attributes available for SVID issuance
The following attributes are produced from the EK certificate. All attributes have the origin tpm_ek.
| Attribute | Description | Availability |
|---|---|---|
tpm_ek.public_hash | SHA-256 fingerprint of the TPM's endorsement public key. Uniquely identifies the chip. | Always |
tpm_ek.serial_number | Serial number of the EK certificate (lowercase hex). | Only when an EK certificate is present |
tpm_ek.manufacturer | Manufacturer identifier from the EK certificate (e.g., id:4E544300 for Nuvoton). | Only when EK certificate includes TPM identity fields |
tpm_ek.model | TPM model name from the EK certificate. | Only when EK certificate includes TPM identity fields |
tpm_ek.version | TPM firmware version from the EK certificate. | Only when EK certificate includes TPM identity fields |
When the agent's TPM has no manufacturer certificate (only a raw public key), only tpm_ek.public_hash is emitted.
Example SPIFFE ID template using TPM identity:
/agents/tpm/{{tpm_ek.manufacturer}}/{{tpm_ek.public_hash}}
Computing the EK Public Hash
To pre-populate an allowedHashes list from a known EK certificate:
openssl x509 -in ek.pem -pubkey -noout \
| openssl pkey -pubin -outform DER \
| sha256sum \
| awk '{print $1}'
How to Deploy
Step 1 — Update cluster configuration
Configure the AgentAttestation policy with either CA-based validation, an explicit hash allow-list, or both. At least one of caCerts or allowedHashes must be present.
CA-based validation (trust any TPM whose EK cert chains to this CA):
section: AgentAttestation
schema: v1
spec:
policies:
- name: tpm_ek_policy
requiredAttestors:
- type: tpm_ek
config:
caCerts: |
-----BEGIN CERTIFICATE-----
MIIBxTCCAW...
-----END CERTIFICATE-----
Hash allow-list (trust only specific, known chips):
section: AgentAttestation
schema: v1
spec:
policies:
- name: tpm_ek_policy
requiredAttestors:
- type: tpm_ek
config:
allowedHashes:
- "a3f1c82bd4e9f07c..."
Combined (TPM passes if it satisfies either check):
section: AgentAttestation
schema: v1
spec:
policies:
- name: tpm_ek_policy
requiredAttestors:
- type: tpm_ek
config:
caCerts: |
-----BEGIN CERTIFICATE-----
MIIBxTCCAW...
-----END CERTIFICATE-----
allowedHashes:
- "a3f1c82bd4e9f07c..."
Apply it using spirlctl:
spirlctl config set cluster --id <cluster-id> attestation-policy.yaml
Or using Terraform:
resource "spirl_cluster_config" "agent_attestation" {
cluster_id = spirl_cluster.my_cluster.id
sections = {
AgentAttestation = <<-YAML
section: AgentAttestation
schema: v1
spec:
policies:
- name: tpm_ek_policy
requiredAttestors:
- type: tpm_ek
config:
caCerts: |
-----BEGIN CERTIFICATE-----
MIIBxTCCAW...
-----END CERTIFICATE-----
YAML
}
}
Once a configuration document passes validation and is stored, the Defakto control plane syncs it to your Trust Domain Servers automatically. No server or agent restart is required.
Server Configuration Reference
| Field | Required | Description |
|---|---|---|
caCerts | Semi-required | PEM-encoded CA certificates. Any TPM whose EK cert chains to one of these CAs is trusted. |
intermediateCerts | No | PEM-encoded intermediate CA certificates used when verifying the EK cert chain. Only used with caCerts. |
allowedHashes | Semi-required | List of hex-encoded SHA-256 fingerprints of trusted EK public keys. |
Step 2 — Configure the Agent
The agent reads the TPM identity directly from the host hardware — no key or certificate files to configure. Grant the agent process access to the TPM resource manager device (typically /dev/tpmrm0).
- Helm Installation
- Linux Installation
agent:
auth:
clusterId: c-xxxxxx
attestors:
- type: tpm_ek
The agent pod requires access to the host TPM device. Add a hostPath volume mount for /dev/tpmrm0 to the agent's pod spec.
cluster-id: c-xxxxxx
disable-kubernetes-attestation: true
agent-attestors:
- type: tpm_ek
Step 3 — Verify
Server logs — look for these in order:
"Login started with multi-attestation support"— confirms the agent offeredprovidedMethods: ["tpm_ek"]"Authorization received and verified"— includesagentAttestationAttributeswith the hardware identity:If the TPM has no manufacturer certificate, only{
"msg": "Authorization received and verified",
"agentAttestationAttributes": [
"tpm_ek:tpm_ek.public_hash=\"a3f1c82bd4e9f07c...\"",
"tpm_ek:tpm_ek.manufacturer=\"id:4E544300\"",
"tpm_ek:tpm_ek.model=\"TPM2.0\"",
"tpm_ek:tpm_ek.version=\"7.64\""
]
}tpm_ek.public_hashappears."Connected to agent"— session is fully established
Agent logs — enable debug logging to see "Sending Login" with attestors: ["tpm_ek"]. At the default log level, "Connected to server" confirms the session is live.
Metrics — confirm proofs are succeeding:
spirl_attestation_signer.proof{attestor_type="tpm_ek",outcome="success"}
spirl_attestation_agent.proof{attestor_type="tpm_ek",outcome="success"}
Alert on outcome="failed" to detect EK validation or challenge failures.
Common errors:
| Error | Likely cause |
|---|---|
no cluster policy authorizes the provided attestors | Agent's tpm_ek method doesn't match any policy in the cluster's AgentAttestation config |
EK did not pass any configured validation check | TPM EK not signed by a configured CA and hash not in allowedHashes |
Authorization failed: challenge response failed validation | TPM couldn't decrypt the credential — verify /dev/tpmrm0 is accessible to the agent process |
Security Considerations
TPM EK attestation provides hardware-rooted proof that the agent is running on a specific physical chip.
What the challenge proves: The encrypted credential can only be opened by a TPM that simultaneously holds both the EK and the matching AK. Copying the EK certificate to another machine is not enough. Software TPM emulators are only accepted if their EK fingerprint appears in allowedHashes or their EK certificate is signed by a CA in caCerts.
Timing attack protection: The Trust Domain Server compares the secret returned by the agent in constant time, preventing information leakage from timing differences.
Session expiry: Each attestation attempt is tracked with a random identifier. If the agent does not complete the challenge within 5 minutes, the session is discarded. Once successfully answered, the session is removed immediately to prevent reuse.
EK Certificate requirements: When CA validation is used, the Trust Domain Server enforces strict requirements aligned with the TCG EK Credential Profile v2.6:
- The certificate must not be a CA certificate.
- Key usage must allow the TPM challenge operation.
- The certificate must include a valid issuer chain and TPM identity fields.
Troubleshooting
| Error in Trust Domain Server logs | Likely cause |
|---|---|
caCerts: could not parse any PEM certificates | caCerts value is not valid PEM |
intermediateCerts: could not parse any PEM certificates | intermediateCerts value is not valid PEM |
attestation policy not found or no matching policy | Managed Config not applied |
EK did not pass any configured validation check | TPM EK is not signed by a configured CA and its fingerprint is not in allowedHashes |
failed to verify EK certificate chain | EK certificate chain verification failed against configured CAs |
challenge response secret does not match | TPM returned the wrong secret — possible hardware mismatch or replay attempt |
unknown session ID | Agent sent a challenge response without a prior proof |