Home / Projects / Orchestrata Ultimate / Decisions / ADR index / ADR-0133
ADR-0133: orchestrata-mcp mints its own short-lived gateway token from the deployed JWT secret, and an exported GATEWAY_TOKEN still wins
| field | value |
|---|---|
| Status | Proposed โ Proposed (amends ADR-0099 rule 1's token wording if accepted) |
| Date | 2026-10-23 |
| Register | factory (docs/adr, 4-digit ids) |
| Source | docs/adr/0133-orchestrata-mcp-mints-its-own-short-lived-gateway-token-from-the-deployed-jwt-secret-and-an-exported-gateway-token-still-wins.md โ recorded on branch fix/ship-sanctioned-gate-pytest at 8c7031c9a, not yet on master |
| Wiki register entry | ADR-0133 (wiki status: Proposed) |
โ ADR-0132
The record
Status: Proposed (amends ADR-0099 rule 1's token wording if accepted) ยท Date: 2026-10-23
Context
Measured 2026-10-22 23:50. Every mcp__orchestrata__* call fails with GATEWAY_UNAVAILABLE: GATEWAY_TOKEN is not set, including gateway_ping, gateway_info and volk_list.
McpTransport._connect(gateway/mcp_transport.py:126) reads the token fromos.environfirst. Failing that, it reads the deployed environment layer thatmain()loads throughload_env_contract, which is/opt/orchestrata/.env./opt/orchestrata/.envis installed from~/.config/orchestrata/.env(ADR-0066 R16,install-orchestrata.sh:188). That file holdsJWT_SECRETand noGATEWAY_TOKEN.- The gateway authenticates in
jwtmode by default (create_authenticator,auth_handler.py:38). Tokens are JWTs signed withJWT_SECRET, withTOKEN_EXPIRY_SECONDS=3600.scripts/mint_gateway_token.py [--user U]mints one throughTokenAuthenticator.create_token. - ADR-0099 rule 1 (Accepted 2026-10-13) says the transport "authenticates with GATEWAY_TOKEN from the deployed environment". A JWT that lives one hour cannot be a fixed entry in a secrets file.
Decision (proposed)
- A. Mint a token with
mint_gateway_token.pyand addGATEWAY_TOKEN=to the secrets file. It works for one hour and then every call fails again, so it only unblocks a single probe. - B (recommended). At connect, the transport mints its own short-lived JWT from
JWT_SECRET, which is already in the deployed environment layer it loads. It reusesTokenAuthenticator.create_token, with a subject naming the client (orchestrata-mcp). An exportedGATEWAY_TOKENstill wins, for tests and for other gateways. - C. Run the gateway in
staticauth mode with a non-expiring token in the secrets file. This weakens auth for every client (the TUI, the bot, the canvas), and the token never expires.
Recommendation: B. It keeps the JWT expiry, adds no long-lived secret on disk, and matches what
scripts/start_test_services.py already does for its demo token. It changes the wording of
Accepted ADR-0099 rule 1, so on acceptance ADR-0099 rule 1 is marked amended by ADR-0133. Rules 2
and 3 are unchanged.
Alternatives rejected
A and C, for the reasons given against each above.
Consequences
- If B is accepted:
- A worker changes
McpTransport._connect, following the brief and ADR-0048 waiver on this ADR. - The transport needs
JWT_SECRET, which the deployed layer already provides. - Every MCP session gets a fresh one-hour token.
- The gateway's audit log records the subject
orchestrata-mcp.
- A worker changes
- Independent of the choice: the prod gateway and kernel units are disabled and inactive (DeepChat, 2026-10-21), so no MCP call can succeed until they run.
Provenance
- Measurements: the session of 2026-10-22, via the AST toolkit (
McpTransport._connect,TokenAuthenticator._get_secret,create_authenticator). - Key names only, never values:
/opt/orchestrata/.envandenv/prod.env. - The scratch decision note
decision-gateway-token.md. - Mohamed asked for the open decisions to be published, 2026-10-23.
Related ADRs
Rulings cited
None.
Specs cited
None (or no spec page exists for the ones named).