---
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, 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.
- 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 three pre-provisioned slots 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 six 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.

_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.
