---
title: "Development Environment"
slug: gcp-env-development
section: GCP Infrastructure
status: stable
description: "The Development environment is the GCP project `skilled-script-469819-f2` (project number 382570452229)."
last-updated: 2026-10-07
---

# Development Environment

## Purpose and scope

The Development environment is the GCP project `skilled-script-469819-f2` (project number 382570452229). It runs the Globus development cluster, the Applicant Portal and Host Portal development services, the n8n development and sandbox instances, and a group of automation agents. Its Terraform lives in `environments/development` of the `alliance-gcp-infra` repo, with state in the GCS bucket `dev-tfstate-skilled-script-469819-f2` (prefix `alliance-gcp-infra`, `environments/development/backend.tf`).

Development is the first step of the promotion path `development` -> `QA` -> `prod` (there is no staging environment). See `/docs/gcp-env-qa` and `/docs/gcp-env-production` for the other two, `/docs/gcp-overview` for the whole estate, and `/docs/dev-only-deployment-policy` for which repos and services are intentionally dev-only.

## What runs here

From the live snapshot (read through the gateway, names only):

- **GKE:** one Autopilot cluster, `globus-cluster-development`, in `us-central1`, release channel REGULAR. Terraform declares Workload Identity bindings for the `n8n-dev` and `n8n-sandbox` namespaces, each backed by its own Cloud SQL Postgres instance (`n8n-db-dev`, `n8n-db-sandbox`) and runtime service account (`n8n-runtime-dev`, `n8n-runtime-sandbox`); namespace contents were not read (see Known gaps). The apply workflow fetches GKE credentials so that the n8n credential-sync and sandbox baseline-deploy provisioners can run after apply, and mints a GitHub App token to clone `n8n-workflows` for the sandbox baseline deploy.
- **Cloud Run in `northamerica-northeast1`:** the Applicant Portal pieces (Keycloak, participant server and client, drizzle-migrator job) and the Host Portal client and server, behind VPC connectors (`default-net-connect`, `host-portal-connect`).
- **Cloud Run in `us-central1`:** the agent fleet (bug-diagnosis, docs-update, gke-workload-health, openstatus-alert, pr-latency, pr-review-eligibility, secrets-drift, user-addition) and `gcp-mcp-server`, plus `wildpacks-development` and the three pool slots of the branching sandbox.
- **Data:** Cloud SQL instances for Globus, MCP, n8n, the Applicant Portal, Keycloak and others; two BASIC-tier Redis instances; Firestore databases for several agents; GCS buckets for documents, photos and branding assets; and a large Secret Manager inventory.
- **Artifact Registry** repositories in `us-central1`, `us-east1` and `northamerica-northeast1`, and Cloud Build triggers for the portal repos.

The environment also holds references to other environments by name: buckets named `globus-documents-prod`, `globus-profile-photos-prod` and `globus-vertex-agent-prod` are declared here, and IAM grants exist for service accounts of `production-499116` and `quality-assurance-496022`. Terraform also grants the `alliance-platform-services` service account `environment-index-sa` read-only access here: `roles/run.viewer` on the project (`google_project_iam_member.environment_index_platform_sa_run_viewer`), used to list Cloud Run services and show which branch holds each pooled slot, `roles/container.viewer` on the project (`google_project_iam_member.environment_index_platform_sa_container_viewer`), a read-only grant used to read the deploy allocator's lease for the Globus GKE pool from labels on the `globus-<env>-N` namespaces, and `roles/secretmanager.secretAccessor` on the `github-agent-workflow-app-id` and `github-agent-workflow-app-private-key` secrets, from which environment-index mints read-only `alliance-agent-workflow` GitHub App installation tokens at runtime. Terraform also grants the `alliance-platform-agents` service account `atlas-agent-sa` `roles/secretmanager.secretAccessor` on the `atlas-agent-gateway-pat` secret; the atlas-agent Cloud Run service in `alliance-platform-agents` reads its gateway robot PAT from this project. See `/docs/gcp-iam-and-workload-identity` and `/docs/gcp-secrets-and-data-stores`.

## How changes are deployed

There are three separate deployment paths, and only the first is Terraform:

1. **Infrastructure:** `terraform-apply-dev` (`.github/workflows/terraform-apply-dev.yml`) runs on every push to `main` that touches `environments/development/**` or `modules/**`, and on manual dispatch with an optional `targets` list for a scoped `-target` apply. It authenticates through the WIF pool `github-actions-apply-dev` as `terraform-tf@skilled-script-469819-f2`, locked to `refs/heads/main` of the infra repo. Pull requests are handled by the separate `terraform-plan-pr` workflow (plan only). Workflow details are on `/docs/gcp-terraform-workflows`.
2. **Applications:** portal and Globus images are built and rolled out by each application repo's own CI (GitHub Actions or Cloud Build triggers), not by Terraform. PPPToo also has an opt-in Google Cloud Deploy pilot: Terraform declares the delivery pipeline `ppp2-cloud-deploy-pipeline` in `northamerica-northeast1` with two targets, `ppp2-dev` (Skaffold profile `server`) and `ppp2-dev-client` (profile `client`), both executing as `ppp2-deployer`. There are two targets because Cloud Deploy allows exactly one Cloud Run service per target. PPPToo's `cloud-deploy-dev.yml` is manual (`workflow_dispatch` only); `deploy-dev.yml` remains the live pipeline on every push to `development`. See `/docs/onboarding-cicd-deployment` and `/docs/git-branching-release-model`.
3. **Agents and `gcp-mcp-server`:** deployed outside Terraform (see the drift section below). How they are deployed was not verified from the sources (no pipeline for them is declared in `environments/development`).
4. **n8n:** the `n8n-dev` instance (namespace `n8n-dev`) has two cooperating paths. Workflow definitions are deployed by `n8n-workflows`' `deploy-dev.yml`, which runs after "Export Dev Workflows" completes on `development` (or by manual dispatch), authenticates through the WIF pool `github-actions-n8n-wf` as `n8n-deploy-ci-dev` (trust limited to the `Alliance-Strategies/n8n-workflows` repo, project role `roles/container.developer`) and reaches n8n with `kubectl port-forward`. Terraform covers what n8n's public REST API cannot: `null_resource.n8n_workflow_sync_dev` runs `n8n-sync/sync-n8n-credentials.js` against the in-cluster n8n CLI to import credentials (values resolved from Secret Manager) and activate the deployed workflows. The sandbox instance (namespace `n8n-sandbox`) is seeded by Terraform: `null_resource.n8n_sandbox_credential_sync` then `null_resource.n8n_baseline_deploy_sandbox` (`deploy-n8n-baseline.cjs`, which creates only missing workflows from the curated manifest in `n8n-sync-sandbox/`). Both provisioners shell out to `kubectl`/`node` and so depend on the credential steps in the apply workflow. The static global address `n8n-development2-ip` is reserved for the n8n-dev instance's public ingress hostname `development2.n8n.allianceabroad.com`; the sandbox instance uses `n8n-sandbox-ip` for `sandbox.n8n.allianceabroad.com`. DNS for `allianceabroad.com` is on GoDaddy, not Cloud DNS.

## Operating notes

