OSVauco/docs/runbook/CI6-post-mortem.md

4.2 KiB

CI6 Post-Mortem — Jason bruker live MCP

Dato: 2026-06-10
Løst av: Chris + Perplexity
Varighet: ~2.5 timer


Problemet

Jason-agenten skulle bruke live MCP-verktøy (get_build_status etc.) i stedet for RAG/gjetting. CI6 gikk ikke igjennom på første forsøk — tok mange iterasjoner å debugge.


Rotårsaker (5 stk)

1. Feil Cloud Run URL

osvauco-agent har to URLs:

  • https://osvauco-agent-357036551735.us-central1.run.app — generert URL (ikke bak IAP)
  • https://osvauco-agent-zjbqp3prqq-uc.a.run.app — faktisk URL (bak IAP)

Lærdom: Bruk alltid gcloud run services describe ... --format="value(status.url)" for å hente riktig URL.


2. IAP-middleware blokkerte alle kall unntatt /health

main.py har en require_iap middleware som krever x-goog-authenticated-user-email-header. Kall fra VM uten denne headeren → 401 Unauthorized før FastAPI prosesserer requesten.

Lærdom: For API-kall fra ikke-browser-klienter (scripts, agenter, CI), legg til ruten i IAP_EXEMPT_PATHS eller send headeren manuelt:

-H "x-goog-authenticated-user-email: accounts.google.com:user@vauco.no"

3. RAG blokkerte AFC (Automatic Function Calling)

RAG-verktøyet (VertexAiRagRetrieval) er ikke en Python callable — det er en ADK-spesifikk tool-type. Når den kombineres med FunctionTool-er i samme agent, deaktiveres AFC:

Tools at indices [1] are not compatible with automatic function calling (AFC).

Dette betyr at agenten aldri kaller MCP-verktøyene.

Lærdom: Bland ALDRI VertexAiRagRetrieval og FunctionTool i samme agent. RAG må isoleres i en dedikert sub-agent.

Fix: Fjernet RAG fra root_agent (commit 3bb95c8). TODO: RAG som sub-agent når korpuset er oppdatert.


4. _opax_headers() brukte access token, ikke identity token

google.auth.default() gir et OAuth2 access token — ikke et identity token. Cloud Run krever identity token med riktig aud-claim for å autorisere kall.

Symptom: 401 Unauthorized fra opax-mcp selv om IAM var riktig.

Fix: Bytt til GCE metadata server for å hente identity token med riktig audience (commit 8013bd8):

resp = httpx.get(
    f"http://metadata.google.internal/.../identity?audience={OPAX_MCP_URL}",
    headers={"Metadata-Flavor": "Google"},
)

5. MCP_SECRET ikke mountet på osvauco-agent

mcp-server-key var i Secret Manager, men ikke eksponert som env-var på osvauco-agent. Agenten sendte X-MCP-Key: ""opax-mcp avviste alle kall.

Fix:

gcloud run services update osvauco-agent \
  --update-secrets="MCP_SECRET=mcp-server-key:latest"

Lærdom: Dokumenter ALLE required secrets i .env.example og i Cloud Run deploy-scriptet.


IAM som måtte settes

# VM-SA må kunne kalle begge Cloud Run-tjenester
gcloud run services add-iam-policy-binding osvauco-agent \
  --member="serviceAccount:357036551735-compute@developer.gserviceaccount.com" \
  --role="roles/run.invoker"

gcloud run services add-iam-policy-binding opax-mcp \
  --member="serviceAccount:357036551735-compute@developer.gserviceaccount.com" \
  --role="roles/run.invoker"

Tidslinje

Tid (CEST) Hendelse
06:20 CI5 lukket, build SUCCESS
06:25 Første /chat-kall — 404 (feil endepunkt)
06:30 Oppdaget endepunkt heter /run
06:34 Feil URL brukt (357036551735 vs zjbqp3prqq)
06:45 IAP-middleware identifisert i main.py
06:51 Riktig token-type identifisert (audience-problem)
07:00 VM-SA fikk run.invokerosvauco-agent
07:14 AFC-feil identifisert — RAG blokkerer FunctionTools
07:17 RAG fjernet fra root_agent (commit 3bb95c8)
07:39 _opax_headers() fikset til identity token (commit 8013bd8)
07:47 VM-SA fikk run.invokeropax-mcp
07:52 MCP_SECRET mountet på osvauco-agent
07:53 Jason svarer med live build-data

Forebyggende tiltak

  • IAP_EXEMPT_PATHS dokumentert i main.py
  • .env.example oppdatert med MCP_SECRET
  • RAG som sub-agent (OQ-RAG backlog)
  • Deploy-script skal verifisere alle required secrets er mountet
  • CI-test for MCP-kall skal kjøres automatisk etter hver deploy