Secret Manager
Secret Manager stores secrets as versioned values that IAM grants access to one by one. The GCP platform keeps three kinds there: credentials the Baseline never writes itself, the Web App Blueprint's connection values, and the application secrets the Secrets Blueprint syncs from Git.
What it does
A secret is a named container in a project, and every change adds a version; readers usually ask for the latest. Replication decides where the payload is stored: automatic (Google chooses) or user-managed (named regions). Access is IAM on the project or on the single secret, with roles/secretmanager.secretAccessor to read a version. A secret's metadata can be created without any version, so its value never has to pass through infrastructure code.
How BuiltForProd uses it
Every secret on the platform uses user-managed replication in the home region, because the gcp.resourceLocations organization policy refuses automatic replication.
| Secrets | Project | Written by | Read by |
|---|---|---|---|
github-runner--app-id, -app-key, -app-installation-id, -webhook-secret | acme-core-auto | the platform team, by hand | the Baseline and web app CI accounts, the four stage deployers |
mongo--host, mongo--uri, mongo--database | each stage project | the Web App Blueprint (firestore unit) | the External Secrets Operator |
redis--host, redis--port, redis--ca | each stage project | the Web App Blueprint (valkey unit) | the External Secrets Operator |
<app>--<KEY> | each stage project | the Secrets Blueprint's sync workflow | the External Secrets Operator |
Placeholders filled by hand. The Baseline's platform-params unit creates the four GitHub App secrets without any version and with deletion protection; the platform team adds the values outside the code, so no credential reaches the state. The self-hosted runners read them, and the Web App Blueprint reads three of them through the stage deployer to give ArgoCD access to the GitOps repository.
Connection values, not credentials. The Web App Blueprint publishes where its data stores are and how to verify them, never a password: the Firestore URI names the MONGODB-OIDC mechanism and the Valkey CA bundle verifies TLS, while the pods authenticate with their own workload identity. The Data and ETL Blueprint writes no secret at all: everything there authenticates with IAM, so its stages hold none of its secrets by design.
Synced application secrets. SOPS files in the Secrets Blueprint become one secret per key, <app>--<KEY>, labeled source=sops, and every change is a new version. The syncer account holds Secret Manager Admin on the stage projects with an IAM condition that excludes every secret whose ID starts with platform--. Inside the cluster, the External Secrets Operator maps the secrets the application needs into Kubernetes Secrets.
Non-secret configuration, such as the landing-zone contract and image tags, lives in Parameter Manager instead.
Terms you will see
| Term | Meaning |
|---|---|
| Secret | A named container whose values are versions. |
| Version | One immutable value of a secret; a sync adds one only when the value changes. |
| User-managed replication | The payload stored in named regions only, here the home region. |
| Placeholder secret | A secret created by the code without a value, filled by hand. |
<app>--<KEY> | The ID pattern of a synced application secret, such as sample--AUTH0_DOMAIN. |
Where to read more
- GCP Secrets Blueprint overview, GCP Web App Blueprint overview and the GCP Enterprise Baseline overview.
- SOPS for how application secrets are encrypted in Git.
- Parameter Manager for non-secret configuration.