Authenticating an inbound factory dispatch

When trustmint dispatches to your factory backend — an annihilation or provisioning leg sent to the EndpointURL you registered — it authenticates the request as its own workload identity. Every dispatch carries an Authorization: Bearer <jwt> header holding a short-lived JWT that DotID minted for trustmint via RFC 8693 token exchange.

Your factory backend MUST verify that token before acting on the payload. A backend that trusts an unverified Bearer (or ignores the header) will accept a forged or misdirected dispatch. This page is the verification contract.

What to verify

Check

Requirement

Signature

RS256 (or RS384/RS512) over the DotID token-exchange signing key. Reject alg=none and every HMAC (HS*) algorithm outright.

Issuer (iss)

Exactly https://auth.flexgalaxy.ai/auth/realms/token-exchange.

Audience (aud)

Must contain factory-dispatch. A token minted for any other audience (a different platform service) must be rejected.

Expiry (exp)

In the future. Dispatch tokens live 15 minutes; allow a small clock-skew leeway (≈60s).

Signing keys are published as a JWKS. Fetch and cache it (refresh in the background); do not fetch per request. The current signing key id is dotid-token-exchange-signing-v1.

If any check fails, respond 401 and do not process the payload — fail closed.

Claims you can trust after verification

Claim

Meaning

sub

trustmint’s workload-identity id (the dispatcher).

aud

factory-dispatch.

resource

The factory-service FRN this dispatch is bound to (per-instance binding).

federated_subject

{ issuer, sub } — the original federated identity the exchange was performed for (trustmint’s runtime service account).

jti

Unique token id — log it for audit correlation.

Reference implementation

A runnable reference backend ships in the trustmint tree at services/thingmake/cmd/factory-dispatch-refstub. It performs exactly the checks above (via the reusable pkg/factorydispatch verifier), logs a structured DISPATCH RECEIVED (verified) line, and returns 200; unverifiable Bearers get 401 before the handler runs. Run --expected-resource=<FRN> to enable per-instance binding. Use it as the executable specification for your own backend.

POST /v1/annihilate            (or your registered dispatch path)
Authorization: Bearer <factory-dispatch jwt>
→ 200 once verified, 401 otherwise