Skip to content

fix: forward HERMES_API_TOKEN to gateway in proxy routes - #19

Open
coolswood wants to merge 1 commit into
JPeetz:mainfrom
coolswood:fix/gateway-proxy-authorization
Open

fix: forward HERMES_API_TOKEN to gateway in proxy routes#19
coolswood wants to merge 1 commit into
JPeetz:mainfrom
coolswood:fix/gateway-proxy-authorization

Conversation

@coolswood

Copy link
Copy Markdown

Summary

Fixes #17.

Several server-side proxy routes forwarded requests to the Hermes gateway without the Authorization: Bearer header, even when HERMES_API_TOKEN was set. When the gateway has API_SERVER_KEY configured (the documented, required setting for API_SERVER_HOST=0.0.0.0), it correctly rejects these requests with 401 gateway_auth_failed.

This breaks the Jobs view (Failed to load jobs: Failed to fetch jobs: 401), leaves the model dropdown empty, drops run events before they reach the browser, and forces approvals through the chat-command fallback instead of the native endpoint. Gateway logs fill with:

WARNING gateway.platforms.api_server: API server rejected invalid API key: method='GET' path='/api/jobs?include_disabled=true' user_agent='node'

A canonical helper already exists — BEARER_TOKEN exported from src/server/gateway-capabilities.ts, already used by hermesGet/hermesPost in src/server/hermes-api.ts. The proxy routes just didn't use it.

Changes

Reuses the existing BEARER_TOKEN pattern and passes Authorization: Bearer ... on every gateway fetch in the affected routes. The universal proxy (hermes-proxy/$.ts) now sets Authorization explicitly from HERMES_API_TOKEN rather than copying the browser request's headers verbatim — the browser authenticates with a hermes-auth cookie, which the gateway does not accept as a bearer token.

  • src/routes/api/hermes-jobs.ts (GET, POST)
  • src/routes/api/hermes-jobs.$jobId.ts (GET, POST, PATCH, DELETE)
  • src/routes/api/models.ts (fetchHermesModels)
  • src/routes/api/hermes-runs.ts (POST)
  • src/routes/api/hermes-runs.$runId.events.ts (SSE GET)
  • src/routes/api/approvals.$approvalId.approve.ts (native /approve)
  • src/routes/api/approvals.$approvalId.deny.ts (native /deny)
  • src/routes/api/hermes-proxy/$.ts (sets Authorization from BEARER_TOKEN)

Verification

Against Hermes Agent v0.20.0 (API_SERVER_ENABLED=true, API_SERVER_HOST=0.0.0.0, API_SERVER_KEY set):

Endpoint Before After
GET /api/hermes-jobs?include_disabled=true 401 200
GET /api/models empty / 401 200, models populated
GET /v1/runs/{id}/events 401 SSE stream
Gateway 401 log lines (~8/min) ongoing 0

npx tsc --noEmit introduces no new errors (the 4 pre-existing errors on main are unrelated: the missing remark-math/rehype-katex deps and two untouched files). prettier --check passes on all changed files.

Related: #18 (separate but similar-class bug — listSessions/getMessages reading .items instead of .data).

Several server-side proxy routes forwarded requests to the gateway without
the Authorization: Bearer header, even when HERMES_API_TOKEN was set. With
API_SERVER_KEY configured the gateway rejects them with 401 gateway_auth_failed,
breaking Jobs ("Failed to load jobs: 401"), the model dropdown, run events
and approvals. The universal proxy also forwarded the browser's headers
verbatim, but the browser authenticates with a hermes-auth cookie, not the
gateway bearer.

Reuses the existing BEARER_TOKEN from gateway-capabilities.ts (same pattern
hermesGet/hermesPost already use) and passes Authorization on every gateway
fetch in the affected routes. The proxy now sets Authorization explicitly
from HERMES_API_TOKEN.

Affected routes:
- src/routes/api/hermes-jobs.ts (GET, POST)
- src/routes/api/hermes-jobs.$jobId.ts (GET, POST, PATCH, DELETE)
- src/routes/api/models.ts (fetchHermesModels)
- src/routes/api/hermes-runs.ts (POST)
- src/routes/api/hermes-runs.$runId.events.ts (SSE GET)
- src/routes/api/approvals.$approvalId.approve.ts (native /approve)
- src/routes/api/approvals.$approvalId.deny.ts (native /deny)
- src/routes/api/hermes-proxy/$.ts (sets Authorization from BEARER_TOKEN)

Closes JPeetz#17
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

@coolswood is attempting to deploy a commit to the Joerg Peetz's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proxy routes call gateway without Authorization → 401 on Jobs/Models/Runs/Approvals when API_SERVER_KEY is set

1 participant