Security Model
Defence-in-depth across auth, encryption, signing, and key management.
Authentication
- API keys: Hashed with HMAC-SHA256 before storage. Plaintext never persisted.
- Pilot tokens: SHA-256 hashed. Scoped by max jobs, expiry, and allowed lanes.
- Partner API keys: Separate table from core platform keys (anti-contamination).
- Rate limiting: Redis-backed in production (100 req/min per key hash). In-memory for pilot.
Replay protection
Mutating requests (POST, PUT, DELETE) in production postures require:
X-Nonceheader (one-time use, scoped by key hash)X-Timestampheader (within configurable window, default ±300s)
Nonces are stored in Redis with TTL matching the timestamp window. Fail-closed: if Redis is unreachable, requests are rejected.
Request signing
Optional per-key policy. When enabled, the X-Signature header must contain a valid HMAC-SHA256 signature over METHOD + PATH + QUERY + TIMESTAMP + NONCE + BODY_HASH. Per-key signing secrets are encrypted at rest.
Encryption at rest
- Database: Cloud SQL with Google-managed encryption (AES-256).
- Uploads: Stored in Cloud Storage with default encryption. Automatic deletion within 24 hours.
- CMEK: Available for Enterprise MMC lanes only.
Key management
- Receipt signing: Ed25519 signing keys are protected by Google Cloud KMS in production. Private keys are not exported.
- JWKS (canonical): Issuer public keys are published at https://registry.attestlayer.com/v1/jwks/issuer.jwks.json. Each kit also includes a jwks.json snapshot for offline verification.
- Key rotation: Enabled in production postures. Old keys remain in JWKS for verification of previously issued receipts.
Posture model
Three postures with escalating security controls:
| Feature | Pilot | MSP Prod | Enterprise |
|---|---|---|---|
| Redis required | No | Yes | Yes |
| Replay protection | No | Yes | Yes |
| Fail-closed nonce | No | Yes | Yes |
| Auto-migrations | Yes | No (fail-fast) | No (fail-fast) |
| Pub/Sub audit | No | No | Yes |