- The apply has a destroy circuit breaker: `DESTROY_THRESHOLD` is 3 here. `terraform plan` runs first; a plan error or more than 3 proposed destroys fails the job before apply, and a human must review and apply by hand.
- Concurrency group `terraform-apply-development` queues runs instead of cancelling them, so quick successive merges do not race on state.
- The job refuses to run if the repo secret `DEV_DRIZZLE_MIGRATOR_JOB_ARGS` is missing, because an empty value would blank the live drizzle-migrator job arguments.
- A large block of `drift-reconciliation-*.tf` and `decommission-legacy-mcp-services.tf` files records resources that were imported or deliberately removed. Read these before assuming a resource is unmanaged or gone. For example, `globus-webhook-secret` was created live with `gcloud`, is declared in `module.secrets_bulk_development` and is imported by `drift-reconciliation-2026-10-05-globus-webhook-secret.tf`; Terraform never manages its secret value. The `atlas-agent-gateway-pat` secret container was likewise created live with `gcloud` and declared in `module.secrets_bulk_development`; `atlas-agent-gateway-pat-import.tf` adopts it with an `import` block. The import changes no live resource and never touches the secret value.
- New secrets in this project use the short-name convention with no environment token (for example `globus-google-maps-api-key`), because dev, QA and prod are separate projects. PR #114 renamed 39 legacy `globus-development-*` entries in `module.secrets_bulk_development` to `globus-*`; a few legacy ids remain in the list because a secret id is immutable. The `null_resource` cleanups in `decommission-legacy-mcp-services.tf` that use multi-line shell pin `interpreter = ["bash", "-c"]`, since Terraform defaults `local-exec` to `cmd.exe` on a Windows toolchain.
- Branching sandbox (`branching-sandbox.tf`): three pre-provisioned Cloud Run slots in `us-central1`, reserved per feature branch for 30 minutes, with their own WIF pool. The pool only trusts jobs from `feature/*` and `hotfix/*` branches that call the `Alliance-Strategies/branching-sandbox/.github/workflows/trusted-deploy-dev.yml@refs/heads/main` workflow. Slot labels, image and traffic are written by the sandbox repo's CI and must not be managed by Terraform. Domain mappings are not allowed in `northamerica-northeast1`, which is why the Cloud Run slots are in `us-central1`; the sandbox Artifact Registry repo stays in `northamerica-northeast1` (the module has `prevent_destroy`, so its region cannot move, and Cloud Run pulls the image cross-region). The custom hostnames `dev-1`, `dev-2` and `dev-3` under `sandbox.allianceabroad.com` are not managed by Terraform: creating a Cloud Run domain mapping needs a caller that is a verified owner of `allianceabroad.com`, which `terraform-tf` is not, so a verified human creates them with `gcloud beta run domain-mappings create`. DNS CNAMEs live at GoDaddy, and a `removed` block (with `destroy = false`) makes Terraform forget the old failed mapping entries without deleting anything.
- Host Portal dev pool (`host-portal-pool.tf`): `feature/**` pushes on `Alliance-Strategies/HostPortalPrototype` deploy a server+client pair to one of eighteen pre-provisioned slots (keys `1` to `18`) in `us-central1` (`host-portal-server-dev-N` and `host-portal-client-dev-N`). The dedicated deployer `hostportal-deployer-dev` can only be assumed through its own WIF pool `github-actions-hostportal`, from `feature/*` and `hotfix/*` refs of that repo running `trusted-deploy-dev.yml@refs/heads/main`. It has `roles/run.developer` on the pool services, project-wide `roles/run.viewer`, actAs on both runtime service accounts, writer on the existing `host-company-portal` repo in `us-east1`, and read access to the four build-time client secrets. Server slots run as `backend-service-potal` and client slots as `host-service-potal`; the client slots read `VITE_POSTHOG_KEY` as a secret-backed env var at container start. Terraform never manages labels, image, env or traffic on these services. Custom domains (`dev-N` and `dev-N-api` under `hosts.allianceabroad.com`) are not managed by Terraform and are created by hand with `gcloud beta run domain-mappings create`. The legacy dev pair (`host-company-portal-server`/`-client`) is untouched and stays the rollback path. The Host Portal deployers of all three environments (`hostportal-deployer-dev`, `-qa`, `-prod`) also have reader on this project's `globus-npm` repo, because the server image's `npm install` resolves `@alliance-strategies/globus-sdk` from it.
- Applicant Portal Keycloak slots (`applicant-keycloak-slots.tf` and `applicant-keycloak-slot-services.tf`): slot 1 is the existing `applicant-keycloak` service; dev pool slots 2 to 18 are separate Keycloak Cloud Run services named `applicant-keycloak-dev-<slot>` in `northamerica-northeast1`. Each slot has its own database `applicant_kc_dev_<slot>` on the `applicant-portal-db-development` instance and its own `applicant-kc-dev-<slot>-db-url` secret container (container only; the value is written out-of-band). Databases and these secret containers are declared for slots 2 to 18 (`applicant_kc_slots`); the slot services are gated separately by `applicant_kc_service_slots`. The slot services are copies of slot 1 apart from their own `KC_DB_URL` secret and `KC_DB_POOL_MAX_SIZE=15`. They reuse slot 1's DB username/password and Keycloak admin secrets, and have a public invoker like slot 1. Unlike slot 1, Terraform owns the image and volumes on the slot services (no `ignore_changes` on them); the Keycloak image deploy CI (`ppp2-deployer`) only targets `applicant-keycloak`, so a slot is refreshed by bumping the image digest in Terraform. Slot databases are filled from slot 1's database by a Cloud SQL export/import through the private bucket `applicant-kc-slot-copy-development` (public access prevention enforced, objects expire after one day). The `applicant-portal-db-development` instance's `max_connections` flag is 250 (raised from 100 on 2026-11-09 for 17 per-slot Keycloaks plus slot 1; earlier raised from 50 for the per-slot Keycloaks) and its tier is `db-custom-2-7680`; changing the flag restarts the instance.
- bop-front dev deploy identity (`bop-front.tf`): declares the Artifact Registry repo `bop-front`, a deployer service account (`module.bop_front_deployer_dev`) and the WIF pool `github-actions-bop-front`. The deployer is granted writer access on the `bop-front` repo; the GKE roles it previously held (`roles/container.developer` and the `gkehub` roles) were dropped on 2026-10-15 (ADR 0005). The deployer also has `roles/secretmanager.secretAccessor` on three build-time Vite secrets (`globus-vite-google-maps-api-key`, `globus-posthog-key` and `globus-development-posthog-host`), listed in `local.bop_front_build_secrets` and granted by `google_secret_manager_secret_iam_member.bop_front_deployer_dev_build_secrets`; the deployer reads them at image build. The pool's provider has an attribute condition that requires a `feature/` or `hotfix/` ref and a `job_workflow_ref` of `.github/workflows/trusted-deploy-dev.yml@refs/heads/main` in the `Alliance-Strategies/bop-front` repo.
- bop-front dev Cloud Run pool (`bop-front.tf`, ADR 0005): `google_cloud_run_v2_service.bop_front_pool` creates one service per key of `local.bop_front_slots` (`1`, `2`, `3`), named `bop-front-${local.bop_front_env}-${each.key}`, in `us-central1` (domain mappings are not allowed in `northamerica-northeast1`). Terraform creates them with the bootstrap `us-docker.pkg.dev/cloudrun/container/hello` image and a scaling range of 0 to 2 instances; CI (`trusted-deploy-dev.yml@main`) owns image, env, labels and traffic. The services run as the runtime service account `module.bop_front_runtime_dev`, which has no project roles and `roles/secretmanager.secretAccessor` on exactly the five secrets the BFF loads: the portal-owned `bop-front-globus-api-key` and `bop-front-session-jwt-secret` (secret containers only; values are added out of band) and three `globus-entra-*` secrets. Each pool service grants `allUsers` the `roles/run.invoker` role. The deployer service account has `roles/run.developer` on each pool service, project-wide `roles/run.viewer` (`gcloud run deploy` lists revisions project-wide before it writes) and `roles/iam.serviceAccountUser` on the runtime service account. The hostnames `dev-N.staff.allianceabroad.com` are mapped by `module.bop_front_dev_domain_mapping` (one per slot, through `modules/domain-mapping`, with `prevent_destroy`), because the Terraform service account is a verified owner of `allianceabroad.com`; the DNS CNAME `dev-N.staff` -> `ghs.googlehosted.com` exists.
- Globus dev pool slot databases (`globus-pool.tf`): each Globus pool slot has its own Cloud SQL instance, declared as `module.globus_db_dev_slot` (one per `local.globus_all_slots` key: the pool slots plus an `atlas` sandbox slot) and named `globus-db-${local.globus_pool_env}-${each.key}`. The instances are `POSTGRES_15` on tier `db-custom-2-7680` with deletion protection enabled. Each slot's database `globus_${local.globus_pool_env}_${each.key}` is created on that slot's own instance. `globus-db-development` keeps the legacy `globus_development` database. The pool has 18 slots, with keys `1` to `18`. The `atlas` slot is an Atlas sandbox outside the pool: it reuses the per-slot resources (own Cloud SQL instance, database and Workload Identity binding) with namespace `globus-dev-atlas` and host `dev-atlas.globus.allianceabroad.com`. Its host, namespace, Cloud SQL instance and database are exposed by the `globus_dev_atlas_sandbox` output. `globus-pool-import-2026-11-09.tf` is a one-time adoption file: its `import` blocks bring the live instances `globus-db-dev-16` and `globus-db-dev-18` into state at `module.globus_db_dev_slot["16"]` and `module.globus_db_dev_slot["18"]` (resource `google_sql_database_instance.this`), because an interrupted first apply of the pool growth did not record them.
- WIF subject bound (`wif-subject.tf`): Google IAM rejects a mapped `google.subject` larger than 127 bytes. The GitHub Actions pool providers declared in `bop-front.tf`, `branching-sandbox.tf`, `globus-pool.tf`, `host-portal-pool.tf`, `ppp2-pool.tf` and `wildpacks.tf` map `google.subject` to `local.wif_subject_bounded`. A subject of 127 bytes or less is mapped unchanged; otherwise it falls back to the repository plus the ref truncated at the first `-`.
- Agreements deployer self token binding (`agreements-service.tf`): `google_service_account_iam_member.agreements_deployer_self_id_token` grants the agreements deployer service account (`module.agreements_deployer`) `roles/iam.serviceAccountTokenCreator` on itself. The post-deploy smoke mints the deployer's own OIDC identity token with `gcloud auth print-identity-token --impersonate-service-account` on itself, with the slot URL as audience, because federated GitHub credentials cannot mint audience-bound tokens directly. `gcloud` impersonation mints an access token first, so the narrower `roles/iam.serviceAccountOpenIdTokenCreator` role was not enough. The member is the account itself, so no other principal gains anything.
- PartnerPortal sign-in configuration (`partner-portal-pool.tf`): Auth0 replaced Clerk on 2026-10-27, and the Auth0 values are public configuration, not secrets. The file sets `AUTH0_DOMAIN`, `AUTH0_CLIENT_ID` and `AUTH0_AUDIENCE` as env entries. Each slot has its own dedicated Auth0 tenant, replacing the shared `hostqa` app: `AUTH0_DOMAIN` and `AUTH0_CLIENT_ID` are read per slot from `local.partner_portal_auth0[each.key]`, and the development map has entries for slots `1` (`partner-dev-1.us.auth0.com`) and `2` (`partner-dev-2.us.auth0.com`). `AUTH0_AUDIENCE` is the same for every slot (`https://api.partnerportal`).
- Platform Pulse alert bridge (`monitoring-pulse-bridge.tf`, `monitoring-pulse-channel.tf`): the bridge is one Cloud Run service that receives incidents from a Pub/Sub push subscription and posts them to Platform Pulse. The service's image, env, secret binding and labels are owned by the deploy, and only the push identities may invoke it: Terraform grants `roles/run.invoker` on the service to the dev push identity, to the QA push identity (`monitoring-pulse-push-qa` in `quality-assurance-496022`) and to the production push identity (`monitoring-pulse-push-prod` in `production-499116`). In this project the topic is `monitoring-alerts-dev` and the notification channel is `google_monitoring_notification_channel.platform_pulse`; an alert policy in this root can notify Platform Pulse by listing that channel's id. The bridge's Cloud Run container limits are 1 CPU and 512Mi of memory.
- Apply identity KMS role (`main.tf`, `agreements-service-security.tf`): the apply identity (`module.terraform_tf_development`) is granted `roles/cloudkms.admin`, for key rings, crypto keys and key IAM for the agreements CMEK. The agreements key ring has `depends_on = [module.terraform_tf_development]`, so the ring is created after that binding exists.
- Agreements Cloud SQL CMEK successor (`agreements-service-security.tf`, `agreements-service.tf`): `google_kms_crypto_key.agreements_cloud_sql` is a symmetric, software-protected key named `cloud-sql` in the agreements key ring, rotating every 90 days (`7776000s`), with `prevent_destroy`. `google_kms_crypto_key_iam_member.agreements_cloud_sql_agent` grants `roles/cloudkms.cryptoKeyEncrypterDecrypter` on it to the project's Cloud SQL service agent (`service-<project number>@gcp-sa-cloud-sql.iam.gserviceaccount.com`). CMEK is set at instance creation only, so `module.agreements_db_cmek` creates a second instance, `agreements-db-${local.agreements_env}-2`, as the encrypted successor to the Google-managed original, with `encryption_key_name` set to that key. It is `POSTGRES_17` on tier `db-custom-1-3840` with point-in-time recovery and deletion protection enabled. Its `backup_retained_count` is 7, because Cloud SQL refuses a lower backup retention at creation and PITR keeps 7 days of transaction logs. The data and the new database-url secret version are handled out of band.
- Agreements events push subscription (`agreements-service.tf`): `module.agreements_events_topic` declares a push subscription named `agreements-events-${local.agreements_env}-hub` that delivers to `https://dev-1.globus.allianceabroad.com/api/internal/agreements/events`. It authenticates with an OIDC token for `module.agreements_events_push`, a dedicated service account with no project roles.
- Agreements artifacts read grant (`agreements-service.tf`): `google_storage_bucket_iam_member.globus_runtime_artifacts_read` grants `roles/storage.objectViewer` on the bucket `agreements-artifacts-${local.agreements_env}` to the `globus-dev-runtime` service account. The grant is read only; the agreements service alone writes to the bucket.
- Agreements slot Hub invoker grant (`agreements-service.tf`): `google_cloud_run_v2_service_iam_member.agreements_slot_hub_runtime_invoker` grants `roles/run.invoker` on each agreements slot service (one per `local.agreements_slots` key) to the `globus-dev-runtime` service account. The Globus Hub pool calls the service with a Google OIDC token for `AGREEMENTS_URL`.
- Agreements observability (`agreements-observability.tf`): `module.agreements_observability` (from `modules/agreements-observability`) provides log-based metrics, a `/readyz` uptime check, Platform Pulse alert policies, SLOs and a dashboard for the agreements-service dev slot. It covers one slot today (slot `1`) and notifies through `google_monitoring_notification_channel.platform_pulse`. The `agreements_dev_observability` output exposes the uptime check id, SLO names, alert policy names and dashboard id.
- Agreements Cloud Run scaling ignore (`agreements-service.tf`): the API reports a service-level `scaling` block (`manual_instance_count` / `min_instance_count = 0`) that the config never declares. `scaling` is added to the ignored attributes so that applies do not plan an in-place no-op update. Template scaling is still managed.
- Agreements rendering workers (`agreements-worker.tf`): `google_cloud_run_v2_service.agreements_worker` creates one Cloud Run service per `local.agreements_slots` key, named `agreements-worker-${local.agreements_env}-${each.key}`. Each worker runs with `SERVICE_ROLE=worker` while its slot runs `SERVICE_ROLE=api`, and the agreements-service rails deploy it next to each pool slot. It runs as `module.agreements_runtime` and is created with the `us-docker.pkg.dev/cloudrun/container/hello` image; CI owns the image, env and slot labels. The worker keeps one instance with the CPU never throttled, because background rendering needs the CPU between requests. It takes no traffic: it is IAM-gated and only the deployer's readiness probe (`scripts/smoke-ready.sh`) calls it, through `google_cloud_run_v2_service_iam_member.agreements_worker_deployer_invoker`. The `agreements_workers` output lists the worker service names.

