120 lines
4.2 KiB
Markdown
120 lines
4.2 KiB
Markdown
# 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`):
|
|
```python
|
|
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:**
|
|
```bash
|
|
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
|
|
```bash
|
|
# 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.invoker` på `osvauco-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.invoker` på `opax-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
|