OSVauco/docs/RUNBOOK.md
Chris Christiansen 3b6e4e4890 docs/code: clarify A2H2A prototype status and disable execution
- Add Implementation Status section to A2H2A spec

- Clarify Google Chat is notification-only

- Add target approval architecture requirements

- Add critical A2H2A safety principle to RUNBOOK.md

- Remove unsafe approval/rejection endpoints from server.py

- Enforce server-side parameter_hash calculation

- Disable execution for all tools in A2H2A_TOOL_ALLOW_LIST
2026-09-04 12:00:07 +00:00

246 lines
11 KiB
Markdown

# OSVxCC Runbook
> Dette dokumentet beskriver operasjonelle prosedyrer for å håndtere varsler og verifisere systemstatus. Målet er å raskt avklare om en hendelse er reell eller en falsk positiv.
---
## Innholdsfortegnelse
1. [Varsel: "Ukjent bruker" Git Push](#varsel-ukjent-bruker-git-push)
2. [Hendelse: Eksponert Hemmelighet](#hendelse-eksponert-hemmelighet)
3. [Hendelse: Høy andel HTTP 401/403 på Cloud Run](#hendelse-høy-andel-http-401403-på-cloud-run)
4. [Hendelse: HTTP 50x (Cloud Run nede)](#hendelse-http-50x-cloud-run-nede)
5. [Hendelse: VPC Service Controls blokkerer tilgang](#hendelse-vpc-service-controls-blokkerer-tilgang)
6. [Hendelse: Cloud Build / Binary Authorization feiler deploy](#hendelse-cloud-build--binary-authorization-feiler-deploy)
---
## 1. Varsel: "Ukjent bruker" Git Push
### Symptom
Chat-applikasjonen (f.eks. Slack, Discord) rapporterer gjentatte Git-pushes fra en "ukjent bruker" eller en generisk app-bruker (f.eks. "CodeOSS-push, App"). Aktiviteten skjer ofte på faste tidspunkter (f.eks. 09:00 og 21:00).
### Undersøkelsesprosedyre
Følg disse stegene for å verifisere aktiviteten:
1. **Sjekk Git-loggen umiddelbart.**
```bash
git log -n 10 --pretty=format:"%h %an <%ae> %ar: %s"
```
- **Se etter:** Er de siste comittene fra en kjent og autorisert bidragsyter (f.eks. `Chris Christiansen <chris.christiansen@vauco.no>`)?
2. **Analyser tidspunkt og innhold.**
- **Spørsmål:** Samsvarer tidspunktene med normalt utviklingsarbeid? Er commit-meldingene og filendringene logiske?
3. **Verifiser webhook-konfigurasjon.**
- **Undersøk:** Sjekk innstillingene for webhooken i Gitea/GitHub og i chat-applikasjonen. Ofte kan webhooks være konfigurert slik at de ikke klarer å mappe den tekniske brukeren til et visningsnavn, og faller tilbake på et generisk navn.
4. **Kontroller automatiserte systemer (for å utelukke dem).**
- Sjekk Cloud Build-triggere, cron-jobs på VM-en, og eventuelle lokale Git hooks for uventet aktivitet.
### Konklusjon (Mest sannsynlig)
**Ingen sikkerhetshendelse.** Aktiviteten er høyst sannsynlig legitimt utviklingsarbeid utført av en autorisert bruker via en IDE (som VS Code) sin Git-integrasjon. "Ukjent bruker"-navnet er et resultat av hvordan webhooken tolker og presenterer hendelsen.
### Status
**Avklart — Falsk positiv.** Ingen tiltak er nødvendig med mindre `git log` viser ukjente forfattere.
---
## 2. Hendelse: Eksponert Hemmelighet
### Symptom
En hemmelighet (API-nøkkel, passord, tjenestenøkkel) er oppdaget på et usikret sted. Eksempler:
- Limt inn i en offentlig chat (Slack, Discord).
- Sjekket inn i Git og pushet til Gitea/GitHub.
- Hardkodet i en offentlig tilgjengelig fil.
**Dette er en KRITISK hendelse.**
### Undersøkelsesprosedyre (PICERL-fasene)
#### Fase 1: Containment (Innkapsling) - UMIDDELBART
1. **Roter hemmeligheten umiddelbart.** Dette er det viktigste steget for å stoppe misbruk.
1. **Generer en ny verdi** for hemmeligheten.
2. **Opprett en ny versjon** i Secret Manager med den nye verdien. Se `docs/SECRET_MANAGEMENT.md` for detaljerte kommandoer.
```bash
# Eksempel for mcp-server-key
printf "<NY_HEMMELIG_VERDI>" | gcloud secrets versions add mcp-server-key --data-file=-
```
3. **Oppdater applikasjonen(e)** som bruker hemmeligheten til å peke mot den nye versjonen (`latest`). For Cloud Run, deploy en ny revisjon med den oppdaterte hemmelighetsreferansen.
4. **Deaktiver den gamle versjonen** i Secret Manager. **Ikke slett den ennå.** Dette fungerer som en "kill switch".
```bash
gcloud secrets versions disable <GAMMEL_VERSJON> --secret=<HEMMELIGHETENS_NAVN>
```
#### Fase 2: Eradication (Utryddelse)
1. **Fjern hemmeligheten fra eksponeringsstedet.**
- **Git:** Bruk et verktøy som `git-filter-repo` eller `BFG Repo-Cleaner` for å fjerne hemmeligheten fra **hele** Git-historikken. En vanlig `git commit` er **ikke** nok.
- *Referanse: Den tidligere hendelsen med `mcp-server-key` (se `docs/SECURITY_AUDITS.md`).*
- **Slack/Chat:** Slett meldingen.
- **Filer:** Fjern hemmeligheten fra filen og deploy på nytt.
#### Fase 3: Recovery & Lessons Learned
1. **Analyser logger.** Sjekk Secret Manager audit logs for å se om den eksponerte hemmeligheten ble aksessert av uautoriserte IP-adresser eller tjenestekontoer.
- Naviger til `Logging > Log Explorer` i Cloud Console.
- Query:
```
resource.type="gcp_secret"
protoPayload.methodName="AccessSecretVersion"
protoPayload.resourceName="projects/.../secrets/<HEMMELIGHETENS_NAVN>/versions/<GAMMEL_VERSJON>"
```
2. **Verifiser at alle systemer fungerer** med den nye hemmeligheten.
3. **Destruer den gamle versjonen** i Secret Manager etter en verifikasjonsperiode (f.eks. 24-48 timer).
4. **Dokumenter hendelsen** og diskuter hvordan det skjedde for å forhindre gjentakelse.
### Status
🔴 **KRITISK TIL AVKLART.** Følg prosedyren til alle steg er fullført.
---
## 3. Hendelse: Høy andel HTTP 401/403 på Cloud Run
### Symptom
Cloud Monitoring-varsler rapporterer en unormalt høy andel av HTTP-responser med statuskode 401 (Unauthorized) eller 403 (Forbidden) fra MCP-serveren (opax-mcp).
### Undersøkelsesprosedyre
1. **Analyser kildene.**
- Gå til `Logging > Log Explorer` i Cloud Console.
- Kjør en spørring for å gruppere 401/403-feil etter kilde-IP.
```
resource.type="cloud_run_revision"
resource.labels.service_name="opax-mcp"
httpRequest.status IN (401, 403)
```
- Se i loggene etter `jsonPayload.remoteIp`.
2. **Skill mellom angrep og feilkonfigurasjon.**
- **Brute-force/Scanning:** Ser du mange forespørsler fra **én eller få IP-adresser** som ikke er gjenkjennelige? Dette kan tyde på et angrepsforsøk. Vurder å blokkere IP-en midlertidig med Cloud Armor.
- **Feilkonfigurert klient:** Ser du forespørsler fra **kjente IP-adresser** (f.eks. andre VM-er i prosjektet)? Dette tyder på at en legitim klient bruker en utdatert eller feilaktig hemmelighet (`X-MCP-Secret`).
- **Mønster:** Er feilene sporadiske eller konstante? Konstante feil fra en kjent klient indikerer nesten alltid en konfigurasjonsfeil hos klienten.
### Konklusjon (Mest sannsynlig)
- **Scenario A (Ukjent IP):** Potensielt sikkerhetsproblem (scanning). Overvåk og vurder blokkering.
- **Scenario B (Kjent IP):** Operasjonell feil. Informer eieren av klienten om å oppdatere sin hemmelighet.
### Status
🟡 **MODERAT TIL AVKLART.**
---
## 4. Hendelse: HTTP 50x (Cloud Run nede)
### Symptom
Cloud Monitoring varsler om en høy andel HTTP 5xx-feil, eller tjenesten svarer ikke. Dette indikerer at containeren krasjer eller ikke starter.
### Undersøkelsesprosedyre
1. **Sjekk container-logger for krasj.**
- Gå til `Cloud Run > opax-mcp > Logs`.
- Se etter meldinger som indikerer at prosessen stoppet uventet, f.eks. `panic`, `out of memory`, eller andre unntak ved oppstart.
2. **Verifiser IAM-tilganger (spesielt til Secret Manager).**
- Gå til `Cloud Run > opax-mcp > Revisions`.
- Sjekk hvilken Service Account som brukes (skal være `jason-vauger@...`).
- Gå til `IAM & Admin > IAM`.
- Verifiser at `jason-vauger@...` har rollen `roles/secretmanager.secretAccessor`.
- **Vanlig feil:** Hvis applikasjonen ikke får hentet `mcp-server-key` ved oppstart på grunn av manglende IAM-tilgang, vil den ofte krasje med en 5xx-feil.
3. **Analyser nylige endringer.**
- Har det vært en nylig deployering? Rull tilbake til en tidligere, fungerende revisjon via `Cloud Run > opax-mcp > Manage Revisions` for å se om problemet vedvarer.
### Konklusjon (Mest sannsynlig)
- Oftest er dette enten en **bug i koden** (som fører til krasj) eller en **IAM/Secret Manager-konfigurasjonsfeil**.
### Status
🔴 **KRITISK TIL AVKLART.**
---
## 5. Hendelse: VPC Service Controls blokkerer tilgang
### Symptom
En applikasjon, et skript eller en utvikler mottar en `403 Request Prohibited by organization's policy` feil ved kall mot en GCP API (f.eks. BigQuery, Storage) som er beskyttet av en VPC-SC perimeter.
### Undersøkelsesprosedyre
1. **Finn VPC-SC brudd-loggen.**
- Gå til `Logging > Log Explorer`.
- Bruk følgende spørring for å finne de relevante loggene:
```
log_id("cloudaudit.googleapis.com/activity")
protoPayload.metadata.violationReason = "SERVICE_NOT_ALLOWED_FROM_VPC" OR "NO_MATCHING_ACCESS_LEVEL"
```
2. **Analyser logg-detaljene.**
- `resource.labels.project_id`: Hvilket prosjekt skjedde bruddet i?
- `protoPayload.authenticationInfo.principalEmail`: Hvem eller hva ble blokkert?
- `protoPayload.requestMetadata.callerIp`: Hvor kom kallet fra (hvis relevant)?
- `protoPayload.resourceName`: Hvilken beskyttet ressurs var målet?
### Konklusjon (Mest sannsynlig)
- **Scenario A (Legitimt kall blokkert):** En ny tjeneste eller utvikler-VM er satt opp utenfor perimeteren og trenger tilgang. **Tiltak:** Vurder å inkludere ressursen i perimeteren, eller opprett et tilgangsnivå (Access Level).
- **Scenario B (Uventet kall blokkert):** Et uautorisert skript eller en ekstern tjeneste prøver å nå en beskyttet ressurs. **Konklusjon:** Perimeteren har fungert som designet og forhindret et potensielt datainnbrudd.
### Status
🟡 **MODERAT TIL AVKLART.** Krever analyse for å skille mellom feilkonfigurasjon og reell beskyttelse.
---
## 6. Hendelse: Cloud Build / Binary Authorization feiler deploy
### Symptom
En Cloud Build-pipeline feiler på det siste "deploy to Cloud Run"-steget. Feilmeldingen nevner `Binary Authorization` eller `attestation`.
### Undersøkelsesprosedyre
1. **Sjekk bygge-loggen for TYR-feil.**
- Åpne loggen for den feilede builden i Cloud Build.
- Scroll opp til steget som kjører **TYR Compliance Scan**.
- Hvis dette steget feilet (rødt ikon), vil loggen inneholde detaljer om nøyaktig hvilken compliance-regel som ble brutt.
2. **Verifiser at attestering finnes.**
- Hvis TYR-steget var vellykket, men deploy likevel feiler, kan selve attesteringen mangle.
- Finn "digest" for ditt image i loggen (en lang `sha256:...` streng).
- Kjør denne kommandoen i Cloud Shell:
```bash
gcloud container binauthz attestations list --artifact-url="[REGION]-docker.pkg.dev/[PROJECT_ID]/[REPO]/[IMAGE_NAME]@[IMAGE_DIGEST]"
```
### Konklusjon (Mest sannsynlig)
- **TYR-feil:** Den vanligste årsaken. En endring i koden eller infrastrukturen bryter med en definert sikkerhetsregel. **Tiltak:** Rett feilen som TYR rapporterer.
- **Manglende attestering:** Output fra `gcloud` er tomt. Dette kan skyldes en midlertidig feil med KMS eller at IAM-rettighetene til Cloud Build sin service account er feil. **Tiltak:** Prøv å kjøre builden på nytt. Hvis feilen vedvarer, sjekk IAM for `cloud-build-private-pool@...`.
### Status
🟡 **MODERAT TIL AVKLART.** Vanligvis en operasjonell feil forårsaket av en compliance-endring.
---
## 7. Sikkerhet og Hendelseshåndtering
Se følgende dokumenter for detaljerte prosedyrer:
- `docs/SECURITY.md`: Overordnet sikkerhetsarkitektur.
- `docs/INCIDENT_RESPONSE.md`: Prosedyrer for håndtering av sikkerhetshendelser.
- `docs/SECRET_MANAGEMENT.md`: Retningslinjer for håndtering av secrets.
### Kritisk Sikkerhetsprinsipp for A2H2A
**No privileged action may be authorized by a notification, a URL parameter, or a client-supplied identity. Approval requires a verified identity boundary and server-side validation of an immutable ticket.**