Skip to content

feat: Hardware attestation — HSM/enclave key confinement and attestation document binding #61

@rsharath

Description

@rsharath

Summary

ZeroID's data model includes a public_key_pem field and a required_attestation field in the identity record, but neither hardware key confinement nor attestation document verification are implemented. The proposed NHI IAM standard mandates that high-trust agent identities bind their private key to hardware (HSM, TEE/enclave, or cloud KMS) and present a verifiable attestation document as part of the token request, with the attestation bound into the issued token.

Problem

Without hardware attestation:

  1. Software key extraction risk: Agent private keys stored in process memory or on disk can be exfiltrated without detection. Compromised keys allow silent impersonation indefinitely (until manual discovery and revocation).
  2. No proof of execution environment: ZeroID can verify what an agent claims to be, but not where it is running. A cloned agent image, a compromised container, or a supply-chain-attacked model weight has the same identity as a legitimate agent.
  3. Compliance gap: The proposed standard (and EU AI Act Article 9 accountability requirements) require evidence that agent credentials are bound to hardware roots of trust for high-assurance workloads. The required_attestation field exists but is not enforced.
  4. DPoP / channel binding gap: The forward-secret channel work (see companion issue) is significantly weakened if the key used for DPoP proofs is software-extractable — hardware confinement closes the loop.

Proposed Implementation

1. Attestation document types

Support three hardware attestation mechanisms:

Mechanism Attestation Document Format Target Environment
AWS Nitro Enclaves Nitro attestation document (CBOR/COSE) EC2 / ECS / Lambda
Azure Confidential VMs / Managed HSM Azure Attestation JWT (MAA) Azure
GCP Confidential VMs / Cloud HSM Google Cloud Attestation JWT GCP
TPM 2.0 TPM quote + PCR values (JSON envelope) On-prem / bare metal
YubiHSM / SoftHSM (dev) PKCS#11 key handle proof Development / CI

2. Token request extension

Extend the token request (all grant types that can carry a public key) to accept an attestation document:

{
  "grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",
  "assertion": "<signed JWT>",
  "public_key": "<base64url DER or PEM>",
  "attestation": {
    "type": "aws_nitro",
    "document": "<base64url-encoded Nitro attestation document>",
    "nonce": "<challenge nonce from ZeroID>"
  }
}

Challenge-response flow:

  1. Agent calls GET /oauth2/attestation/challenge → receives a nonce (short-lived, 30s TTL).
  2. Agent generates or retrieves its hardware-confined key pair.
  3. Agent requests attestation from the hardware (nonce is bound into the attestation document).
  4. Agent submits token request with attestation document.
  5. ZeroID verifies: attestation document signature → nonce matches → public key in attestation matches supplied public key → key was generated inside the hardware boundary.

3. Attestation verification

Implement attestation verifiers for each supported mechanism:

  • Nitro: verify COSE_Sign1 against AWS root CA; extract public_key from user data field; verify nonce.
  • Azure MAA: verify JWT against MAA JWKS; extract x-ms-runtime.keys; verify nonce in nonce claim.
  • GCP: verify JWT against Google Trust Services; extract key from submods.container.gce.instance_id context + key material.
  • TPM: verify quote signature against endorsement key certificate chain; verify PCR values against expected golden values (configurable per identity).

4. Token binding

When attestation is verified at issuance, add the following claims to the issued JWT:

{
  "cnf": {
    "x25519": "<base64url public key>"
  },
  "hwattest": {
    "type": "aws_nitro",
    "pcr0": "<base64url PCR0 value>",
    "enclave_image_digest": "sha256:...",
    "verified_at": 1744000000
  }
}
  • hwattest.type indicates the attestation mechanism.
  • hwattest.pcr0 (or equivalent) binds the token to a specific firmware/software measurement.
  • Enforcement points can reject tokens where hwattest.enclave_image_digest does not match an approved image list.

5. Trust level gating

Extend the trust level policy:

Trust Level Key Requirement
standard Software key (current behavior)
elevated Software key + DPoP proof
high Hardware-confined key + verified attestation document

Identity records with required_attestation: true (already in the data model) MUST present a valid attestation document; token issuance fails otherwise.

6. Approved image / PCR policy

Add a new AttestationPolicy resource type that administrators can configure per project:

attestation_policy:
  type: aws_nitro
  approved_pcr0:
    - "sha384:abc123..."
  approved_enclave_image_digests:
    - "sha256:def456..."
  max_token_ttl: 3600

ZeroID enforces this policy at issuance: tokens are only issued if the attestation document's measurements match an approved entry.

7. CAE signal: attestation drift

Add a attestation_drift CAE signal type emitted when:

  • A re-attestation check (on token renewal) shows a different PCR value than the original token's hwattest claims.
  • The approved image list is updated and an outstanding token's hwattest.enclave_image_digest is no longer in the approved list.

8. SDK changes

  • HighflameClient(attestation=NitroAttestation()) / equivalent for each SDK language
  • SDK handles challenge-response, attestation generation, and key material retrieval transparently
  • PKCS#11 interface for YubiHSM/SoftHSM in development environments

Acceptance Criteria

  • Attestation challenge endpoint implemented (GET /oauth2/attestation/challenge)
  • Nitro attestation verifier implemented and tested against real Nitro documents
  • At least one additional verifier (Azure MAA or GCP) implemented
  • TPM 2.0 verifier implemented (for on-prem support)
  • Token request extended to accept attestation document
  • hwattest claim added to issued tokens when attestation is verified
  • required_attestation: true enforced at issuance
  • AttestationPolicy resource type defined, stored, and enforced
  • attestation_drift CAE signal implemented
  • SDK: transparent attestation in Python, JS, Rust; PKCS#11 for dev
  • GET /oauth2/introspect response includes hwattest claims
  • Documentation: new Hardware Attestation guide in ZeroID; Credential Policies updated with attestation policy examples
  • Security review of attestation verification code paths (this is security-critical)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions