Orchestrata Ultimate › Research › Gateway token analysis

Gateway token analysis — how orchestrata-mcp authenticates

Question How should the orchestrata-mcp stdio server get the token it needs to talk to the gateway?
Method Measured 2026-10-22 23:50. Three mcp__orchestrata__* tools were called (gateway_ping, gateway_info, volk_list), and the token path was traced through the transport, the authenticator and the installer (file and line cited below)
Status OPEN. Published 2026-10-23 as ADR-0133 (Proposed), with option B recommended. It needs Mohamed's ruling because it changes the text of Accepted ADR-0099 rule 1

What happens today

Every orchestrata MCP tool returns:

GATEWAY_UNAVAILABLE: GATEWAY_TOKEN is not set

The chain behind that error:

  1. The transport. McpTransport._connect (gateway/mcp_transport.py:126) reads GATEWAY_TOKEN from the process environment. If the variable is not there, it falls back to the deployed env layer that main() loads through load_env_contract, which is /opt/orchestrata/.env.
  2. The env file. /opt/orchestrata/.env is installed from ~/.config/orchestrata/.env (ADR-0066 R16, install-orchestrata.sh:188). It holds the gateway's JWT signing secret (JWT_SECRET) and other credentials, but no GATEWAY_TOKEN.
  3. The gateway's auth. The gateway's default auth mode is jwt (create_authenticator, auth_handler.py:38). Tokens are JWTs signed with JWT_SECRET, and they expire after TOKEN_EXPIRY_SECONDS=3600.
  4. A minting tool exists. scripts/mint_gateway_token.py [--user U] mints a token through TokenAuthenticator.create_token.
  5. What ADR-0099 says. Rule 1 (Accepted 2026-10-13) says the client "authenticates with GATEWAY_TOKEN from the deployed environment". But a JWT that lives one hour cannot be a fixed entry in a secrets file.

The rule and the token lifetime contradict each other. Writing the variable into the file would not fix the design.

Options

Option What it fixes What it costs
A Mint a token, add GATEWAY_TOKEN= to ~/.config/orchestrata/.env, and reinstall One hour of working MCP calls It fails again after 3600 s. It also puts a long-lived credential on disk for no lasting gain
B The transport mints its own short-lived JWT at connect time, from JWT_SECRET, which is already in the env layer it loads. An exported GATEWAY_TOKEN still wins when set Works in every session. Nothing expires between sessions. No new secret is stored A small worker change in McpTransport._connect, reusing TokenAuthenticator.create_token. It amends ADR-0099 rule 1 to "a token minted from the deployed JWT_SECRET, or GATEWAY_TOKEN when exported"
C Run the gateway in static auth mode with a non-expiring token in the secrets file Works in every session It weakens auth for every gateway client, including the TUI and the bot, and the token never expires

Recommendation: B

ADR-0133 records B as the proposed decision, with the token's subject set to orchestrata-mcp. B keeps the JWT expiry and stores no new secret. It is also the pattern the test services already use: start_test_services.py mints its demo token the same way. The change is small, and the gateway does not change at all.

Diagram projects-orchestrata-ultimate-research-gateway-token-analysis-1

Why this matters beyond MCP

With the gateway token missing, Claude has no working path to the kernel through MCP: no volk list, no workflow start, no gateway info. The gateway and kernel units have also been disabled since 2026-10-21 (see host inventories). Fixing the token alone does not bring the runtime back. Re-enabling the units is a separate open item that awaits Mohamed.

Related plan item: the components cut-over's INT-11 increment covers mint_gateway_token. The plan still lists its N4 gate as open, although N4 was approved under AD-65 R3 (see the cut-over review).