_Terraform inventory generated from `alliance-gcp-infra` at commit `fc9bd1d`. Live snapshots: `skilled-script-469819-f2` read 2026-10-01. Snapshots hold names and a few stable attributes only, never secret values._

## Terraform-managed resources

Every module call and resource block under `environments/development` (174 in total), grouped by category.

### Identity and access (service accounts, IAM bindings, Workload Identity)

73 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `google_artifact_registry_repository_iam_member.gcp_connector_deployer_ar_reader` | `google_artifact_registry_repository_iam_member` | `roles/artifactregistry.reader -> serviceAccount:gcp-connector-deployer@alliance-mcp-services.iam.gserviceaccount.com` | `gcp-connector-deployer-ar-reader.tf:12` |
| `google_artifact_registry_repository_iam_member.globus_npm_host_portal_deployer_prod` | `google_artifact_registry_repository_iam_member` | `roles/artifactregistry.reader -> serviceAccount:host-portal-deployer@production-499116.iam.gserviceaccount.com` | `host-portal-deployer-globus-npm-access.tf:31` |
| `google_artifact_registry_repository_iam_member.sandbox_deployer_writer` | `google_artifact_registry_repository_iam_member` | `roles/artifactregistry.writer -> serviceAccount:${module.sandbox_deployer.email}` | `branching-sandbox.tf:187` |
| `google_cloud_run_service_iam_member.gke_workload_health_agent_n8n_runtime_dev_invoker` | `google_cloud_run_service_iam_member` | `roles/run.invoker -> serviceAccount:n8n-runtime-dev@${var.project_id}.iam.gserviceaccount.com` | `gke-workload-health-agent-run-invoker.tf:32` |
| `google_cloud_run_service_iam_member.gke_workload_health_agent_sys_n8n_invoker` | `google_cloud_run_service_iam_member` | `roles/run.invoker -> serviceAccount:sys-n8n-sa@alliance-platform-services.iam.gserviceaccount.com` | `gke-workload-health-agent-sys-n8n-invoker.tf:9` |
| `google_cloud_run_v2_service_iam_member.sandbox_deployer` | `google_cloud_run_v2_service_iam_member` | `google_cloud_run_v2_service.sandbox_web[each.key].name` (one per `for_each` key) | `branching-sandbox.tf:160` |
| `google_cloud_run_v2_service_iam_member.sandbox_public` | `google_cloud_run_v2_service_iam_member` | `google_cloud_run_v2_service.sandbox_web[each.key].name` (one per `for_each` key) | `branching-sandbox.tf:150` |
| `google_iam_workload_identity_pool_provider.sandbox` | `google_iam_workload_identity_pool_provider` | `GitHub` | `branching-sandbox.tf:72` |
| `google_iam_workload_identity_pool.sandbox` | `google_iam_workload_identity_pool` | `GitHub Actions (sandbox)` | `branching-sandbox.tf:65` |
| `google_org_policy_policy.allowed_policy_member_domains` | `google_org_policy_policy` | `projects/${data.google_project.this.number}/policies/iam.allowedPolicyMemberDomains` | `ci-failure-alert-agent-public-access.tf:31` |
| `google_project_iam_member.compute_default_development_roles` | `google_project_iam_member` | `each.value -> serviceAccount:382570452229-compute@developer.gserviceaccount.com` (one per `for_each` key) | `main.tf:659` |
| `google_project_iam_member.env_audit_agent_sa_cloudsql_viewer` | `google_project_iam_member` | `roles/cloudsql.viewer -> serviceAccount:env-audit-agent-sa@alliance-platform-agents.iam.gserviceaccount.com` | `env-audit-agent-sa-viewer-roles.tf:18` |
| `google_project_iam_member.env_audit_agent_sa_compute_viewer` | `google_project_iam_member` | `roles/compute.viewer -> serviceAccount:env-audit-agent-sa@alliance-platform-agents.iam.gserviceaccount.com` | `env-audit-agent-sa-viewer-roles.tf:24` |
| `google_project_iam_member.env_audit_agent_sa_secretmanager_viewer` | `google_project_iam_member` | `roles/secretmanager.viewer -> serviceAccount:env-audit-agent-sa@alliance-platform-agents.iam.gserviceaccount.com` | `env-audit-agent-sa-viewer-roles.tf:12` |
| `google_project_iam_member.github_actions_deploy_aiplatform_user` | `google_project_iam_member` | `roles/aiplatform.user -> serviceAccount:github-actions-deploy@skilled-script-469819-f2.iam.gserviceaccount.com` | `github-actions-deploy-aiplatform-user.tf:21` |
| `google_project_iam_member.human_and_cross_project_bindings_development` | `google_project_iam_member` | `each.value.role -> each.value.member` (one per `for_each` key) | `main.tf:686` |
| `google_project_iam_member.n8n_runtime_dev_compute_viewer` | `google_project_iam_member` | `roles/compute.viewer -> serviceAccount:n8n-runtime-dev@skilled-script-469819-f2.iam.gserviceaccount.com` | `cert-monitor-n8n-runtime-sa-compute-viewer.tf:10` |
| `google_project_iam_member.platform_hub_sa_cross_project` | `google_project_iam_member` | `each.value -> serviceAccount:platform-hub-sa@alliance-mcp-services.iam.gserviceaccount.com` (one per `for_each` key) | `main.tf:3052` |
| `google_project_iam_member.ppp2_deployer_clouddeploy_developer` | `google_project_iam_member` | `roles/clouddeploy.developer -> serviceAccount:${module.ppp2_deployer_development.email}` | `main.tf:503` |
| `google_project_iam_member.ppp2_deployer_clouddeploy_job_runner` | `google_project_iam_member` | `roles/clouddeploy.jobRunner -> serviceAccount:${module.ppp2_deployer_development.email}` | `main.tf:492` |
| `google_project_iam_member.ppp2_deployer_clouddeploy_releaser` | `google_project_iam_member` | `roles/clouddeploy.releaser -> serviceAccount:${module.ppp2_deployer_development.email}` | `main.tf:538` |
| `google_project_iam_member.ppp2_deployer_storage_admin` | `google_project_iam_member` | `roles/storage.admin -> serviceAccount:${module.ppp2_deployer_development.email}` | `main.tf:515` |
| `google_project_iam_member.sandbox_deployer_run_viewer` | `google_project_iam_member` | `roles/run.viewer -> serviceAccount:${module.sandbox_deployer.email}` | `branching-sandbox.tf:174` |
| `google_project_iam_member.security_agent_sa_cloudkms_viewer` | `google_project_iam_member` | `roles/cloudkms.viewer -> serviceAccount:security-agent-sa@alliance-platform-agents.iam.gserviceaccount.com` | `security-agent-sa-cloudkms-viewer.tf:13` |
| `google_project_iam_member.security_agent_sa_cloudsql_viewer` | `google_project_iam_member` | `roles/cloudsql.viewer -> serviceAccount:security-agent-sa@alliance-platform-agents.iam.gserviceaccount.com` | `security-agent-sa-cloudsql-viewer.tf:13` |
| `google_project_iam_member.terraform_tf_datastore_owner` | `google_project_iam_member` | `roles/datastore.owner -> serviceAccount:terraform-tf@${var.project_id}.iam.gserviceaccount.com` | `terraform-tf-datastore-owner.tf:11` |
| `google_project_iam_member.terraform_tf_role_admin` | `google_project_iam_member` | `roles/iam.roleAdmin -> serviceAccount:terraform-tf@${var.project_id}.iam.gserviceaccount.com` | `terraform-tf-role-admin.tf:9` |
| `google_secret_manager_secret_iam_member.n8n_workflows_sandbox_test_ci_api_key_accessor` | `google_secret_manager_secret_iam_member` | `globus-n8n-sandbox-api-key` | `n8n-workflows-sandbox-test-ci.tf:48` |
| `google_service_account_iam_member.n8n_runtime_dev_wi` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> serviceAccount:${var.project_id}.svc.id.goog[n8n-dev/n8n-ksa]` | `n8n-dev-standalone.tf:75` |
| `google_service_account_iam_member.n8n_runtime_sandbox_wi` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> serviceAccount:${var.project_id}.svc.id.goog[n8n-sandbox/n8n-ksa]` | `n8n-sandbox-standalone.tf:74` |
| `google_service_account_iam_member.n8n_workflows_dev_deploy_ci_wif` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/${module.wif_pool_github_actions_n8n_workflows.name}/attribute.repository/Alliance-Strategies/n8n-workflows` | `n8n-workflows-dev-deploy-ci.tf:53` |
| `google_service_account_iam_member.n8n_workflows_sandbox_test_ci_wif` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/${module.wif_pool_github_actions_n8n_workflows.name}/attribute.repository/Alliance-Strategies/n8n-workflows` | `n8n-workflows-sandbox-test-ci.tf:39` |
| `google_service_account_iam_member.platform_hub_sa_tc_manus` | `google_service_account_iam_member` | `roles/iam.serviceAccountTokenCreator -> serviceAccount:platform-hub-sa@alliance-mcp-services.iam.gserviceaccount.com` | `main.tf:3067` |
| `google_service_account_iam_member.ppp2_deployer_self_actas` | `google_service_account_iam_member` | `roles/iam.serviceAccountUser -> serviceAccount:${module.ppp2_deployer_development.email}` | `main.tf:526` |
| `google_service_account_iam_member.ppp2_e2e_wif_binding` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/projects/382570452229/locations/global/workloadIdentityPools/github-actions/attribute.repository/Alliance-Strategies/PPPToo` | `ppp2-e2e.tf:53` |
| `google_service_account_iam_member.sandbox_deployer_actas` | `google_service_account_iam_member` | `roles/iam.serviceAccountUser -> serviceAccount:${module.sandbox_deployer.email}` | `branching-sandbox.tf:181` |
| `google_service_account_iam_member.sandbox_deployer_wif` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/${google_iam_workload_identity_pool.sandbox.name}/attribute.repository/${local.sandbox_repo}` | `branching-sandbox.tf:91` |
| `google_service_account_iam_member.terraform_ci_viewer_dev_wif` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/${module.wif_pool_github_actions_iac_development.name}/attribute.repository/Alliance-Strategies/alliance-gcp-infra` | `ci-terraform-readonly.tf:54` |
| `google_service_account_iam_member.terraform_tf_apply_dev_wif` | `google_service_account_iam_member` | `roles/iam.workloadIdentityUser -> principalSet://iam.googleapis.com/${module.wif_pool_github_actions_apply_dev.name}/attribute.repository/Alliance-Strategies/alliance-gcp-infra` | `ci-terraform-apply.tf:48` |
| `google_storage_bucket_iam_member.globus_prod_runtime_profile_photos_prod_cross_project` | `google_storage_bucket_iam_member` | `roles/storage.objectViewer -> serviceAccount:globus-prod-runtime@production-499116.iam.gserviceaccount.com` | `globus-prod-runtime-photo-bucket-cross-project-access.tf:26` |
| `google_storage_bucket_iam_member.globus_prod_runtime_profile_photos_prod_cross_project_creator` | `google_storage_bucket_iam_member` | `roles/storage.objectCreator -> serviceAccount:globus-prod-runtime@production-499116.iam.gserviceaccount.com` | `globus-prod-runtime-photo-bucket-cross-project-access.tf:38` |
| `google_storage_bucket_iam_member.terraform_ci_viewer_dev_tfstate_lock` | `google_storage_bucket_iam_member` | `roles/storage.objectUser -> serviceAccount:${module.terraform_ci_viewer_dev.email}` | `ci-terraform-readonly.tf:67` |
| `module.applicant_service_sa_development` | `service-account` | `applicant-service-sa` | `main.tf:1984` |
| `module.backend_service_potal` | `service-account` | `backend-service-potal` | `main.tf:456` |
| `module.cloudbuild_dev` | `service-account` | `cloudbuild-dev` | `main.tf:339` |
| `module.docs_update_agent_sa` | `service-account` | `docs-update-agent-sa` | `docs-update-agent-service-account.tf:8` |
| `module.github_actions_deploy_development` | `service-account` | `github-actions-deploy` | `main.tf:317` |
| `module.gke_node_sa` | `service-account` | `gke-node-sa` | `main.tf:360` |
| `module.globus_dev_runtime` | `service-account` | `globus-dev-runtime` | `main.tf:415` |
| `module.globus_google_maps_distance_matrix_key` | `api-key` | `globus-google-maps-distance-matrix-server` | `globus-google-maps-distance-matrix-key.tf:42` |
| `module.host_service_potal` | `service-account` | `host-service-potal` | `main.tf:437` |
| `module.karin_db_proxy_dev` | `service-account` | `karin-db-proxy-dev` | `karin-db-proxy-sa.tf:20` |
| `module.localreplitserviceaccount` | `service-account` | `localreplitserviceaccount` | `main.tf:638` |
| `module.manus_agent_sa_development` | `service-account` | `manus-agent-sa` | `main.tf:270` |
| `module.n8n_gke_sa` | `service-account` | `n8n-gke-sa` | `main.tf:398` |
| `module.n8n_runtime_dev` | `service-account` | `n8n-runtime-dev` | `n8n-dev-standalone.tf:63` |
| `module.n8n_runtime_sandbox` | `service-account` | `n8n-runtime-sandbox` | `n8n-sandbox-standalone.tf:61` |
| `module.n8n_workflows_dev_deploy_ci` | `service-account` | `n8n-deploy-ci-dev` | `n8n-workflows-dev-deploy-ci.tf:40` |
| `module.n8n_workflows_sandbox_test_ci` | `service-account` | `n8n-sandbox-test-ci-dev` | `n8n-workflows-sandbox-test-ci.tf:26` |
| `module.nexus_hub_runtime_sa` | `service-account` | `nexus-hub-runtime-sa` | `main.tf:624` |
| `module.ppp2_deployer_development` | `service-account` | `ppp2-deployer` | `main.tf:473` |
| `module.ppp2_e2e` | `service-account` | `ppp2-e2e` | `ppp2-e2e.tf:23` |
| `module.sandbox_deployer` | `service-account` | `sandbox-deployer-dev` | `branching-sandbox.tf:55` |
| `module.sandbox_runtime` | `service-account` | `sandbox-runtime-dev` | `branching-sandbox.tf:46` |
| `module.terraform_ci_viewer_dev` | `service-account` | `terraform-ci-viewer-dev` | `ci-terraform-readonly.tf:41` |
| `module.terraform_tf_development` | `service-account` | `terraform-tf` | `main.tf:236` |
| `module.user_addition_agent_sa` | `service-account` | `user-addition-agent-sa` | `user-addition-agent-service-account.tf:10` |
| `module.wif_pool_github_actions_apply_dev` | `workload-identity-pool` | `github-actions-apply-dev` | `ci-terraform-apply.tf:25` |
| `module.wif_pool_github_actions_development` | `workload-identity-pool` | `github-actions` | `main.tf:2481` |
| `module.wif_pool_github_actions_iac_development` | `workload-identity-pool` | `github-actions-iac` | `ci-terraform-readonly.tf:19` |
| `module.wif_pool_github_actions_n8n_workflows` | `workload-identity-pool` | `github-actions-n8n-wf` | `n8n-workflows-dev-deploy-ci.tf:18` |
| `module.wif_pool_manus` | `workload-identity-pool` | `manus-pool` | `main.tf:2461` |
| `module.wildpacks_dev_runtime` | `service-account` | `wildpacks-dev-runtime` | `main.tf:593` |

