Skip to content

Secrets and identity flow

Identity grants a component permission to act. A secret supplies sensitive configuration or key material. Resilience Gate uses several identities and external secret references so image publication, registry discovery, rendered Git writes, Kubernetes experiment control, and payment signing do not share one credential.

CI receives short-lived publication identity

Section titled “CI receives short-lived publication identity”

The GitHub OIDC Terraform creates a Workload Identity Federation provider for GitHub’s issuer. Its condition binds the configured repository, ref, and allowed event types. A dedicated publisher service account has Artifact Registry writer access to the configured repository. The publication workflows require trusted-main validation before granting their publish job id-token: write.

The workflow exchanges an OIDC token for short-lived Google credentials, authenticates Docker to the registry, and signs the emitted digest through keyless Cosign. There is no generated static JSON cloud key in this path. This does not enforce repository review or branch protection by itself. Workflow tests check read-only pull-request permissions, publish dependencies, and digest records.

Controllers use distinct cloud and Git identities

Section titled “Controllers use distinct cloud and Git identities”

Kargo’s registry-reader identity can read the selected Artifact Registry repository. The Kargo Kubernetes service account receives token-creation permission for that Google service account. It is separate from the publisher and External Secrets Operator identities.

Git writes use another path. The Kargo ExternalSecret references a Secret Manager token. External Secrets Operator materializes the kargo-git-credentials Kubernetes Secret with the credential-type label Kargo discovers. Kargo uses that credential for rendered-branch commits and pushes. Ordinary image CI does not render or push env/* branches.

The configured credential’s effective Git scope depends on its externally provisioned token. The manifest’s repository reference and Kargo label describe intended use; they are not proof of every permission the external token actually possesses.

External references become workload configuration

Section titled “External references become workload configuration”

The shared ClusterSecretStore identifies the GCP project, GKE cluster, location, and External Secrets Kubernetes service account. ESO Terraform binds that service account to a dedicated Google identity with project-level Secret Manager accessor permission. It avoids a static key, but its cloud grant is broader than per-secret IAM and should not be described as exact-secret isolation.

ExternalSecret resources contain remote key names, refresh intervals, target Secret names, and templates. They do not contain secret values. ESO retrieves values and writes Kubernetes Secrets; workloads then read their named Secret through envFrom or secretKeyRef. A successful manifest render only proves references are structurally present, not that remote values exist or are correct.

Consumer Materialized configuration Boundary
Application and stateful dependencies Database/Redis URLs and credentials; merchant address when payments are enabled Environment-specific Secret referenced by the app chart
Signer Testnet RPC URL, merchant address, three payer private keys Signer-only Secret in staging
Load generator Merchant address No payer private keys or RPC credentials supplied by its Secret
Kargo Git repository credential Kargo project namespace
Gate runner Optional Grafana annotation password Optional single-key reference; absence does not block startup

The application ExternalSecret template fails rendering if PostgreSQL or Redis existing-Secret names differ from its target. Signer, load-generator, and annotation manifests show the other materialization contracts.

Kubernetes control is another identity boundary

Section titled “Kubernetes control is another identity boundary”

The gate Job runs under chaos-gate in resilience-gate and mounts a Kubernetes service-account token because it must create and observe objects. Its Roles grant Lease operations in the project namespace and workflow/load/observation operations in staging. The script limits actions to its run objects. RBAC itself remains namespace-scoped and does not constrain every permitted create/delete to a specific run ID.

The signer and load-generator Pods disable automatic Kubernetes token mounting. They need HTTP configuration and credentials for their work rather than Kubernetes API authority. The application chart also controls service-account creation and token mounting explicitly. These choices reduce unused API credential exposure without implying network authentication for every internal HTTP call.

Rotation and evidence have practical limits

Section titled “Rotation and evidence have practical limits”

Most external references refresh hourly. Updating a Kubernetes Secret does not automatically rewrite the environment of an already-running process. The chart’s checksum annotations track rendered Secret or ExternalSecret definitions; they do not prove automatic restart after a remote value alone changes. Credential rotation therefore needs explicit operational verification.

Evidence should retain public image digests, source revisions, workflow names, and object identities needed to explain a run. It must exclude Secret values, payer keys and addresses, payment signatures and headers, transaction identifiers, cookies, and kubeconfigs. The evidence policy defines that disclosure boundary. A sanitized receipt intentionally limits independent payment inspection; that absence should remain visible.

For the release identity chain, continue with artifact trust. For responsibilities and failure layers, see delivery design.

Maintained by Satyam Agnihotri · DevOps & Cloud Engineer