fix: routing pod cannot authenticate against gitea-mcp (401 on project_create) #13
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
project_createfails at stepcreate_repowithmcp http 401: unauthorizedwhen called via the routing pod. The routing pod cannot authenticate against the gitea-mcp server.Symptoms
Investigation so far (2026-05-18)
What we know
GITEA_MCP_TOKENwas patched intorouting-secretsbut appears to be emptyGITEA_MCP_STATIC_TOKENingitea-mcp-secretsappears to be a placeholder value (---...)2026-05-18T06:06:42Zwith no restartsWhat needs investigation
Question 1: What is GITEA_MCP_STATIC_TOKEN actually used for?
gitea-mcp has two token env vars:
GITEA_MCP_DEFAULT_TOKEN— likely the Gitea API token (for API calls to Gitea)GITEA_MCP_STATIC_TOKEN— likely the MCP server auth token (for authenticating MCP clients)Verify by reading gitea-mcp source:
Question 2: Is the GITEA_MCP_STATIC_TOKEN a real value or placeholder?
If it's a placeholder, the real token lives elsewhere (SOPS encrypted file, .env on disk, etc).
Question 3: How does claude.ai authenticate to gitea-mcp today?
claude.ai calls gitea-mcp successfully (we use it in every session). Check what auth mechanism it uses — likely Dex JWT, not static token. If so, routing pod needs to use Dex JWT too, not a static token.
Check gitea-mcp auth middleware:
Question 4: What does the mcpclient in hyperguild send as auth?
The
mcpclient.New(cfg.GiteaMCPURL, cfg.GiteaMCPToken)call — what does it set as the auth header? Does it match what gitea-mcp expects?Expected fix
Once the correct token/auth mechanism is identified:
routing-secretscorrectlyAfter fix
Re-run e2e test:
Expected: all five artifacts created — Gitea repo, GitHub repo, mirror sync, infra namespace, issue.
Cleanup needed
test-throwaway-001andtest-throwaway-002Gitea repos still exist and should be deleted after this is resolved. GitHub repos too if they were created.Related
92cdeccf,b6d8244,fd3d4d1(deployment.yaml patches)Resolved
Root cause
routing-secretsdid not containGITEA_MCP_TOKEN. Themcpclient.New(url, token)constructor accepts an empty token without complaint, and at request time it only setsAuthorization: Bearer …whenc.token != "". So the routing pod was sending requests with no Authorization header at all — gitea-mcp'sBearerMiddlewarerejects that outright as 401.Answers to the investigation questions
GITEA_MCP_STATIC_TOKENis the MCP server auth token, compared constant-time against the incoming Bearer ininternal/auth/bearer.go.GITEA_MCP_DEFAULT_TOKENis the upstream Gitea PAT used by the gitea client. They're intentionally decoupled (seeBearerMiddlewaredoc comment).d7423fc3eabcb9d2f1ee2b0d88b5d15a2c51b54fingitea-mcp/secrets.enc.yaml.elsebranch of the middleware). Routing pod doesn't have a JWT-issuing identity inside the cluster, so static token is the correct choice for service-to-service.Authorization: Bearer <c.token>only when token is non-empty. Emptyc.token⇒ no header ⇒ 401. Matches what gitea-mcp expects when the value is the static token.Fix
infra commit
2b7d792:sops setGITEA_MCP_TOKEN: d7423fc3…intorouting-secrets.secrets-revisionannotation so the rollout picked up the newenvFromvalue (envFrom doesn't auto-reload on Secret changes — known gotcha).Verification
E2E
project_create(name=test-throwaway-003, …)via port-forward torouting/3210:All five steps green.
Cleanup
mathias/test-throwaway-002,mathias/test-throwaway-003deleted ✅staging/test-throwaway-003branch on infra deleted ✅mathiasb/test-throwaway-003still orphaned —ghtoken lacksdelete_reposcope. Rungh auth refresh -h github.com -s delete_repothengh repo delete mathiasb/test-throwaway-003 --yes. (-001and-002were 404 — never created on GitHub because GITHUB_PAT was missing during those runs.)Closing.
✅ RESOLVED — 2026-05-18
Root cause:
GITEA_MCP_TOKENin routing-secrets was empty. Fixed by CC on koala — correct static token patched into routing-secrets and routing pod restarted.project_create e2e test passed after fix. All five steps reached including
create_repowhich was previously 401.Remaining action
GITEA_MCP_TOKEN should be added to the SOPS-encrypted
secrets.enc.yamlfor the routing pod so it survives secret rotation and cluster rebuilds — currently only patched imperatively into routing-secrets.