Hive
fix(infra): source Google OAuth from 1Password via ESO
GitHub issue · Closed
What changed
Wires the Google OAuth client credentials (TUIST_GOOGLE_OAUTH_CLIENT_ID / TUIST_GOOGLE_OAUTH_CLIENT_SECRET) through External Secrets Operator from 1Password for all managed environments, the same way the GitHub App credentials already are.
- New
templates/google-external-secrets.yaml— anExternalSecretsyncingGOOGLE_OAUTH/client_idandGOOGLE_OAUTH/client_secretfrom each cluster’stuist-k8s-<env>1P vault into a dedicated Secret. - New
tuist.googleEnvhelper in_helpers.tpl, included on the server Deployment only (the processors don’t render the login page or handle the OAuth callback). server.googleschema invalues.yaml, defaultmanagedSecrets: false.- Enabled for all managed envs via
values-managed-common.yaml.
Why
The “Log in with Google” button was missing on canary only. The button is gated on Environment.google_oauth_configured?/0, which is true only when both TUIST_GOOGLE_OAUTH_* resolve. Those values are read from the encrypted priv/secrets/<env>.yml.enc blob, and production + staging carry a google: block in theirs while can.yml.enc never did, so canary alone hid the button. Verified against the live login pages: prod and staging show Google, canary does not.
Root cause
A per-env secrets gap, not a code bug. The gating function and its env-var/secret resolution have been unchanged since the server entered the monorepo, and Environment.get/3 reads the TUIST_* env var before the decrypted blob — so injecting the env var via ESO is sufficient to surface the button.
Why this approach over patching the blob
Patching can.yml.enc would fix canary but keep Google credentials in the mix-secrets blob. Sourcing them from 1Password instead both fixes canary and continues the ongoing migration of OAuth secrets out of the blob (GitHub already lives in 1P). Because the env var takes precedence over the blob, each env transparently switches to 1P as its vault is populated.
Notable decisions
- Enabled in
values-managed-common.yaml(all managed envs) rather than canary-only, since the goal is to move Google fully off the blob. - Hard-required secret refs (not
optional), matching the GitHub pattern. The two cases a lenient ref would cover are handled elsewhere: a self-hosted install that doesn’t use Google leavesmanagedSecretsat itsfalsedefault, so no Secret or env refs are rendered at all; and every managed env’s vault already carries theGOOGLE_OAUTHitem, so there’s no not-yet-populated gap at deploy time. Failing loud on a missing/unsynced secret is consistent with how the GitHub App credentials behave in the same helper.
Validation
helm template across values-managed-{canary,staging,production}.yaml: each renders the ExternalSecret and both env refs. The chart is inert (no resources, no env refs) when server.google.managedSecrets is false — confirmed against the default values.yaml.
Rollout (manual, per env)
- Create a
GOOGLE_OAUTHitem (fieldsclient_id,client_secret) in eachtuist-k8s-<env>1P vault. For staging/production, copy the values already in their blob so their existing registered redirect URIs keep working. Done for all three envs. - For canary, register the new client’s redirect URI
https://canary.tuist.dev/users/auth/google/callbackin Google Cloud Console. - Deploy. ESO syncs the Secret and the pods roll with the env vars; if a vault is populated after deploy,
kubectl rollout restart deploy/tuist-tuist-server -n <ns>to pick it up. - Once verified, drop the now-dead
google:block from each env’s encrypted blob (mix secrets.edit --env <env>).
Draft until the canary redirect URI is confirmed in place and the chart change is verified on a managed env.
🤖 Generated with Claude Code
No GitHub comments yet.