### Secrets (Secret Manager containers)

14 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `module.globus_google_maps_distance_matrix_secret` | `secret-manager-secret` | `globus-google-maps-api-key` | `globus-google-maps-distance-matrix-key.tf:51` |
| `module.n8n_dev_db_password` | `secret-manager-secret` | `n8n-dev-db-password` | `n8n-dev-standalone.tf:39` |
| `module.n8n_dev_encryption_key` | `secret-manager-secret` | `n8n-dev-encryption-key` | `n8n-dev-standalone.tf:53` |
| `module.n8n_email_health_kc_admin_pass_qa` | `secret-manager-secret` | `n8n-dev-email-health-kc-admin-pass-qa` | `n8n-email-health-qa-probe-secrets.tf:24` |
| `module.n8n_email_health_n8n_api_key_qa` | `secret-manager-secret` | `n8n-dev-email-health-n8n-api-key-qa` | `n8n-email-health-qa-probe-secrets.tf:38` |
| `module.n8n_email_health_sendgrid_key_qa` | `secret-manager-secret` | `n8n-dev-email-health-sendgrid-key-qa` | `n8n-email-health-qa-probe-secrets.tf:13` |
| `module.n8n_globus_webhook_secret` | `secret-manager-secret` | `n8n-globus-webhook-secret` | `n8n-globus-webhook-secret.tf:25` |
| `module.n8n_sandbox_db_password` | `secret-manager-secret` | `n8n-sandbox-db-password` | `n8n-sandbox-standalone.tf:37` |
| `module.n8n_sandbox_encryption_key` | `secret-manager-secret` | `n8n-sandbox-encryption-key` | `n8n-sandbox-standalone.tf:51` |
| `module.ppp2_e2e_bot_password` | `secret-manager-secret` | `ppp2-e2e-bot-password` | `ppp2-e2e.tf:39` |
| `module.qa_agent_gateway_pat` | `secret-manager-secret` | `qa-agent-gateway-pat` | `pr-review-agent-and-qa-agent-gateway-pats.tf:22` |
| `module.secrets_bulk_development` | `secret-manager-secret-bulk` | `161 items: applicant-kc-admin, applicant-kc-admin-password, applicant-kc-db, ...` | `main.tf:2624` |
| `module.user_addition_agent_api_key` | `secret-manager-secret` | `user-addition-agent-api-key` | `user-addition-agent-secrets.tf:7` |
| `module.user_addition_agent_gateway_pat` | `secret-manager-secret` | `user-addition-agent-gateway-pat` | `user-addition-agent-secrets.tf:15` |

