# AirGap Time API (status + anchor ingest) ## Endpoints - `POST /api/v1/time/anchor` - Body (JSON): - `tenantId` (string, required) - `hexToken` (string, required) — hex-encoded Roughtime or RFC3161 token. - `format` (string, required) — `Roughtime` or `Rfc3161`. - `trustRootKeyId` (string, required) - `trustRootAlgorithm` (string, required) - `trustRootPublicKeyBase64` (string, required) — pubkey (Ed25519 for Roughtime, RSA for RFC3161). - `warningSeconds` (number, optional) - `breachSeconds` (number, optional) - Response: `TimeStatusDto` (anchor + staleness snapshot) or 400 with reason (`token-hex-invalid`, `roughtime-signature-invalid`, `rfc3161-verify-failed:*`, etc.). - Example: ```bash curl -s -X POST http://localhost:5000/api/v1/time/anchor \ -H 'content-type: application/json' \ -d '{ "tenantId":"tenant-default", "hexToken":"01020304deadbeef", "format":"Roughtime", "trustRootKeyId":"root-1", "trustRootAlgorithm":"ed25519", "trustRootPublicKeyBase64":"", "warningSeconds":3600, "breachSeconds":7200 }' ``` - `GET /api/v1/time/status?tenantId=` - Returns `TimeStatusDto` with anchor metadata and staleness flags. 400 if `tenantId` missing. - `GET /healthz/ready` - Health check: `Healthy` when anchor present and not stale; `Degraded` when warning threshold crossed; `Unhealthy` when missing/stale. Uses configured tenant/budgets. ## Config `appsettings.json` (see `docs/airgap/time-config-sample.json`): ```json { "AirGap": { "TenantId": "tenant-default", "Staleness": { "WarningSeconds": 3600, "BreachSeconds": 7200 } } } ``` ## Startup validation - The host runs sealed-mode validation at startup using the configured tenant and budgets. - Fails closed with `sealed-startup-blocked:` if anchor is missing/stale or budgets mismatch. ## Notes - Roughtime verifier checks Ed25519 signatures (message||signature framing). - RFC3161 verifier uses SignedCms signature verification and signing-time attribute for anchor time. - DTO serialization is stable (ISO-8601 UTC timestamps, fields fixed).