Note not found.

SOP: Gmail OAuth Token Management

sop-gmail-oauth Sop

sop active

SOP: Gmail OAuth Token Management

Purpose

Used by agents and humans when Gmail email sending fails with 401 Unauthorized. Covers token verification, emergency recovery, and the permanent fix history. The Gmail SDK auto-refreshes tokens transparently — this SOP is only needed when something breaks.

Steps

  • Verify token health. Run: cat ~/secrets/google-oauth/gmail-westsidebasketball.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'expires_in: {d.get(\"refresh_token_expires_in\", \"PERMANENT\")}')". If it says PERMANENT, the token is fine — the issue is elsewhere (MCP server crash, network). If it says 604799, the app has regressed to Testing mode — go to step 5.
  • Re-auth via MCP (if access token expired). Call gmail_reauth_start(account="westsidebasketball"). Open the URL in a browser, sign in as westsidebasketball@gmail.com (NOT draneylucas). Paste the redirect URL into gmail_reauth_complete(account="westsidebasketball", callback_url="...").
  • Sync to k8s. Run: kubectl create secret generic gmail-oauth-westsidebasketball --namespace basketball-api --from-file=gmail-westsidebasketball.json=$HOME/secrets/google-oauth/gmail-westsidebasketball.json --from-file=credentials.json=$HOME/secrets/google-oauth/credentials.json --dry-run=client -o yaml | kubectl apply -f -. Also update the legacy secret: same command but with gmail-oauth-token as the secret name.
  • Restart the consuming pod. Run: kubectl rollout restart deployment/basketball-api -n basketball-api.
  • If refresh token expired (Testing mode regression). Go to https://console.cloud.google.com/apis/credentials/consent?project=gmail-oauth-486921 (sign in as draneylucas@gmail.com). Verify the app is Published. If it reverted to Testing, click Publish App. Then re-auth one final time per step 2.

Rules

  • NEVER ask the user to re-auth before checking token health (step 1). Diagnose first.
  • ALWAYS sign in as westsidebasketball@gmail.com during re-auth, not draneylucas@gmail.com. Wrong account = token for wrong Gmail.
  • The Gmail account has a typo: westsidebasktball@gmail.com (missing 'e'). The token file uses the correct alias: gmail-westsidebasketball.json.
  • Three token stores must stay in sync: local (~/secrets/google-oauth/), k8s gmail-oauth-westsidebasketball, k8s gmail-oauth-token.
  • The MCP server caches tokens in memory. After updating the local file, the MCP gmail_reauth_complete tool clears the cache automatically — no restart needed.
  • Google Cloud project gmail-oauth-486921 is owned by draneylucas@gmail.com. OAuth client type is Desktop/Installed (redirect_uri: http://localhost).
  • The gmail-sdk auto-refresh code lives at gmail-sdk/src/gmail_sdk/auth.py:157-179. It refreshes when access token is within 300 seconds of expiry.
  • sop-email-send — email sending workflow that depends on working Gmail OAuth
  • deployment-lessons — historical debugging lessons including OAuth incidents
  • reference-gmail-oauth — original reference note for Gmail OAuth re-auth procedure
  • sop-incident-response — escalation path when email is down