Hash Chain Verification
Verify the integrity of the audit log hash chain over a specified time window. The audit log is structured as a hash chain — each record contains the hash of the previous record — making it tamper-evident. This endpoint walks the chain and reports whether every link is valid.
Endpoint
GET /api/v1/audit/verify-chain
Required Role
ADMIN
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer <token> | Yes |
X-Tenant-ID | Tenant identifier string | Yes |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start | string | Yes | ISO 8601 start timestamp (inclusive). |
end | string | Yes | ISO 8601 end timestamp (inclusive). |
Time Window Limit
The requested window (end minus start) must not exceed 30 days. Requests spanning a longer period will be rejected with 400 Bad Request.
Response Body
json
{
"valid": true,
"brokenAt": null,
"reason": null,
"recordsVerified": 4821
}| Field | Type | Description |
|---|---|---|
valid | boolean | true if every record in the window forms an unbroken hash chain; false if any link is invalid or missing. |
brokenAt | string | null | ISO 8601 timestamp of the first record where the chain breaks. null when valid is true. |
reason | string | null | Human-readable description of why the chain is broken. null when valid is true. |
recordsVerified | number | Total number of audit records examined during verification. |
HTTP Status Codes
| Status | Meaning |
|---|---|
200 OK | Verification completed. Inspect valid to determine chain integrity. |
400 Bad Request | Missing parameters, malformed timestamps, or requested window exceeds the 30-day limit. |
401 Unauthorized | Missing or invalid bearer token. |
403 Forbidden | Token is valid but the caller lacks the ADMIN role. |
500 Internal Server Error | Unexpected engine failure during verification. |
Examples
bash
curl -X GET "https://policy.aster-lang.dev/api/v1/audit/verify-chain?start=2024-01-01T00:00:00Z&end=2024-01-31T23:59:59Z" \
-H "Authorization: Bearer <token>" \
-H "X-Tenant-ID: acme-corp"js
const params = new URLSearchParams({
start: '2024-01-01T00:00:00Z',
end: '2024-01-31T23:59:59Z',
});
const response = await fetch(
`https://policy.aster-lang.dev/api/v1/audit/verify-chain?${params}`,
{
headers: {
Authorization: 'Bearer <token>',
'X-Tenant-ID': 'acme-corp',
},
}
);
const result = await response.json();
if (!result.valid) {
console.error(`Chain broken at ${result.brokenAt}: ${result.reason}`);
}Example Response — Valid Chain
json
{
"valid": true,
"brokenAt": null,
"reason": null,
"recordsVerified": 4821
}Example Response — Broken Chain
json
{
"valid": false,
"brokenAt": "2024-01-14T08:22:11Z",
"reason": "Hash mismatch: stored hash does not match recomputed hash for record id=a3f9c1d2",
"recordsVerified": 512
}