Verifier
Push-Model Attestation Endpoints
These endpoints implement the two-phase push-model attestation protocol. Agents use these endpoints to submit attestation capabilities and evidence. Administrators can use the GET endpoints to view attestation results.
For details on authentication requirements, see Authentication.
- POST /v3/agents/{agent_id}/attestations
Phase 1: Submit attestation capabilities and receive a challenge.
The agent sends its supported evidence types, cryptographic algorithms, and attestation key. The verifier selects parameters and returns a challenge nonce for TPM quote generation.
- Parameters:
agent_id (string) – UUID of the agent
Authentication: PoP bearer token (agent-only)
Example request:
{ "data": { "type": "attestation", "attributes": { "evidence_supported": [ { "evidence_class": "certification", "evidence_type": "tpm_quote", "capabilities": { "signature_schemes": ["rsassa"], "hash_algorithms": ["sha256", "sha384", "sha512"], "available_subjects": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], "certification_keys": [ { "key_class": "asymmetric", "key_algorithm": "rsa", "key_size": 2048, "server_identifier": "ak", "allowable_signature_schemes": ["rsassa"], "allowable_hash_algorithms": ["sha256", "sha384", "sha512"], "public": "<base64-encoded AK public key>" } ], "component_version": "2.0", "evidence_version": "1.0" } }, { "evidence_class": "log", "evidence_type": "ima_log", "capabilities": { "entry_count": 1024, "supports_partial_access": true, "appendable": true, "formats": ["text/plain"], "component_version": "1.0", "evidence_version": "1.0" } } ], "system_info": { "boot_time": "2024-01-15T10:30:00Z" } } } }
Example response (201 Created):
{ "data": { "type": "attestation", "id": "0", "attributes": { "stage": "awaiting_evidence", "evidence_requested": [ { "evidence_class": "certification", "evidence_type": "tpm_quote", "chosen_parameters": { "challenge": "<base64-encoded nonce>", "signature_scheme": "rsassa", "hash_algorithm": "sha256", "selected_subjects": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], "certification_key": { "key_class": "asymmetric", "key_algorithm": "rsa", "key_size": 2048, "server_identifier": "ak" } } }, { "evidence_class": "log", "evidence_type": "ima_log", "chosen_parameters": { "starting_offset": 0, "entry_count": 1024, "format": "text/plain" } } ], "system_info": { "boot_time": "2024-01-15T10:30:00Z" }, "capabilities_received_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:35:00.123456Z" }, "links": { "self": "/v3/agents/{agent_id}/attestations/0" } } }
- Request JSON Object:
data.type (string) – Must be
"attestation"data.attributes.evidence_supported (array) – List of evidence types the agent can produce
evidence_supported[].evidence_class (string) –
"certification"or"log"evidence_supported[].evidence_type (string) –
"tpm_quote","ima_log", or"uefi_log"evidence_supported[].capabilities (object) – Capabilities for this evidence type
data.attributes.system_info (object) – System information (e.g. boot time)
- Response JSON Object:
data.id (string) – Attestation index (auto-incremented per agent)
data.attributes.stage (string) –
"awaiting_evidence"data.attributes.evidence_requested (array) – Evidence the verifier wants the agent to provide
evidence_requested[].chosen_parameters.challenge (string) – Base64-encoded challenge nonce for TPM quote
data.attributes.capabilities_received_at (string) – ISO 8601 timestamp
data.attributes.challenges_expire_at (string) – Deadline for evidence submission
data.links.self (string) – URL to this attestation resource
- Status Codes:
201 Created – Attestation created, challenge issued
400 Bad Request – Invalid request body
403 Forbidden – Attestations disabled for this agent (timeout or previous failure)
404 Not Found – Agent not found
409 Conflict – Concurrent attestation creation attempt
422 Unprocessable Entity – Invalid capabilities data
429 Too Many Requests – Rate limited (attestation interval not elapsed). Includes
Retry-Afterheader503 Service Unavailable – Previous attestation still being verified. Includes
Retry-Afterheader
- PATCH /v3/agents/{agent_id}/attestations/latest
Phase 2: Submit attestation evidence for the latest attestation.
The agent sends the TPM quote, PCR values, and event logs generated using the challenge nonce from Phase 1. The verifier accepts the evidence and verifies it asynchronously.
- Parameters:
agent_id (string) – UUID of the agent
Authentication: PoP bearer token (agent-only)
Example request:
{ "data": { "type": "attestation", "attributes": { "evidence_collected": [ { "evidence_class": "certification", "evidence_type": "tpm_quote", "data": { "subject_data": { "0": "<PCR 0 value>", "1": "<PCR 1 value>" }, "message": "<base64-encoded TPM quote>", "signature": "<base64-encoded quote signature>" } }, { "evidence_class": "log", "evidence_type": "ima_log", "data": { "entry_count": 512, "entries": "<base64-encoded or raw IMA log entries>" } } ] } } }
Example response (202 Accepted):
{ "data": { "type": "attestation", "id": "0", "attributes": { "stage": "evaluating_evidence", "evidence": [ { "evidence_class": "certification", "evidence_type": "tpm_quote", "capabilities": {}, "chosen_parameters": {}, "data": { "message": "<base64-encoded TPM quote>", "signature": "<base64-encoded quote signature>", "subject_data": {} } } ], "system_info": { "boot_time": "2024-01-15T10:30:00Z" }, "capabilities_received_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:35:00.123456Z", "evidence_received_at": "2024-01-15T10:31:00.123456Z" }, "links": { "self": "/v3/agents/{agent_id}/attestations/0" } }, "meta": { "seconds_to_next_attestation": 45 } }
- Request JSON Object:
data.type (string) – Must be
"attestation"data.attributes.evidence_collected (array) – List of evidence items
evidence_collected[].evidence_class (string) –
"certification"or"log"evidence_collected[].evidence_type (string) – Type of evidence (must match what was requested)
evidence_collected[].data (object) – Evidence data (format depends on evidence type)
- Response JSON Object:
data.attributes.stage (string) –
"evaluating_evidence"(verification in progress)data.attributes.evidence (array) – Evidence items with capabilities, parameters, and data
data.attributes.evidence_received_at (string) – ISO 8601 timestamp when evidence was received
meta.seconds_to_next_attestation (int) – Suggested wait before starting the next attestation cycle
- Status Codes:
202 Accepted – Evidence accepted, verification in progress
400 Bad Request – Invalid evidence format
403 Forbidden – Evidence already submitted, attestation is not the latest, or challenges expired
404 Not Found – Agent or attestation not found
410 Gone – Attestation no longer exists
503 Service Unavailable – No available worker processes. Includes
Retry-Afterheader
- PATCH /v3/agents/{agent_id}/attestations/{index}
Submit attestation evidence for a specific attestation by index.
Behaves identically to
PATCH /v3/agents/{agent_id}/attestations/latestbut targets a specific attestation index. Evidence can only be submitted for the latest attestation.- Parameters:
agent_id (string) – UUID of the agent
index (integer) – Attestation index
Authentication: PoP bearer token (agent-only)
- Status Codes:
202 Accepted – Evidence accepted
403 Forbidden – Not the latest attestation, evidence already submitted, or challenges expired
404 Not Found – Agent or attestation not found
- GET /v3/agents/{agent_id}/attestations
List all attestations for an agent.
- Parameters:
agent_id (string) – UUID of the agent
Authentication: mTLS (admin) or PoP bearer token (own agent only)
Example response:
{ "data": [ { "type": "attestation", "id": "1", "attributes": { "stage": "verification_complete", "evaluation": "pass", "evidence": [], "system_info": { "boot_time": "2024-01-15T10:30:00Z" }, "capabilities_received_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:35:00.123456Z", "evidence_received_at": "2024-01-15T10:31:00.123456Z", "verification_completed_at": "2024-01-15T10:32:00.123456Z" }, "links": { "self": "/v3/agents/{agent_id}/attestations/1" } }, { "type": "attestation", "id": "0", "attributes": { "stage": "verification_complete", "evaluation": "pass", "evidence": [], "system_info": {}, "capabilities_received_at": "2024-01-15T10:25:00.123456Z", "challenges_expire_at": "2024-01-15T10:30:00.123456Z", "evidence_received_at": "2024-01-15T10:26:00.123456Z", "verification_completed_at": "2024-01-15T10:27:00.123456Z" }, "links": { "self": "/v3/agents/{agent_id}/attestations/0" } } ] }
- Response JSON Object:
data (array) – List of attestation resources
data[].id (string) – Attestation index
data[].attributes.stage (string) –
"awaiting_evidence","evaluating_evidence", or"verification_complete"data[].attributes.evaluation (string) –
"pending","pass", or"fail"data[].attributes.failure_reason (string) –
"broken_evidence_chain"or"policy_violation"(only when evaluation is"fail")
- Status Codes:
200 OK – Success
404 Not Found – Agent not found
- GET /v3/agents/{agent_id}/attestations/latest
Get the latest attestation for an agent.
- Parameters:
agent_id (string) – UUID of the agent
Authentication: mTLS (admin) or PoP bearer token (own agent only)
Example response:
{ "data": { "type": "attestation", "id": "1", "attributes": { "stage": "verification_complete", "evaluation": "pass", "failure_reason": null, "evidence": [ { "evidence_class": "certification", "evidence_type": "tpm_quote", "capabilities": {}, "chosen_parameters": {}, "data": { "message": "<base64-encoded TPM quote>", "signature": "<base64-encoded signature>", "subject_data": {} } } ], "system_info": { "boot_time": "2024-01-15T10:30:00Z" }, "capabilities_received_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:35:00.123456Z", "evidence_received_at": "2024-01-15T10:31:00.123456Z", "verification_completed_at": "2024-01-15T10:32:00.123456Z" }, "links": { "self": "/v3/agents/{agent_id}/attestations/1" } } }
- Response JSON Object:
data.attributes.stage (string) – Current stage of the attestation
data.attributes.evaluation (string) –
"pending","pass", or"fail"data.attributes.failure_reason (string) –
null,"broken_evidence_chain", or"policy_violation"data.attributes.evidence (array) – Evidence items with full data
data.attributes.capabilities_received_at (string) – When capabilities were received
data.attributes.challenges_expire_at (string) – When challenges expire
data.attributes.evidence_received_at (string) – When evidence was received (
nullif still awaiting)data.attributes.verification_completed_at (string) – When verification completed (
nullif still in progress)
- Status Codes:
200 OK – Success
404 Not Found – Agent not found or no attestations exist
- GET /v3/agents/{agent_id}/attestations/{index}
Get a specific attestation by index.
- Parameters:
agent_id (string) – UUID of the agent
index (integer) – Attestation index
Authentication: mTLS (admin) or PoP bearer token (own agent only)
Response format is identical to
GET /v3/agents/{agent_id}/attestations/latest.- Status Codes:
200 OK – Success
404 Not Found – Agent or attestation not found
Session Endpoints
These endpoints manage PoP (Proof of Possession) authentication sessions for push-model agents. Sessions are required before an agent can submit attestations.
- POST /v3/sessions
Create a new authentication session.
The verifier generates a challenge nonce that the agent must sign using its TPM attestation key to prove possession.
Authentication: None (public endpoint)
Example request:
{ "data": { "type": "session", "attributes": { "agent_id": "d432fbb3-d2f1-4a97-9ef7-75bd81c00000", "authentication_supported": [ { "authentication_class": "pop", "authentication_type": "tpm_pop" } ] } } }
Example response (200 OK):
{ "data": { "type": "session", "id": "550e8400-e29b-41d4-a716-446655440000", "attributes": { "agent_id": "d432fbb3-d2f1-4a97-9ef7-75bd81c00000", "authentication_requested": [ { "authentication_class": "pop", "authentication_type": "tpm_pop", "chosen_parameters": { "challenge": "<base64-encoded nonce>" } } ], "created_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:31:00.123456Z" } } }
- Request JSON Object:
data.attributes.agent_id (string) – UUID of the agent requesting a session
data.attributes.authentication_supported (array) – Supported authentication methods
- Response JSON Object:
data.id (string) – Session UUID
data.attributes.challenges_expire_at (string) – Deadline for submitting the PoP response
- Status Codes:
200 OK – Session created
400 Bad Request – Missing or invalid agent_id
429 Too Many Requests – Rate limited. Includes
Retry-Afterheader
- PATCH /v3/sessions/{session_id}
Submit Proof of Possession response to complete authentication.
The agent signs the challenge nonce from the session creation response using
TPM2_Certifyand submits the result. If valid, the verifier issues a bearer token for subsequent API calls.- Parameters:
session_id (string) – UUID of the session
Authentication: None (public endpoint; validates PoP internally)
Example request:
{ "data": { "type": "session", "attributes": { "agent_id": "d432fbb3-d2f1-4a97-9ef7-75bd81c00000", "authentication_provided": [ { "authentication_class": "pop", "authentication_type": "tpm_pop", "data": { "message": "<base64-encoded AK attest structure>", "signature": "<base64-encoded AK signature>" } } ] } } }
Example response (200 OK, authentication passed):
{ "data": { "type": "session", "id": "550e8400-e29b-41d4-a716-446655440000", "attributes": { "agent_id": "d432fbb3-d2f1-4a97-9ef7-75bd81c00000", "evaluation": "pass", "token": "550e8400-e29b-41d4-a716-446655440000.<secret>", "authentication": [ { "authentication_class": "pop", "authentication_type": "tpm_pop", "chosen_parameters": { "challenge": "<base64-encoded nonce>" }, "data": { "message": "<base64-encoded AK attest>", "signature": "<base64-encoded AK signature>" } } ], "created_at": "2024-01-15T10:30:00.123456Z", "challenges_expire_at": "2024-01-15T10:31:00.123456Z", "response_received_at": "2024-01-15T10:30:30.123456Z", "token_expires_at": "2024-01-15T11:30:00.123456Z" } } }
- Response JSON Object:
data.attributes.evaluation (string) –
"pass"or"fail"data.attributes.token (string) – Bearer token for subsequent requests (only on
"pass")data.attributes.token_expires_at (string) – Token expiration time (only on
"pass")
- Status Codes:
200 OK – PoP response processed (check
evaluationfield for result)400 Bad Request – Missing or invalid request body
401 Unauthorized – PoP verification failed
404 Not Found – Session not found
Attestation Stages and Evaluations
Each attestation progresses through the following stages:
Stage |
Description |
|---|---|
|
Capabilities received, challenge issued, waiting for evidence |
|
Evidence received, verification in progress |
|
Verification finished, see |
The evaluation field indicates the verification result:
Evaluation |
Description |
|---|---|
|
Verification not yet complete |
|
Evidence verified successfully |
|
Evidence verification failed (see |
When an attestation fails, the failure_reason field provides the cause:
Failure Reason |
Description |
|---|---|
|
TPM quote signature invalid or evidence integrity check failed |
|
Evidence is valid but violates the configured attestation policy |