When to use
A credential is suspected compromised (e.g. pasted in plaintext), on a routine rotation schedule, or when a provider secret is regenerated. Covers the broker's OAuth client secrets and the Telegram bot token.
Principle
Every secret follows the same path: regenerate at the source → update where it lives → redeploy. OAuth client secrets live in Secret Manager and reach the box via Ansible; the Telegram bot token lives in a file on the VM. Existing OAuth access tokens keep working after a client-secret rotation — the new secret is exercised on the next token refresh or reconnect.
OAuth client secrets (GitHub, Notion, …)
- Regenerate at the provider (GitHub → Developer settings → OAuth Apps → Generate a new client secret; Notion → integrations → regenerate secret).
- Store the new value as a new Secret Manager version (deploy always fetches
latest):pbpaste | gcloud secrets versions add <secret-name> --project=bob-mcp-project-2026 --data-file=-Secret names:github-oauth-client-secret,notion-oauth-client-secret,tailscale-oauth-client-secret,gitlab-token,adzuna-app-id,adzuna-app-key. - Redeploy the broker (re-fetches into
.env, restarts):cd ansible && ansible-playbook -i inventory.ini install.yml -e cloudflare_tunnel_token="$(cat ~/.cf-tunnel-token)" - Validate without a browser reconnect — confirm the deployed value matches
Secret Manager and has the right shape (catches a clipboard swap: GitHub
secrets are 40 hex chars; Notion secrets start
secret_):ssh ubuntu@gcp-mcp-broker "sudo grep '^GITHUB_CLIENT_SECRET=' /home/ubuntu/mcp-broker/.env | cut -d= -f2- | grep -qE '^[0-9a-f]{40}$' && echo shape-ok"For 100% proof, disconnect + reconnect the connector (browser OAuth) — that exercises the new secret directly.
Telegram bot token
The bot token is not in Secret Manager — it lives in
/home/claudebot/.config/telegram.env (TELEGRAM_BOT_TOKEN) and the source of
truth is ~/.tg-bot-token on the Mac (read by claudebot.yml on deploy).
1. @BotFather → /revoke → pick the bot → copy the new token.
2. Update the live file + restart the service, and keep the Mac source of truth
in sync (otherwise a rebuild restores the old token):
ssh -t ubuntu@gcp-mcp-broker 'read -rs T && sudo sed -i "s|^TELEGRAM_BOT_TOKEN=.*|TELEGRAM_BOT_TOKEN=$T|" /home/claudebot/.config/telegram.env && sudo systemctl restart claude-telegram.service && echo done'
# then sync the Mac source of truth:
ssh ubuntu@gcp-mcp-broker "sudo grep '^TELEGRAM_BOT_TOKEN=' /home/claudebot/.config/telegram.env | cut -d= -f2-" > ~/.tg-bot-token && chmod 600 ~/.tg-bot-token
Gotchas
- Deploy fetches
latest— if you add a wrong value, it goes live on the next deploy. Verify shape (above) before trusting it. - gcloud CLI vs ADC —
gcloud secretsneeds a live CLI login (gcloud auth login); Terraform needs the ADC login (gcloud auth application-default login). They expire independently. - Mac ↔ VM drift for the bot token — always re-sync
~/.tg-bot-tokenafter rotating the Telegram token, or the nextclaudebot.ymlrun restores the old one.
Related
Sources
wiki/projects/gcp-mcp-standalone/runbooks/rotate-secrets.md · git is the source of truth