### Compute (Cloud Run, GKE, jobs, schedulers)

18 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `google_cloud_run_service.applicant_keycloak` | `google_cloud_run_service` | `applicant-keycloak` | `main.tf:1250` |
| `google_cloud_run_service.host_company_portal_client` | `google_cloud_run_service` | `host-company-portal-client` | `main.tf:1369` |
| `google_cloud_run_service.host_company_portal_server` | `google_cloud_run_service` | `host-company-portal-server` | `main.tf:1487` |
| `google_cloud_run_service.ppp2_participant_client_development` | `google_cloud_run_service` | `ppp2-participant-client` | `main.tf:1750` |
| `google_cloud_run_service.ppp2_participant_server_development` | `google_cloud_run_service` | `ppp2-participant-server` | `main.tf:1823` |
| `google_cloud_run_service.wildpacks_development` | `google_cloud_run_service` | `wildpacks-development` | `main.tf:1151` |
| `google_cloud_run_v2_service.sandbox_web` | `google_cloud_run_v2_service` | `sandbox-web-${local.sandbox_env}-${each.key}` (one per `for_each` key) | `branching-sandbox.tf:98` |
| `module.drizzle_migrator_development` | `cloud-run-job` | `drizzle-migrator` | `main.tf:1996` |
| `module.globus_cluster_development` | `gke-autopilot-cluster` | `globus-cluster-development` | `main.tf:921` |
| `module.globus_npe_migration` | `cloud-run-job` | `globus-npe-migration` | `main.tf:2014` |
| `null_resource.delete_orphaned_asana_mcp_gke_workload` | `null_resource` |  | `decommission-legacy-mcp-services.tf:81` |
| `null_resource.delete_orphaned_globus_mcp_cloud_run` | `null_resource` |  | `decommission-legacy-mcp-services.tf:23` |
| `null_resource.delete_orphaned_mcp_dev_secrets` | `null_resource` |  | `decommission-legacy-mcp-services.tf:57` |
| `null_resource.delete_orphaned_nexus_hub_cloud_run` | `null_resource` |  | `decommission-legacy-mcp-services.tf:41` |
| `null_resource.delete_orphaned_openstatus_mcp_gke_workload` | `null_resource` |  | `decommission-legacy-mcp-services.tf:103` |
| `null_resource.n8n_baseline_deploy_sandbox` | `null_resource` |  | `main.tf:1001` |
| `null_resource.n8n_sandbox_credential_sync` | `null_resource` |  | `main.tf:981` |
| `null_resource.n8n_workflow_sync_dev` | `null_resource` |  | `main.tf:957` |

### Data stores (Cloud SQL, Redis, Firestore, Cloud Storage)

28 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `module.applicant_portal_db_development` | `cloud-sql-postgres` | `applicant-portal-db-development` | `main.tf:779` |
| `module.bucket_applicant_portal_documents_development` | `storage-bucket` | `applicant-portal-documents-development` | `main.tf:2142` |
| `module.bucket_applicant_portal_photos_development` | `storage-bucket` | `applicant-portal-photos-development` | `main.tf:2153` |
| `module.bucket_development_globus_branding_assets` | `storage-bucket` | `development-globus-branding-assets` | `main.tf:2164` |
| `module.bucket_globus_documents_development` | `storage-bucket` | `globus-documents-development` | `main.tf:2172` |
| `module.bucket_globus_documents_prod` | `storage-bucket` | `globus-documents-prod` | `main.tf:2193` |
| `module.bucket_globus_documents_test` | `storage-bucket` | `globus-documents-test` | `main.tf:2205` |
| `module.bucket_globus_profile_photos_development` | `storage-bucket` | `globus-profile-photos-development` | `main.tf:2216` |
| `module.bucket_globus_profile_photos_prod` | `storage-bucket` | `globus-profile-photos-prod` | `main.tf:2223` |
| `module.bucket_globus_vertex_agent_prod` | `storage-bucket` | `globus-vertex-agent-prod` | `main.tf:2230` |
| `module.bucket_globus_vertex_agent_staging` | `storage-bucket` | `globus-vertex-agent-staging` | `main.tf:2238` |
| `module.bucket_host_portal_metrics_storage` | `storage-bucket` | `host-portal-metrics-storage` | `main.tf:2246` |
| `module.bucket_manus_agent_builds_469819` | `storage-bucket` | `manus-agent-builds-469819` | `main.tf:2254` |
| `module.bucket_openstatus_sqld_data` | `storage-bucket` | `openstatus-sqld-data-skilled-script-469819-f2` | `main.tf:2262` |
| `module.bucket_skilled_script_cloudbuild_source` | `storage-bucket` | `skilled-script-469819-f2-cloudbuild-source` | `main.tf:2274` |
| `module.docs_update_agent_firestore` | `firestore-database` |  | `docs-update-agent-firestore.tf:1` |
| `module.globus_db_development` | `cloud-sql-postgres` | `globus-db-development` | `main.tf:845` |
| `module.mcp_db_development` | `cloud-sql-postgres` | `mcp-db-development` | `main.tf:895` |
| `module.n8n_db_dev` | `cloud-sql-postgres` | `n8n-db-dev` | `n8n-dev-standalone.tf:26` |
| `module.n8n_db_sandbox` | `cloud-sql-postgres` | `n8n-db-sandbox` | `n8n-sandbox-standalone.tf:24` |
| `module.n8n_dev_db` | `cloud-sql-postgres` | `n8n-dev-db` | `main.tf:764` |
| `module.npe_j1_visa_postgres_db` | `cloud-sql-postgres` | `npe-j1-visa-postgres-db` | `main.tf:831` |
| `module.openstatus_alert_agent_firestore` | `firestore-database` |  | `openstatus-alert-agent-firestore.tf:1` |
| `module.participant_keycloak_db_development` | `cloud-sql-postgres` | `participant-keycloak-db-development` | `main.tf:819` |
| `module.pr_review_eligibility_agent_firestore` | `firestore-database` |  | `pr-review-eligibility-agent-firestore.tf:1` |
| `module.redis_globus_cache_dev` | `redis-instance` | `globus-cache-dev` | `main.tf:1094` |
| `module.redis_keycloackparticipant_development` | `redis-instance` | `keycloackparticipant` | `main.tf:1109` |
| `module.user_addition_agent_firestore` | `firestore-database` |  | `user-addition-agent-firestore.tf:1` |

### Networking and load balancing

14 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `google_compute_global_address.globus_development_ip` | `google_compute_global_address` | `globus-development-ip` | `main.tf:1044` |
| `google_compute_global_address.host_portal_development_lb_ip` | `google_compute_global_address` | `host-portal-development-lb-ip` | `main.tf:1076` |
| `google_compute_global_address.hostportal_dev_ip` | `google_compute_global_address` | `hostportal-dev-ip` | `main.tf:1070` |
| `google_compute_global_address.n8n_dev_ip` | `google_compute_global_address` | `n8n-dev-ip` | `main.tf:1049` |
| `google_compute_global_address.n8n_development2_ip` | `google_compute_global_address` | `n8n-development2-ip` | `main.tf:1061` |
| `google_compute_global_address.n8n_sandbox_ip` | `google_compute_global_address` | `n8n-sandbox-ip` | `n8n-sandbox-standalone.tf:90` |
| `google_compute_global_address.npe_participant_postgres_psa_range_orphaned` | `google_compute_global_address` | `sql-peering-range-us-central1-npe-participant-postgres-db` | `main.tf:146` |
| `google_compute_global_address.ppp2_applicants_dev_ip` | `google_compute_global_address` | `ppp2-applicants-dev-ip` | `main.tf:1081` |
| `google_compute_network_peering.dev_to_ocr` | `google_compute_network_peering` | `dev-to-ocr` | `main.tf:87` |
| `module.fw_default_allow_internal_development` | `firewall-rule` | `default-allow-internal` | `main.tf:165` |
| `module.fw_default_allow_ssh_development` | `firewall-rule` | `default-allow-ssh` | `main.tf:179` |
| `module.fw_npe_allow_internal` | `firewall-rule` | `fw-npe-allow-internal` | `main.tf:190` |
| `module.network_default_development` | `network` | `default` | `main.tf:59` |
| `module.network_skilled_script_vpc_npe` | `network` | `skilled-script-vpc-npe` | `main.tf:93` |

### Build, registry and delivery

