fix: routing pod cannot authenticate against gitea-mcp (401 on project_create) #13
Closed
opened 2026-05-18 14:02:46 +00:00 by mathias
·
2 comments
No Branch/Tag Specified
main
fix/pipeline-writes-158
fix/edit-path-io-192
fix/create-regular-188
fix/guard-special-179
fix/linkcheck-keeps-write-178
fix/write-dir-redirect-173
fix/tunnel-detect-174
fix/pipeline-root-157
w3/154-mcp-auth-wiring
fix/tunnel-traversal
test/in-brain-targets-171
fix/brain-scan-root-157
fix/graph-wiki-root-157
fix/vectorstore-root-157
fix/notes-root-157
fix/search-root-157
fix/brainwide-root-157
fix/raw-symlinks-153
feat/symlink-tripwire-157
fix/rest-auth-149
fix/123-brain-edit-envelope-check
feat/106-page-aware-extraction
fix/105-source-drift-on-main
fix/104-surface-merge-conflicts-on-main
agent/b1-compile-on-ingest
agent/104-surface-merge-conflicts
agent/105-source-drift
agent/107-loud-unconfigured-alerting
feat/brain-read-edit
fix/capture-i1-refusal-names-target
renovate/configure
feat/consolidate-single-harness
icebox/cmd-routing
feat/brain-pending-promote
fix/close-session-classification-refresh
fix/capture-summarywriter
v0.24.0
v0.23.1
v0.23.0
v0.22.0
v0.21.1
v0.21.0
v0.20.1
v0.20.0
v0.19.1
v0.19.0
v0.18.4
v0.18.3
v0.18.2
v0.18.1
v0.18.0
v0.17.0
v0.16.1
v0.16.0
v0.15.0
v0.14.0
v0.13.2
v0.13.1
v0.13.0
v0.12.1
v0.12.0
v0.11.2
icebox/cmd-routing-2026-07-01
v0.11.1
v0.11.0
v0.10.0
v0.9.0
v0.8.0
v0.7.0
v0.6.0
v0.5.0
v0.4.1
v0.4.0
v0.3.0
v0.2.0
v0.1.0
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#13
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
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.