feat: billing IAM hardening — 11-billing-iam-hardening.sh, jason.vauger viewer, MASTERPLAN oppdatert
This commit is contained in:
parent
aff36f2f35
commit
25eec703ce
30
.env.example
30
.env.example
|
|
@ -6,7 +6,7 @@
|
|||
export PROJECT_ID="propane-will-491900-m5"
|
||||
export REGION="us-central1"
|
||||
export BILLING_ACCOUNT_ID="XXXXXX-XXXXXX-XXXXXX" # gcloud billing accounts list
|
||||
export ALERT_EMAIL="your-email@example.com"
|
||||
export ALERT_EMAIL="chris.christiansen@vauco.no"
|
||||
|
||||
# ── Service Account ────────────────────────────────────────────
|
||||
export AGENT_SA="osvauco-agent-sa@${PROJECT_ID}.iam.gserviceaccount.com"
|
||||
|
|
@ -43,22 +43,38 @@ export GITHUB_APP_INSTALLATION_ID="" # eks: 12345678
|
|||
# ── Observability ────────────────────────────────────────────
|
||||
# ALERT_EMAIL er allerede satt ovenfor
|
||||
|
||||
# ── Billing IAM Hardening (11-billing-iam-hardening.sh) ─────────────
|
||||
# Kommaseparert liste — får roles/billing.viewer på billing-kontoen
|
||||
# jason.vauger = agentens identitet (kan hente kostnadsdata autonomt)
|
||||
# chris = eier med eksplisitt viewer i tillegg til admin
|
||||
export BILLING_VIEWER_EMAILS="chris.christiansen@vauco.no,jason.vauger@vauco.no"
|
||||
# Google Workspace / Cloud Identity domene:
|
||||
# Sett kun hvis vauco.no er koblet som org i GCP — fjerner billing.creator fra domenet
|
||||
# export ORG_DOMAIN="vauco.no"
|
||||
#
|
||||
# Fremtidig (Fase C): erstatt enkeltadresser med Google Group:
|
||||
# export BILLING_VIEWER_EMAILS="billing@vauco.no"
|
||||
|
||||
# ── Webhook / Chat-notifikasjoner ────────────────────────────
|
||||
# Lagres i Secret Manager, ikke her:
|
||||
# gcloud secrets create webhook-url --data-file=<(echo -n "https://DIN-WEBHOOK-URL")
|
||||
# Se: infrastructure/notifications/webhook-setup.md
|
||||
|
||||
# ── VPC / Security (valgfritt) ────────────────────────────────
|
||||
export VPC_NETWORK="default"
|
||||
# export CMEK_KEY_RING="agent-keyring" # kun ved CMEK
|
||||
# export CMEK_KEY_NAME="agent-key" # kun ved CMEK
|
||||
# export CMEK_KEY_RING="agent-keyring"
|
||||
# export CMEK_KEY_NAME="agent-key"
|
||||
|
||||
# ── IAP / Domene (Fase B) ─────────────────────────────────────
|
||||
# export IAP_DOMAIN="opax.vauco.no"
|
||||
# export IAP_CLIENT_ID="" # fra GCP Console → IAP
|
||||
# export IAP_CLIENT_SECRET="" # fra GCP Console → IAP
|
||||
# export IAP_CLIENT_ID=""
|
||||
# export IAP_CLIENT_SECRET=""
|
||||
|
||||
# ── Terraform / Kunde-onboarding (Fase C) ─────────────────────
|
||||
# Brukes av vauco-bootstrap Terraform-modul ved onboarding av ny kunde
|
||||
# export TF_VAR_customer_id="medioteq"
|
||||
# export TF_VAR_customer_project_id=""
|
||||
# export TF_VAR_customer_region="europe-north1"
|
||||
# export TF_STATE_BUCKET="${PROJECT_ID}-tfstate" # GCS bucket for Terraform state
|
||||
# export TF_STATE_BUCKET="${PROJECT_ID}-tfstate"
|
||||
|
||||
# ── LiteLLM proxy (valgfritt) ─────────────────────────────────
|
||||
# export LITELLM_BASE_URL=""
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# VAUCO MASTERPLAN — Chris Christiansen
|
||||
|
||||
**Sist oppdatert: 2026-05-23 CEST**
|
||||
**Status: Repo ferdig — GCP gjenstår (A4–A8 neste)**
|
||||
**Sist oppdatert: 2026-05-24 CEST**
|
||||
**Status: Repo ferdig — GCP gjenstår (A4–A9 neste)**
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -21,6 +21,22 @@ Du er første kunde. Når det virker for deg → selg det til andre.
|
|||
|
||||
---
|
||||
|
||||
## AGENT-IDENTITET
|
||||
|
||||
| Identitet | E-post | Rolle | Formål |
|
||||
|---|---|---|---|
|
||||
| Eier / admin | `chris.christiansen@vauco.no` | `billing.admin` + `billing.viewer` | Full kontroll |
|
||||
| Agent (OPAX) | `jason.vauger@vauco.no` | `billing.viewer` | Hente og rapportere kostnadsdata autonomt |
|
||||
| Fremtidig gruppe | `billing@vauco.no` | `billing.viewer` (Fase C) | Delt innboks for team og kunder |
|
||||
|
||||
**Agent-kapabiliteter med `billing.viewer`:**
|
||||
- Svare på «Hva koster dette prosjektet denne måneden?»
|
||||
- Sende ukentlig kostnadsrapport til chat-appen
|
||||
- Reagere på Pub/Sub budget-alerts (via `10-cost-guard.sh`)
|
||||
- **Ikke:** endre IAM, budsjetter eller koble prosjekter
|
||||
|
||||
---
|
||||
|
||||
## CLOUD SHELL QUICK-START (kopi-klipp)
|
||||
|
||||
> Bruk Cloud Shell: https://shell.cloud.google.com
|
||||
|
|
@ -46,16 +62,17 @@ bash infrastructure/00-authcheck.sh
|
|||
bash infrastructure/01-setupenv.sh
|
||||
bash infrastructure/07-rag-setup.sh
|
||||
# *** Kopier RAG_CORPUS_NAME fra output inn i .env ***
|
||||
nano .env # Legg til: export RAG_CORPUS_NAME="..."
|
||||
nano .env
|
||||
source .env
|
||||
|
||||
bash infrastructure/08-memorybank-setup.sh
|
||||
# *** Kopier MEMORY_ENGINE_NAME fra output inn i .env ***
|
||||
nano .env # Legg til: export MEMORY_ENGINE_NAME="..."
|
||||
nano .env
|
||||
source .env
|
||||
|
||||
bash infrastructure/05-cloudrun-deploy.sh
|
||||
bash infrastructure/04-observability-setup.sh
|
||||
bash infrastructure/11-billing-iam-hardening.sh
|
||||
|
||||
# Om kvelden (OBLIGATORISK — unngå 24/7-fakturering):
|
||||
bash infrastructure/03-teardown.sh
|
||||
|
|
@ -77,6 +94,7 @@ bash infrastructure/03-teardown.sh
|
|||
SUBAGENT_MODEL=gemini-2.0-flash
|
||||
[ ] A2 — bash infrastructure/00-authcheck.sh
|
||||
[ ] A3 — bash infrastructure/01-setupenv.sh
|
||||
Oppretter: budsjetter ($75 dev + $500 prod), Pub/Sub topic
|
||||
[ ] A4 — bash infrastructure/07-rag-setup.sh
|
||||
OQ-02: Script faller automatisk tilbake til us-east1 om nødvendig
|
||||
ACTION: Kopier RAG_CORPUS_NAME til .env
|
||||
|
|
@ -86,6 +104,10 @@ bash infrastructure/03-teardown.sh
|
|||
[ ] A6 — bash infrastructure/05-cloudrun-deploy.sh
|
||||
[ ] A7 — bash infrastructure/04-observability-setup.sh
|
||||
[ ] A8 — bash infrastructure/03-teardown.sh (kjør hver kveld)
|
||||
[ ] A9 — bash infrastructure/11-billing-iam-hardening.sh
|
||||
Gir billing.viewer til: chris.christiansen@vauco.no + jason.vauger@vauco.no
|
||||
Løser GCP billing health-advarsel: "0 billing account viewers"
|
||||
Fjerner billing.creator fra domenet (hvis ORG_DOMAIN er satt i .env)
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -103,7 +125,11 @@ bash infrastructure/03-teardown.sh
|
|||
Fyll inn GITHUB_APP_INSTALLATION_ID i .env
|
||||
[ ] B3 — bash infrastructure/06-cicd-setup.sh
|
||||
OQ-04: LØST — Cloud Build 2nd gen, ingen manuell OAuth i Console
|
||||
Bruker: gcloud builds connections create github (programmatisk)
|
||||
[ ] B4 — Legg til webhook URL i Secret Manager:
|
||||
gcloud secrets create webhook-url --data-file=<(echo -n "https://DIN-WEBHOOK-URL")
|
||||
Se: infrastructure/notifications/webhook-setup.md
|
||||
[ ] B5 — bash infrastructure/10-cost-guard.sh
|
||||
Aktiverer auto-teardown Cloud Function + chat-varsling ved budsjett-overskridelse
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -119,7 +145,11 @@ bash infrastructure/03-teardown.sh
|
|||
Terraform-variabler: customer_id, customer_project_id, customer_region
|
||||
State-backend: GCS bucket (TF_STATE_BUCKET i .env)
|
||||
[ ] C2 — Pakk `vauco-os` som kundeflate
|
||||
[ ] C3 — Første kunde: Medioteq
|
||||
[ ] C3 — Opprett billing@vauco.no som Google Group
|
||||
Legg inn: chris.christiansen@vauco.no + jason.vauger@vauco.no
|
||||
Oppdater .env: BILLING_VIEWER_EMAILS="billing@vauco.no"
|
||||
Kjør på nytt: bash infrastructure/11-billing-iam-hardening.sh
|
||||
[ ] C4 — Første kunde: Medioteq
|
||||
Region: europe-north1, separat GCP-prosjekt
|
||||
Kjør: terraform apply -var="customer_id=medioteq"
|
||||
```
|
||||
|
|
@ -131,15 +161,17 @@ bash infrastructure/03-teardown.sh
|
|||
| Script | Rolle | Status |
|
||||
|--------|-------|--------|
|
||||
| `00-authcheck.sh` | Verifiser gcloud-innlogging | Klar |
|
||||
| `01-setupenv.sh` | Aktiver APIs, SA, IAM, budsjett | Klar |
|
||||
| `01-setupenv.sh` | Aktiver APIs, SA, IAM, budsjetter ($75+$500), Pub/Sub | Klar |
|
||||
| `02-deploy.sh` | IAP-deploy på eget domene | Klar |
|
||||
| `03-teardown.sh` | Riv ned Cloud Run | Klar |
|
||||
| `04-observability-setup.sh` | Monitoring + alerting | Klar |
|
||||
| `05-cloudrun-deploy.sh` | ADK-agent til Cloud Run | Klar |
|
||||
| `06-cicd-setup.sh` | GitHub → Cloud Build **2nd gen** | **Oppdatert** |
|
||||
| `06-cicd-setup.sh` | GitHub → Cloud Build **2nd gen** | Oppdatert |
|
||||
| `07-rag-setup.sh` | RAG Engine corpus + fallback | Oppdatert |
|
||||
| `08-memorybank-setup.sh` | Memory Bank + auto-install | Oppdatert |
|
||||
| `09-cost-check.sh` | Kostnadsoversikt + Artifact Registry | Klar |
|
||||
| `10-cost-guard.sh` | Cloud Function auto-teardown + webhook-alert | **Ny** |
|
||||
| `11-billing-iam-hardening.sh` | Billing IAM: viewer-roller + fjern domain Creator | **Ny** |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -166,7 +198,6 @@ bash infrastructure/03-teardown.sh
|
|||
| Medioteq-type (klinisk, compliance) | ~$220-350 |
|
||||
|
||||
Breakeven: 1 kunde til $300-500/mnd dekker alle kostnader.
|
||||
Ikke bygg kost-analyse-system nå — spør agenten når GCP er oppe.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -182,13 +213,15 @@ Ikke bygg kost-analyse-system nå — spør agenten når GCP er oppe.
|
|||
| OQ-06 | Memory Bank auto-discovery | Eksplisitt env var |
|
||||
| OQ-07 | Monitoring email flag-format | Teste i dev |
|
||||
| OQ-08 | VPC connector e2-micro regional | Default us-central1 |
|
||||
| OQ-09 | GCP billing: 0 viewers | **LØST** — `11-billing-iam-hardening.sh` |
|
||||
| OQ-10 | GCP billing: Creator på domenet | **LØST** — fjernes når ORG_DOMAIN er satt |
|
||||
|
||||
---
|
||||
|
||||
## TERRAFORM-VEIKART (Fase C)
|
||||
|
||||
Terraform introduseres **ikke** for nåværende infra — gcloud-scripts er tilstrekkelig
|
||||
når vi opererer med ett GCP-prosjekt. Terraform blir relevant ved kunde-onboarding:
|
||||
Terraform introduseres **ikke** for nåværende infra — gcloud-scripts er tilstrekkelig.
|
||||
Terraform blir relevant ved kunde-onboarding:
|
||||
|
||||
| Når | Hva |
|
||||
|---|---|
|
||||
|
|
@ -198,7 +231,7 @@ når vi opererer med ett GCP-prosjekt. Terraform blir relevant ved kunde-onboard
|
|||
| State-backend | GCS bucket (`TF_STATE_BUCKET`) — én bucket, én state-fil per kunde |
|
||||
| Fase D | Terraform Cloud for sentralisert state og CI/CD på tvers av kunder |
|
||||
|
||||
Terraform-ressurser som er aktuelle:
|
||||
Terraform-ressurser:
|
||||
- `google_cloudbuildv2_connection` — programmatisk GitHub-kobling per kunde
|
||||
- `google_cloudbuildv2_repository` — repo-link
|
||||
- `google_cloudbuild_trigger` — push-til-main trigger
|
||||
|
|
|
|||
104
infrastructure/11-billing-iam-hardening.sh
Normal file
104
infrastructure/11-billing-iam-hardening.sh
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
#!/usr/bin/env bash
|
||||
# 11-billing-iam-hardening.sh — GCP Billing Account Health fixes
|
||||
#
|
||||
# Løser to offisielle GCP-advarsler:
|
||||
# 1. "0 billing account viewers" — gir billing.viewer til spesifiserte brukere
|
||||
# 2. "Billing Account Creator rolle på for domenet" — fjerner domain-wide Creator
|
||||
#
|
||||
# Agent-identitet: jason.vauger@vauco.no får billing.viewer
|
||||
# slik at agenten kan hente og rapportere kostnadsdata autonomt.
|
||||
#
|
||||
# Krav: du må være Billing Account Administrator for å kjøre dette.
|
||||
# Source .env før kjøring: source .env
|
||||
set -euo pipefail
|
||||
|
||||
: "${BILLING_ACCOUNT_ID:?Set BILLING_ACCOUNT_ID i .env}"
|
||||
: "${ALERT_EMAIL:?Set ALERT_EMAIL i .env}"
|
||||
|
||||
# Brukere som får billing.viewer — kan overstyres i .env
|
||||
BILLING_VIEWER_EMAILS="${BILLING_VIEWER_EMAILS:-chris.christiansen@vauco.no,jason.vauger@vauco.no}"
|
||||
|
||||
# Google Workspace / Cloud Identity domene (kun nødvendig ved org-oppsett)
|
||||
ORG_DOMAIN="${ORG_DOMAIN:-}"
|
||||
|
||||
echo "=== 11: Billing IAM Hardening ==="
|
||||
echo " Billing Account: ${BILLING_ACCOUNT_ID}"
|
||||
|
||||
bash "$(dirname "$0")/00-authcheck.sh"
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# FIX 1: billing.viewer til agent-identitet og eier
|
||||
# ----------------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- Fix 1: Billing Account Viewer ---"
|
||||
echo " Gir lesetilgang til: ${BILLING_VIEWER_EMAILS}"
|
||||
echo " Formål: agenten (jason.vauger) kan hente kostnadsdata autonomt;"
|
||||
echo " chris får eksplisitt viewer i tillegg til admin."
|
||||
|
||||
IFS=',' read -ra VIEWER_LIST <<< "${BILLING_VIEWER_EMAILS}"
|
||||
for EMAIL in "${VIEWER_LIST[@]}"; do
|
||||
EMAIL=$(echo "${EMAIL}" | xargs)
|
||||
[[ -z "${EMAIL}" ]] && continue
|
||||
|
||||
if [[ "${EMAIL}" == *".gserviceaccount.com" ]]; then
|
||||
MEMBER="serviceAccount:${EMAIL}"
|
||||
else
|
||||
MEMBER="user:${EMAIL}"
|
||||
fi
|
||||
|
||||
gcloud billing accounts add-iam-policy-binding "${BILLING_ACCOUNT_ID}" \
|
||||
--member="${MEMBER}" \
|
||||
--role="roles/billing.viewer" --quiet
|
||||
echo "✓ billing.viewer gitt til: ${EMAIL}"
|
||||
done
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# FIX 2: Fjern billing.creator fra domenet
|
||||
# ----------------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- Fix 2: Fjern Billing Account Creator fra domenet ---"
|
||||
|
||||
if [[ -z "${ORG_DOMAIN}" ]]; then
|
||||
echo "⚠️ ORG_DOMAIN er ikke satt — hopper over."
|
||||
echo " Sett i .env: export ORG_DOMAIN=\"vauco.no\" og kjør på nytt."
|
||||
echo " (Kun nødvendig om vauco.no er koblet som Google Workspace-org i GCP)"
|
||||
else
|
||||
DOMAIN_MEMBER="domain:${ORG_DOMAIN}"
|
||||
|
||||
EXISTING=$(gcloud billing accounts get-iam-policy "${BILLING_ACCOUNT_ID}" \
|
||||
--format=json 2>/dev/null \
|
||||
| python3 -c "
|
||||
import sys, json
|
||||
policy = json.load(sys.stdin)
|
||||
for b in policy.get('bindings', []):
|
||||
if b.get('role') == 'roles/billing.creator' and '${DOMAIN_MEMBER}' in b.get('members', []):
|
||||
print('found')
|
||||
break
|
||||
" 2>/dev/null || echo "")
|
||||
|
||||
if [[ "${EXISTING}" == "found" ]]; then
|
||||
gcloud billing accounts remove-iam-policy-binding "${BILLING_ACCOUNT_ID}" \
|
||||
--member="${DOMAIN_MEMBER}" \
|
||||
--role="roles/billing.creator" --quiet
|
||||
echo "✓ roles/billing.creator fjernet fra domain:${ORG_DOMAIN}"
|
||||
else
|
||||
echo "✓ roles/billing.creator var ikke tildelt domain:${ORG_DOMAIN} — ingen endring"
|
||||
fi
|
||||
fi
|
||||
|
||||
# ----------------------------------------------------------------
|
||||
# Vis nåværende billing IAM-policy
|
||||
# ----------------------------------------------------------------
|
||||
echo ""
|
||||
echo "--- Nåværende Billing Account IAM (etter endringer) ---"
|
||||
gcloud billing accounts get-iam-policy "${BILLING_ACCOUNT_ID}" \
|
||||
--format="table(bindings.role,bindings.members)" 2>/dev/null || true
|
||||
|
||||
echo ""
|
||||
echo "=== 11: Billing IAM Hardening COMPLETE ==="
|
||||
echo " Verifiser i GCP Console:"
|
||||
echo " https://console.cloud.google.com/billing/${BILLING_ACCOUNT_ID}/manage"
|
||||
echo ""
|
||||
echo " Fremtidig: opprett billing@vauco.no som Google Group,"
|
||||
echo " legg chris + jason inn i gruppa, og erstatt enkeltadressene med:"
|
||||
echo " export BILLING_VIEWER_EMAILS=\"billing@vauco.no\""
|
||||
Loading…
Reference in New Issue
Block a user