21 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `module.ar_alliance_abroad` | `artifact-registry` | `alliance-abroad` | `main.tf:2048` |
| `module.ar_alliance_mcp_gateway` | `artifact-registry` | `alliance-mcp-gateway` | `main.tf:2055` |
| `module.ar_applicant_portal_development` | `artifact-registry` | `applicant-portal` | `main.tf:2063` |
| `module.ar_applicants_portal_us_east1_development` | `artifact-registry` | `applicants-portal` | `main.tf:2103` |
| `module.ar_cloud_run_source_deploy` | `artifact-registry` | `cloud-run-source-deploy` | `main.tf:2071` |
| `module.ar_globus_development` | `artifact-registry` | `globus` | `main.tf:2079` |
| `module.ar_host_company_portal` | `artifact-registry` | `host-company-portal` | `main.tf:2118` |
| `module.ar_portal_development` | `artifact-registry` | `portal` | `main.tf:2087` |
| `module.ar_sevis_npm_development` | `artifact-registry` | `sevis-npm` | `sevis-npm-artifact-registry.tf:12` |
| `module.ar_wildpacks_development` | `artifact-registry` | `wildpacks` | `main.tf:2095` |
| `module.cloudbuild_github_connection_development` | `cloudbuild-github-connection` |  | `main.tf:2294` |
| `module.ppp2_cloud_deploy` | `cloud-deploy-pipeline` |  | `main.tf:556` |
| `module.sandbox_artifact_registry` | `artifact-registry` | `sandbox` | `branching-sandbox.tf:37` |
| `module.trigger_deploy_observer_agent_v2` | `cloudbuild-trigger` | `deploy-observer-agent-v2` | `main.tf:2368` |
| `module.trigger_deploy_overseer_agent` | `cloudbuild-trigger` | `deploy-overseer-agent` | `main.tf:2356` |
| `module.trigger_host_company_portal_server_development` | `cloudbuild-trigger` | `host-company-portal-server-development` | `main.tf:2400` |
| `module.trigger_host_portal_development` | `cloudbuild-trigger` | `host-portal-development` | `main.tf:2413` |
| `module.trigger_portal_development` | `cloudbuild-trigger` | `portal-development-trigger` | `main.tf:2436` |
| `module.trigger_pr_review` | `cloudbuild-trigger` | `pr-review-trigger` | `main.tf:2385` |
| `module.trigger_wildpacks_development` | `cloudbuild-trigger` | `wildpacks-development` | `main.tf:2425` |
| `module.trigger_wildpacks_development_deploy` | `cloudbuild-trigger` | `wildpacks-development-deploy` | `main.tf:2343` |

### Project services, messaging and other

6 items.

| Terraform address | Module or resource type | Identifier | Defined in |
| --- | --- | --- | --- |
| `data.google_project.this` | `google_project` |  | `ci-failure-alert-agent-public-access.tf:27` |
| `google_logging_metric.password_reset_mail_error_dev` | `google_logging_metric` | `password-reset-mail-error-dev` | `mail-deliverability-alerts.tf:14` |
| `google_logging_metric.realm_smtp_missing_dev` | `google_logging_metric` | `realm-smtp-missing-dev` | `mail-deliverability-alerts.tf:61` |
| `google_monitoring_alert_policy.password_reset_mail_error_dev` | `google_monitoring_alert_policy` | `Dev: password reset mail failing (password_reset_mail outcome=error)` | `mail-deliverability-alerts.tf:32` |
| `google_monitoring_alert_policy.realm_smtp_missing_dev` | `google_monitoring_alert_policy` | `Dev: Keycloak realm SMTP relay missing (realm_smtp configured=false)` | `mail-deliverability-alerts.tf:79` |
| `module.project_services_development` | `project-services` | `82 items: accesscontextmanager, admin, agentregistry, ...` | `main.tf:2510` |

## Live state

### Terraform compared with live state

| Resource type | Live | In Terraform | Matched | Live only (unmanaged) | Platform-created | Terraform only | Name not resolvable |
| --- | --- | --- | --- | --- | --- | --- | --- |
| `api` | 87 | 82 | 82 | 5 | 0 | 0 | 0 |
| `cloud_run_service` | 18 | 7 | 9 | 9 | 0 | 0 | 0 |
| `cloud_run_job` | 2 | 2 | 2 | 0 | 0 | 0 | 0 |
| `cloud_sql` | 8 | 8 | 8 | 0 | 0 | 0 | 0 |
| `redis` | 2 | 2 | 2 | 0 | 0 | 0 | 0 |
| `firestore` | 5 | 4 | 0 | 5 | 0 | 0 | 4 |
| `bucket` | 26 | 14 | 14 | 7 | 5 | 0 | 0 |
| `secret` | 234 | 174 | 169 | 65 | 0 | 1 | 1 |
| `service_account` | 49 | 25 | 25 | 23 | 1 | 0 | 0 |
| `wif_pool` | 6 | 6 | 5 | 1 | 0 | 0 | 1 |
| `artifact_registry` | 13 | 11 | 11 | 1 | 1 | 0 | 0 |
| `cloudbuild_trigger` | 8 | 8 | 8 | 0 | 0 | 0 | 0 |
| `pubsub_topic` | 6 | 0 | 0 | 2 | 4 | 0 | 0 |
| `scheduler_job` | 2 | 0 | 0 | 2 | 0 | 0 | 0 |
| `gke_cluster` | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| `domain_mapping` | 7 | 0 | 0 | 7 | 0 | 0 | 0 |
| `firewall_rule` | 8 | 3 | 3 | 0 | 5 | 0 | 0 |
| `vpc_network` | 2 | 2 | 2 | 0 | 0 | 0 | 0 |

### Live but not in Terraform

127 resources of the compared types exist in the project without a matching Terraform declaration.

| Resource type | Name |
| --- | --- |
| `api` | `apikeys` |
| `api` | `firebaserules` |
| `api` | `firestore` |
| `api` | `orgpolicy` |
| `api` | `siteverification` |
| `cloud_run_service` | `bug-diagnosis-agent` |
| `cloud_run_service` | `docs-update-agent` |
| `cloud_run_service` | `gcp-mcp-server` |
| `cloud_run_service` | `gke-workload-health-agent` |
| `cloud_run_service` | `openstatus-alert-agent` |
| `cloud_run_service` | `pr-latency-agent` |
| `cloud_run_service` | `pr-review-eligibility-agent` |
| `cloud_run_service` | `secrets-drift-agent` |
| `cloud_run_service` | `user-addition-agent` |
| `firestore` | `bug-diagnosis-agent` |
| `firestore` | `docs-update-agent` |
| `firestore` | `openstatus-alert-agent` |
| `firestore` | `pr-review-eligibility-agent` |
| `firestore` | `user-addition-agent` |
| `bucket` | `dev-tfstate-skilled-script-469819-f2` |
| `bucket` | `host-portal-db-backups-development` |
| `bucket` | `host-portal-public-assets` |
| `bucket` | `northamerica-northeast1.deploy-artifacts.skilled-script-469819-f2.appspot.com` |
| `bucket` | `pr-review-eligibility-agent-claims` |
| `bucket` | `terraform-state-bucket-npe` |
| `bucket` | `terraform-state-skilled-script-prod` |
| `secret` | `branch-drift-agent-asana-gateway-pat` |
| `secret` | `bug-diagnosis-agent-api-key` |
| `secret` | `bug-diagnosis-agent-asana-pat` |
| `secret` | `bug-diagnosis-agent-gateway-pat` |
| `secret` | `bug-diagnosis-agent-webhook-secret` |
| `secret` | `bug-diagnosis-reasoner-gateway-pat` |
| `secret` | `bug-diagnosis-reasoner-github-pat` |
| `secret` | `docs-update-agent-api-key` |
| `secret` | `docs-update-agent-gateway-pat` |
| `secret` | `email-health-agent-asana-gateway-pat` |
| `secret` | `env-audit-agent-asana-gateway-pat` |
| `secret` | `form-engine-bump-monitor-gateway-pat` |
| `secret` | `gke-workload-health-agent-api-key` |
| `secret` | `gke-workload-health-agent-asana-gateway-pat` |
| `secret` | `gke-workload-health-agent-asana-token` |
| `secret` | `globus-asana-alliance-api-key` |
| `secret` | `globus-dev-hubspot-api-key` |
| `secret` | `globus-dev-hubspot-auth-header` |
| `secret` | `globus-dev-netsuite-access-token` |
| `secret` | `globus-dev-netsuite-account-id` |
| `secret` | `globus-dev-netsuite-consumer-key` |
| `secret` | `globus-dev-netsuite-consumer-secret` |
| `secret` | `globus-dev-netsuite-realm` |
| `secret` | `globus-dev-netsuite-token-secret` |
| `secret` | `globus-development-environment` |
| `secret` | `globus-development-posthog-host` |
| `secret` | `globus-development-sandbox-mode` |
| `secret` | `globus-development-translation-glossary-id` |
| `secret` | `globus-docai-processor-id` |
| `secret` | `globus-n8n-sandbox-api-key` |
| `secret` | `globus-n8n-webhook-url-job-order` |
| `secret` | `globus-sendgrid-api-key` |
| `secret` | `n8n-dev-deploy-api-key` |
| `secret` | `n8n-dev-hubspot-webhook-secret` |
| `secret` | `n8n-dev-owner-password` |
| `secret` | `n8n-globus-api-callback-key` |
| `secret` | `n8n-qa-pipeline-webhook-token` |
| `secret` | `n8n-sandbox-deploy-api-key` |
| `secret` | `n8n-sandbox-globus-callback-key` |
| `secret` | `n8n-sandbox-owner-password` |
| `secret` | `n8n-sandbox-template-admin-harness-key` |
| `secret` | `onepassword-mcp-vault-admin-token` |
| `secret` | `openstatus-alert-agent-api-key` |
| `secret` | `openstatus-alert-agent-gateway-pat` |
| `secret` | `openstatus-alert-agent-known-issues` |
| `secret` | `openstatus-alert-agent-openstatus-key` |
| `secret` | `platform-bot-asana-pat` |
| `secret` | `ppp2-globus-api-key` |
| `secret` | `ppp2-keycloak-admin-client-secret` |
| `secret` | `ppp2-passport-name-sync-secret` |
| `secret` | `pr-hygiene-agent-api-key` |
| `secret` | `pr-hygiene-agent-gateway-pat` |
| `secret` | `pr-hygiene-agent-known-issues` |
| `secret` | `pr-latency-agent-api-key` |
| `secret` | `pr-latency-agent-gateway-pat` |
| `secret` | `pr-review-agent-gateway-pat` |
| `secret` | `pr-review-eligibility-agent-api-key` |
| `secret` | `pr-review-eligibility-agent-asana-gateway-pat` |
| `secret` | `pr-review-eligibility-agent-cycle-state` |
| `secret` | `pr-review-eligibility-agent-gateway-pat` |
| `secret` | `pr-review-eligibility-agent-webhook-secret` |
| `secret` | `secrets-drift-agent-api-key` |
| `secret` | `secrets-drift-agent-state` |
| `secret` | `security-agent-asana-gateway-pat` |
| `secret` | `vertex-reviewer-private-key` |
| `service_account` | `branch-drift-agent-sa` |
| `service_account` | `branch-drift-scheduler` |
| `service_account` | `bug-diagnosis-agent` |
| `service_account` | `bug-diagnosis-reasoner` |
| `service_account` | `cloudbuild-teams-notifier` |
| `service_account` | `data-lake-bigquery` |
| `service_account` | `dev-to-qa-sync-agent-sa` |
| `service_account` | `domain-admin-sa` |
| `service_account` | `env-audit-agent-sa` |
| `service_account` | `gke-workload-health-agent-sa` |
| `service_account` | `observer-agent-v2-sa` |
| `service_account` | `openstatus-alert-agent-sa` |
| `service_account` | `openstatus-mcp-sa` |
| `service_account` | `overseer-agent-sa` |
| `service_account` | `posthog-agent-sa` |
| `service_account` | `pr-hygiene-agent` |
| `service_account` | `pr-latency-agent-sa` |
| `service_account` | `pr-review-eligibility-agent` |
| `service_account` | `secrets-drift-agent-sa` |
| `service_account` | `sevis-sdk-reader` |
| `service_account` | `skilled-script-469819-f2` |
| `service_account` | `vertex-sync-agent-sa` |
| `service_account` | `volume-testing-agent-sa` |
| `wif_pool` | `github-actions-sandbox` |
| `artifact_registry` | `globus-npm` |
| `pubsub_topic` | `cloud-builds` |
| `pubsub_topic` | `secret-rotation-notifications` |
| `scheduler_job` | `docs-update-agent-drift-check` |
| `scheduler_job` | `docs-update-agent-sweep` |
| `domain_mapping` | `dev-1.sandbox.allianceabroad.com` |
| `domain_mapping` | `dev-2.sandbox.allianceabroad.com` |
| `domain_mapping` | `dev-3.sandbox.allianceabroad.com` |
| `domain_mapping` | `dev.apply.allianceabroad.com` |
| `domain_mapping` | `development.apply.allianceabroad.com` |
| `domain_mapping` | `development.apply.wildpacks.com` |
| `domain_mapping` | `nexus.allianceabroad.com` |

