Service-to-Service Authentication
HMAC-SHA256 Request Signing
All internal service-to-service calls are authenticated via HMAC-SHA256 request signatures. This prevents untrusted callers from accessing internal endpoints directly.
Signature Construction
The canonical string is composed of the HTTP method, request path, and a timestamp. The signature is computed as HMAC-SHA256(secret, canonical_string) and sent in a dedicated internal auth header.
| Component | Source |
|---|---|
| Method | HTTP method (GET, POST, etc.) |
| Path | Request path |
| Timestamp | Current Unix timestamp (seconds) |
| Secret | Shared service secret (minimum 32 characters in production) |
Headers
Outbound service-to-service requests include the HMAC signature, calling service identifier, and propagated tenant context.
Replay Protection
Signatures include a timestamp component. The receiving service rejects requests with expired timestamps to prevent replay attacks.
Enforcement Modes
| Mode | Behavior |
|---|---|
enforce |
Rejects requests without valid HMAC signature (403). Default in production. |
audit |
Logs invalid signatures but allows the request. Default in development. |
disabled |
No-op. Never used as a default. |
Outbound Signing
When the API Gateway proxies requests to downstream services, it automatically signs each outbound request and propagates the tenant context.
Inbound Verification
Downstream services verify signatures via middleware. On success, the request is annotated as an internal request with the calling service identity. On failure in enforce mode, the middleware returns a 403 response.
Implemented at commit 4b572c2.