Authentication¶
Every endpoint requires partner authentication. The contract supports two schemes for synchronous calls and one signing scheme for asynchronous webhook delivery.
Schemes¶
Direction |
Environment |
Scheme |
|---|---|---|
Sync call into a planner or executor |
Production |
mTLS |
Sync call into a planner or executor |
Dev / test |
API key |
Webhook delivery from a planner to an executor |
All |
HMAC-SHA256 over body |
mTLS (production)¶
The caller presents a client certificate at the TLS handshake. The receiver resolves the certificate thumbprint to a row in its partner registry — a per-partner record that holds:
partner_id(warehouse + vendor, see below)Certificate thumbprint
Allowed warehouse(s)
Dispatch transport configuration (if the partner is a webhook recipient)
HMAC secret (if applicable)
The mTLS handshake authenticates; the partner registry authorizes. A handshake-valid certificate that is not in the registry is rejected with 401.
Self-signed certificates are not accepted in production. Certificates must chain to a CA the receiving side has explicitly enrolled. In practice, both sides exchange CA bundles during onboarding.
API key (dev / test only)¶
Authorization: Bearer <key>
API keys are acceptable for dev and test environments. They must be disabled per partner in production via partner-registry configuration. A production receiver that accepts a bearer token without falling back to mTLS is a misconfiguration.
Rotate dev keys on a fixed cadence (recommended: 90 days, matching DotID ADR-0021 access-key lifetime). Compromised keys are rotated immediately and the old key is invalidated.
HMAC-SHA256 (webhooks)¶
When the planner sends a webhook event to an executor, the planner signs the raw request body with a per-partner shared secret and includes the signature in the header:
X-FGAI-Signature: sha256=<hex>
The receiving side must:
Read the raw body before parsing.
Compute
HMAC-SHA256(secret, raw_body).Constant-time compare the result against the header.
Reject with
401on mismatch.
Skipping signature verification is a serious vulnerability — anyone who can reach the webhook URL can inject events. Always verify.
The HMAC secret rotates via the partner registry. During rotation, the planner sends the current secret in the signature and the receiver tolerates both old and new secrets for a configurable overlap window (typical: 24h).
Warehouse scoping¶
Warehouse scoping is mandatory. A credential registered for WH-Tokyo-01 must not be accepted for WH-Tokyo-02. The partner registry record (warehouse, vendor) is authoritative; the Policy Decision Point refuses cross-warehouse traffic from the same credential with 403.
This is the single most-violated rule during integration. Test it explicitly during partner onboarding — provision a credential for one warehouse, then deliberately try to post for a different warehouse and confirm you get 403.
partner_id format¶
partner_id carries the warehouse and the integrating vendor:
{warehouse_code}/{vendor_code}
Examples:
WH-Tokyo-01/AcmeWES
WH-Newark-03/ManhattanWMS
WH-Shanghai-02/FG.AI
Do not overload partner_id with tenant, environment, or integration-instance information. Keep those in the partner registry record or in the request meta object. Overloading breaks ad-hoc rolegrep and creates ambiguous logs.
Independence from interactive user JWTs¶
The partner credentials described here are entirely separate from the Keycloak JWTs that authenticate interactive users in the FlexGalaxy console (see DotID — API authentication and JWT validation). A wes-contract partner does not present a user JWT; the planner-executor exchange is a service-to-service trust path.
When a human supervisor resolves a discrepancy through the planner’s UI, that supervisor’s user JWT is what the planner records in the audit log alongside the action. The executor side has no knowledge of the supervisor’s identity.