### In Terraform but not found live

| Resource type | Name | Terraform address | Defined in |
| --- | --- | --- | --- |
| `secret` | `n8n-monitors` | `module.secrets_bulk_development` | `main.tf:2624` |

### Created by GCP or GKE

These are created by the platform itself (default network rules, GKE firewall rules, default compute service accounts, Cloud Build buckets, container analysis topics) and are not drift.

| Resource type | Name |
| --- | --- |
| `bucket` | `481e243513174cba93c5a766e5db6d40_clouddeploy` |
| `bucket` | `gcf-v2-sources-382570452229-us-central1` |
| `bucket` | `gcf-v2-uploads-382570452229.us-central1.cloudfunctions.appspot.com` |
| `bucket` | `run-sources-skilled-script-469819-f2-us-central1` |
| `bucket` | `skilled-script-469819-f2_cloudbuild` |
| `service_account` | `382570452229-compute` |
| `artifact_registry` | `gcf-artifacts` |
| `pubsub_topic` | `container-analysis-notes-v1` |
| `pubsub_topic` | `container-analysis-notes-v1beta1` |
| `pubsub_topic` | `container-analysis-occurrences-v1` |
| `pubsub_topic` | `container-analysis-occurrences-v1beta1` |
| `firewall_rule` | `gke-globus-cluster-development-5c06a123-all` |
| `firewall_rule` | `gke-globus-cluster-development-5c06a123-exkubelet` |
| `firewall_rule` | `gke-globus-cluster-development-5c06a123-inkubelet` |
| `firewall_rule` | `gke-globus-cluster-development-5c06a123-vms` |
| `firewall_rule` | `k8s-fw-l7--9845bf8df74ff07a` |

### Terraform items whose name is computed at plan time

These could not be matched by name, so they are not counted as matched or missing.

| Resource type | Terraform address | Defined in |
| --- | --- | --- |
| `firestore` | `module.docs_update_agent_firestore` | `docs-update-agent-firestore.tf:1` |
| `firestore` | `module.openstatus_alert_agent_firestore` | `openstatus-alert-agent-firestore.tf:1` |
| `firestore` | `module.pr_review_eligibility_agent_firestore` | `pr-review-eligibility-agent-firestore.tf:1` |
| `firestore` | `module.user_addition_agent_firestore` | `user-addition-agent-firestore.tf:1` |
| `secret` | `module.secrets_bulk_development` | `main.tf:2624` |
| `wif_pool` | `google_iam_workload_identity_pool.sandbox` | `branching-sandbox.tf:65` |

### Resource types not compared

_None._

### Live reads that were denied or unavailable

| Read attempted | Result |
| --- | --- |
| first combined gcloud call (services+project describe+billing) via gcp_gcp_shell_exec | backend request failed (transient, retried successfully in split calls) |
| combined python inventory call (jobs+sql+redis+firestore+buckets) via gcp_gcp_shell_exec | backend request failed (likely timeout; retried successfully in split calls) |
| gcloud iam workload-identity-pools providers loop + artifacts list combined call | backend request failed (retried successfully in split calls) |

### Collection notes

Caveats recorded when the live snapshot was read.

- Dedicated gateway read tools were not loaded; all data gathered with read-only gcloud list/describe/get-iam-policy via gcp_gcp_shell_exec (no writes, no secret values, no kubectl).
- IAM member strings are abbreviated: '.SA' = '.iam.gserviceaccount.com', '@P' = '@skilled-script-469819-f2', '@developer' = '@developer.gserviceaccount.com'.
- collected_at is the date (2026-10-01); exact time not captured.
- Secret replication: all 234 secrets are automatic replication; names list is complete (count 234).
- Cloud Deploy targets list returned empty in northamerica-northeast1 for the ppp2 pipeline; targets ppp2-dev and ppp2-dev-client inferred from Cloud Run labels.
- Cloud Run services list contains no nexus-hub service in this project though domain mapping nexus.allianceabroad.com -> nexus-hub exists (dangling). nexus-hub-runtime-sa exists.
- Dev project hosts references to prod/test resources by name: buckets globus-documents-prod, globus-profile-photos-prod, globus-vertex-agent-prod/-staging, terraform-state-skilled-script-prod; a globus-prod NEG; IAM for production-499116 and quality-assurance-496022 SAs. Also resources with 'staging' naming (stg-globus-maps-rot key, globus-vertex-agent-staging).
- Stale/deleted principals in IAM: vi-gke-nodes, virtual-interviews-sa, ci-failure-alert-agent (all 'deleted:'). Stale virtual-interviews resources remain (cert mcrt-f9efe9d8, NEG, Cloud Armor policy virtual-interviews-security-policy).
- External human principals with project access: [user account] (bigquery.admin, iam.serviceAccountCreator), [user account] (viewer, browser), [user account] and [user account] (storage.admin), [user account]. Owners: soregan, bmishkin37, manus-agent-sa.
- Basic roles in use: roles/editor on default compute SA and cloudservices SA; roles/owner on manus-agent-sa.
- Public/exposure: globus-db-development and mcp-db-development have public IPv4 enabled; every Cloud Run service has ingress=all; default-allow-ssh limited to 75.40.188.183/32; GKE exkubelet rule source 0.0.0.0/0.
- Redis instances: both BASIC tier, no persistence/HA; keycloackparticipant transit encryption DISABLED.
- dev-globus-maps-rot-20260314-v3 API key has no API target restriction.
- Cloud Build triggers: pr-review-trigger and host-company-portal-server-development are disabled; ParticipantPortalPrototype trigger still active though that repo is archived.
- Firestore bug-diagnosis-agent database is in us-central1 with delete protection off; others nam5 with protection on.
- GCP project-level labels: none. No GKE ExternalSecret/kubectl data collected (kubectl prohibited).

## Live inventory

Selected stable attributes read from the running project.

### Cloud Run services (live)

