# GCP Observatory Read Adapter ## Definition of Working - Working target: an authenticated GCP staging API returns one canonical claim with source/evidence provenance and a separately labeled proposal ledger. - Operator path: `GET /v1/claims/sample` or `GET /v1/claims/{uuid}` with the server-only `X-Api-Key` value. - Done means: the response names `teleo_canonical`, the dedicated IAM database principal and `kb_observatory_read`, reports a read-only transaction and denied write privileges, and live anonymous/write HTTP attempts return `401`/`405`. - Not done: the VPS `teleo-pg`, a public Cloud SQL address, a browser-visible key, a mock-only receipt, or a production Vercel repoint. - Required tier: `T3_live_readonly`. ## Existing Connector Boundary The current `living-ip/livingip-web` main branch reads claims through `src/lib/api.ts`. It selects `NEXT_PUBLIC_API_URL` and otherwise falls back to `http://77.42.65.182:8081`, then calls the legacy `/api/claims` routes. That is the VPS-local/public Observatory path. It is not safe to replace that public environment variable with this protected API: the response shape differs and the adapter key must never enter a `NEXT_PUBLIC_` variable or browser bundle. The existing Teleo route `GET /api/kb/claims` is the compatibility reference for route-scoped authentication, but its default database/container settings still describe the VPS-local process. This service is a separate GCP runtime; it does not change Argus or PR #148's Leo runtime files. ## Runtime Contract - Cloud Run service: `observatory-read-adapter-staging` in `europe-west6`. - Direct VPC egress: `teleo-staging-net` / `teleo-staging-europe-west6`. - Cloud SQL: `teleo-501523:europe-west6:teleo-pgvector-standby`, private IP. - Database: `teleo_canonical` only. - Runtime identity: `sa-observatory-read-adapter@teleo-501523.iam.gserviceaccount.com`. - IAM database user: `sa-observatory-read-adapter@teleo-501523.iam`. - Database authorization role: `kb_observatory_read` (`NOLOGIN`). - API authentication: route-scoped key from Secret Manager secret `observatory-read-api-key-staging`; the value is not in Git or deploy logs. - No mutation routes exist. Authenticated unsupported methods return `405`. The Cloud SQL Python Connector uses Application Default Credentials from the Cloud Run service identity, automatic IAM database authentication, and private IP. Every request starts a read-only transaction and refuses the response if the database, IAM principal, authorization membership, required reads, or effective write-denial checks drift. ## One-Time Staging Bootstrap These are staging mutations. Run them only with an authenticated GCP operator; they do not route production traffic. 1. Create the dedicated runtime service account and grant only `roles/cloudsql.client` and `roles/cloudsql.instanceUser` in project `teleo-501523`. 2. Add the service account as a Cloud SQL IAM service-account user on `teleo-pgvector-standby`. 3. From the existing private GCP VM database-admin path, run `ops/observatory_read_role.sql` against `teleo_canonical` with `OBSERVATORY_DB_IAM_USER=sa-observatory-read-adapter@teleo-501523.iam`. Do not read, copy, or retain the administrator password. 4. Create `observatory-read-api-key-staging`, add a generated 32-byte-or-longer value through stdin, and grant that secret's accessor role only to the runtime service account and the bounded staging canary identity. 5. Dispatch `.github/workflows/gcp-observatory-read-adapter.yml` with `action=deploy_staging` from the exact reviewed branch revision. The workflow builds an immutable image, deploys at most two Cloud Run instances, and retains the positive response plus anonymous `401` and authenticated POST `405` receipts. It does not modify Vercel. ## Unexecuted Cutover Packet Production cutover requires a separate exact authorization and a `living-ip/livingip-web` change. Do not execute these steps from this lane. 1. Add server-only Vercel secrets `OBSERVATORY_CANONICAL_API_URL` and `OBSERVATORY_CANONICAL_API_KEY` to a protected preview environment. The URL targets the GCP service; neither setting may use `NEXT_PUBLIC_`. 2. Add a Next.js server route or server action that calls the GCP API, validates `livingip.observatory-canonical-claim.v1`, and maps it to the Observatory UI. The browser calls only the same-origin Next.js route. 3. Prove preview Deployment Protection, anonymous denial, source/evidence rendering, proposal/live labels, and no browser key exposure. 4. Obtain exact production-repoint authorization naming the reviewed `livingip-web` commit and Vercel project before changing production values. ## Unexecuted Rollback Packet 1. Revert the authorized `livingip-web` connector commit or disable its server-side feature flag. 2. Restore the prior production Vercel values and redeploy the last accepted production revision. 3. Verify `/claims` again uses the prior `/api/claims` contract. 4. Leave the private Cloud SQL instance and adapter role intact while receipts are reviewed; scale the staging Cloud Run service to zero if isolation is required. 5. Delete the staging service/role/secret only under a separate cleanup decision. Rollback never adds a Cloud SQL public IP and never redirects the adapter to VPS `teleo-pg`.