Raxx · internal docs

internal · gated

ADR 0056 — Reasonator service auth: bearer token in vault

Status: Accepted Date: 2026-05-09 UTC Refs: #1385, docs/architecture/reasonator/design.md (Decision 3)


Context

Raptor must authenticate to Reasonator on every request. Reasonator is a private service (not public-facing), but it handles scoring requests that are tier-tagged (X-Raxx-Tier). An unauthorized caller that spoofed a pro_plus tier header could consume priority capacity.

Three options were evaluated: Bearer token in Infisical, mTLS, and OAuth2 client credentials.


Decision

Bearer token stored in Infisical at /reasonator/prod/REASONATOR_SERVICE_TOKEN. Raptor reads the token at startup and re-reads on SIGHUP (for rotation without redeploy). Reasonator verifies the token on every inbound request via a middleware check. The token is 32 bytes random, base64url-encoded (256-bit entropy).

Vault folder /reasonator/ must be created in Infisical before the first secret write. The scaffold sub-card is responsible for this step.


Consequences


Alternatives Considered

mTLS: Strong mutual authentication. Requires client certificate provisioning, renewal, and Heroku routing that can verify client certs (Heroku does not terminate mTLS by default — would require an nginx sidecar or SNI passthrough). Significant ops overhead for a private service-to-service call. Deferred to a future security hardening ADR if SOC 2 scope demands it.

OAuth2 client credentials: Standards-based with built-in expiry. Requires an authorization server (another service to run and maintain). Over-engineered for a single service-to-service pair. Rejected.

IP allowlist only: Insufficient — Heroku dynos share IP ranges with other tenants. IP allowlist cannot uniquely identify Raptor as the caller.