| Service | Region | Ingress | Scaling | Runs as |
| --- | --- | --- | --- | --- |
| `applicant-keycloak` | `northamerica-northeast1` | `all` | `1-1` | `382570452229-compute@developer.gserviceaccount.com` |
| `bug-diagnosis-agent` | `us-central1` | `all` | `0-100` | `bug-diagnosis-agent@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `docs-update-agent` | `us-central1` | `all` | `0-1` | `docs-update-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `gcp-mcp-server` | `us-central1` | `all` | `1-10` | `manus-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `gke-workload-health-agent` | `us-central1` | `all` | `0-1` | `gke-workload-health-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `host-company-portal-client` | `northamerica-northeast1` | `all` | `1-1` | `host-service-potal@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `host-company-portal-server` | `northamerica-northeast1` | `all` | `1-1` | `backend-service-potal@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `openstatus-alert-agent` | `us-central1` | `all` | `0-1` | `openstatus-alert-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `ppp2-participant-client` | `northamerica-northeast1` | `all` | `0-2` | `382570452229-compute@developer.gserviceaccount.com` |
| `ppp2-participant-server` | `northamerica-northeast1` | `all` | `0-3` | `382570452229-compute@developer.gserviceaccount.com` |
| `pr-latency-agent` | `us-central1` | `all` | `0-1` | `pr-latency-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `pr-review-eligibility-agent` | `us-central1` | `all` | `0-100` | `pr-review-eligibility-agent@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `sandbox-web-dev-1` | `us-central1` | `all` | `0-2` | `sandbox-runtime-dev@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `sandbox-web-dev-2` | `us-central1` | `all` | `0-2` | `sandbox-runtime-dev@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `sandbox-web-dev-3` | `us-central1` | `all` | `0-2` | `sandbox-runtime-dev@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `secrets-drift-agent` | `us-central1` | `all` | `0-1` | `secrets-drift-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `user-addition-agent` | `us-central1` | `all` | `0-1` | `user-addition-agent-sa@skilled-script-469819-f2.iam.gserviceaccount.com` |
| `wildpacks-development` | `us-central1` | `all` | `0-3` | `wildpacks-dev-runtime@skilled-script-469819-f2.iam.gserviceaccount.com` |

### Cloud SQL instances (live)

| Instance | Region | Version | Tier | Edition | Private IP | Backups |
| --- | --- | --- | --- | --- | --- | --- |
| `n8n-dev-db` | `us-central1` | `POSTGRES_15` | `db-g1-small` | `ENTERPRISE` | `true` | `true` |
| `applicant-portal-db-development` | `us-central1` | `POSTGRES_15` | `db-custom-1-3840` | `ENTERPRISE` | `true` | `true` |
| `participant-keycloak-db-development` | `us-central1` | `POSTGRES_15` | `db-g1-small` | `ENTERPRISE` | `true` | `true` |
| `n8n-db-sandbox` | `us-central1` | `POSTGRES_15` | `db-g1-small` | `ENTERPRISE` | `true` | `true` |
| `npe-j1-visa-postgres-db` | `us-central1` | `POSTGRES_15` | `db-f1-micro` | `ENTERPRISE` | `true` | `true` |
| `globus-db-development` | `us-central1` | `POSTGRES_15` | `db-custom-1-3840` | `ENTERPRISE` | `true` | `true` |
| `n8n-db-dev` | `us-central1` | `POSTGRES_15` | `db-g1-small` | `ENTERPRISE` | `true` | `true` |
| `mcp-db-development` | `us-central1` | `POSTGRES_15` | `db-custom-1-3840` | `ENTERPRISE` | `true` | `true` |

### Redis instances (live)

| Instance | Region | Tier | Memory GB | Version |
| --- | --- | --- | --- | --- |
| `keycloackparticipant` | `northamerica-northeast1` | `BASIC` |  | `REDIS_7_2` |
| `globus-cache-dev` | `us-central1` | `BASIC` |  | `REDIS_7_0` |

### Cloud Storage buckets (live)

| Bucket | Location | Class | Versioning | Public access prevention |
| --- | --- | --- | --- | --- |
| `481e243513174cba93c5a766e5db6d40_clouddeploy` | `NORTHAMERICA-NORTHEAST1` |  |  |  |
| `applicant-portal-documents-development` | `US-CENTRAL1` |  | `false` |  |
| `applicant-portal-photos-development` | `US-CENTRAL1` |  | `false` |  |
| `dev-tfstate-skilled-script-469819-f2` | `US-CENTRAL1` |  | `true` |  |
| `development-globus-branding-assets` | `US-CENTRAL1` |  | `false` |  |
| `gcf-v2-sources-382570452229-us-central1` | `US-CENTRAL1` |  | `true` |  |
| `gcf-v2-uploads-382570452229.us-central1.cloudfunctions.appspot.com` | `US-CENTRAL1` |  |  |  |
| `globus-documents-development` | `US-CENTRAL1` |  | `false` |  |
| `globus-documents-prod` | `US-CENTRAL1` |  | `false` |  |
| `globus-documents-test` | `US-CENTRAL1` |  | `false` |  |
| `globus-profile-photos-development` | `US-CENTRAL1` |  | `false` |  |
| `globus-profile-photos-prod` | `US-CENTRAL1` |  | `false` |  |
| `globus-vertex-agent-prod` | `US-CENTRAL1` |  | `false` |  |
| `globus-vertex-agent-staging` | `US-CENTRAL1` |  | `false` |  |
| `host-portal-db-backups-development` | `US-CENTRAL1` |  |  |  |
| `host-portal-metrics-storage` | `NORTHAMERICA-NORTHEAST1` |  | `false` |  |
| `host-portal-public-assets` | `US` |  |  |  |
| `manus-agent-builds-469819` | `US-CENTRAL1` |  | `false` |  |
| `northamerica-northeast1.deploy-artifacts.skilled-script-469819-f2.appspot.com` | `NORTHAMERICA-NORTHEAST1` |  |  |  |
| `openstatus-sqld-data-skilled-script-469819-f2` | `US-CENTRAL1` |  | `false` |  |
| `pr-review-eligibility-agent-claims` | `US-CENTRAL1` |  |  |  |
| `run-sources-skilled-script-469819-f2-us-central1` | `US-CENTRAL1` |  |  |  |
| `skilled-script-469819-f2-cloudbuild-source` | `US-CENTRAL1` |  | `false` |  |
| `skilled-script-469819-f2_cloudbuild` | `US` |  |  |  |
| `terraform-state-bucket-npe` | `US-EAST1` |  | `true` |  |
| `terraform-state-skilled-script-prod` | `NORTHAMERICA-NORTHEAST1` |  |  |  |

### Workload Identity pools (live)

| Pool | State | Providers |
| --- | --- | --- |
| `github-actions-apply-dev` | `ACTIVE` | `github-provider` |
| `github-actions-sandbox` | `ACTIVE` | `github-provider` |
| `manus-pool` | `ACTIVE` | `manus-provider` |
| `github-actions-n8n-wf` | `ACTIVE` | `github-provider` |
| `github-actions` | `ACTIVE` | `github` |
| `github-actions-iac` | `ACTIVE` | `github-provider` |
| `skilled-script-469819-f2.svc.id.goog` | `ACTIVE` |  |

### Cloud Scheduler jobs (live)

| Job | Schedule | State |
| --- | --- | --- |
| `docs-update-agent-sweep` | `0 13 * * *` | `ENABLED` |
| `docs-update-agent-drift-check` | `0 12 * * 1` | `ENABLED` |

## Drift between Terraform and reality

The drift comparison (`drift.json`, read-only live data) shows development is mostly declared but with clear gaps:

- **Agent fleet outside Terraform.** Nine live Cloud Run services have no Terraform declaration; the unmanaged group is the eight agent services plus `gcp-mcp-server`. Their Firestore databases are mostly declared as modules (four modules exist) but did not match live databases by name, and their service accounts, scheduler jobs (docs-update-agent sweep and drift check) and many per-agent secrets are also live-only. Agents are deployed by their own pipeline, so Terraform shows the platform around them but not the services.
- **Service accounts.** About half of the live service accounts are not in Terraform: most agent SAs, the Cloud Build notifier and several data and sync SAs.
- **Secrets.** Roughly 65 of 234 secrets are live-only, mostly agent API keys and gateway PATs, and the NetSuite and HubSpot development values. One declared secret (`n8n-monitors`, inside `module.secrets_bulk_development`) was not found live. Secret values are never managed here.
- **Domain mappings.** Seven Cloud Run domain mappings are live-only (sandbox hostnames, `dev.apply`, `development.apply`, `development.apply.wildpacks.com`). One maps `nexus.allianceabroad.com` to a `nexus-hub` service that no longer exists in this project, so it is dangling.
- **Buckets and registries.** Several buckets are live-only, including the Terraform state bucket itself and an old prod state bucket (`terraform-state-skilled-script-prod`) physically hosted here. The Artifact Registry repo `globus-npm` is live-only.
- **WIF.** The sandbox pool `github-actions-sandbox` is declared in `branching-sandbox.tf`, but its Terraform name is resolved at plan time, so it could not be matched; the live pool of that name is listed as live-only.
- **Compared as platform-created:** Container Analysis Pub/Sub topics, GKE-created firewall rules and Cloud Build and run-sources buckets are counted as platform-created, not drift.

The comment in `backend.tf` (saying the state bucket does not exist yet) is stale; the bucket exists, is live, and is the configured backend.

## Security observations

These come from the live snapshot notes and should be reviewed. They are facts, not confirmed incidents.

- Users from external domains (including `nomnomdata.com`, `cloudkite.io` and `cleversteam.com`) hold project roles, including `roles/bigquery.admin`, `roles/iam.serviceAccountCreator` and `roles/storage.admin`. One further principal is a temporary-account style address from the company domain.
- Basic roles are in use: `roles/editor` on the default compute and cloudservices accounts, and `roles/owner` on `manus-agent-sa`.
- Several principals in IAM policies are marked deleted (`vi-gke-nodes`, `virtual-interviews-sa`, `ci-failure-alert-agent`) and stale virtual-interviews resources remain (certificate, NEG, Cloud Armor policy).
- The Cloud SQL instances `globus-db-development` and `mcp-db-development` have public IPv4 enabled. Every Cloud Run service has ingress set to all. A firewall rule for GKE exkubelet allows source `0.0.0.0/0`, and `default-allow-ssh` is limited to a single address.
- Both Redis instances are BASIC tier with no persistence or HA; one has transit encryption disabled.
- The API key `dev-globus-maps-rot-20260314-v3` has no API target restriction.
- Cloud Build trigger for the archived `ParticipantPortalPrototype` repo is still active, while `pr-review-trigger` and `host-company-portal-server-development` are disabled.
- Names containing `staging` (a Maps key, `globus-vertex-agent-staging`) persist here although no staging environment exists.

## Known gaps

- **Read path.** Data came from read-only `gcloud` list and describe calls through the gateway (impersonating `manus-agent-sa`); three combined calls failed transiently and were retried in split form, so no section is known to be missing. No Kubernetes objects, secret values or database contents were read, so namespace contents and in-cluster workloads are not covered.
- **Cloud Deploy.** The targets list for the `ppp2` pipeline returned empty; targets `ppp2-dev` and `ppp2-dev-client` were inferred from Cloud Run labels only, so the live read neither confirms nor refutes them. Terraform (`module.ppp2_cloud_deploy`) declares both targets.
- **Other projects.** `alliance-platform-services` could not be read at all, and `alliance-mcp-services` was read through a development-environment token with many sections denied, so cross-project grants referencing them cannot be fully verified from this side. See `/docs/gcp-env-mcp` and `/docs/gcp-env-platform-services`.
- **Existing docs.** `/docs/disaster-recovery-plan` says restore-from-git is not guaranteed to reproduce live state; the drift above supports that for the agent fleet, service accounts and domain mappings.
