Automate Gmail OAuth re-auth lifecycle (7-day token expiry) #162
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
forgejo_admin/pal-e-platform#162
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Type
Feature
Lineage
Standalone — discovered during repeated manual Gmail OAuth re-auth cycles (7-day token expiry).
Prerequisite
forgejo_admin/gmail-mcp#6(SSH-compatible reauth tool, board item #361) is done.Repo
forgejo_admin/pal-e-platformUser Story
As a platform operator
I want a single script that re-authenticates Gmail OAuth and syncs the refreshed token to all consuming k8s workloads
So that the 7-day token expiry cycle is a 1-minute ops task instead of a manual multi-step firefight
Context
Gmail OAuth tokens for
westsidebasketball@gmail.comexpire every 7 days (Google's policy for unverified apps). Today, re-auth is a manual, error-prone process: run gmail-mcp'sreauthtool via SSH, then manually copy the refreshed token file into the correct k8s secrets/PVCs for each consuming service.Consumers of the Gmail OAuth token:
gmail-oauth-tokeninbasketball-apinamespace, mounted at/secrets/google-oauthvia initContainer copy pattern.gmail-oauthinpal-e-mailnamespace, mounted at/secrets/gmail. This is a PersistentVolumeClaim, NOT a k8s secret.~/secrets/google-oauth/gmail-westsidebasktball.json.Prerequisite satisfied:
gmail-mcp#6added an SSH-compatiblereauthCLI tool that can perform the OAuth browser flow and write the refreshed token to the local file. This ticket wraps that tool in an end-to-end automation script.File Targets
Files the agent should create or modify:
scripts/gmail-reauth.sh(new) — orchestration script that: (1) calls gmail-mcp reauth, (2) updates k8s secretgmail-oauth-tokeninbasketball-apinamespace, (3) restarts affected deployments to pick up new tokensalt/pillar/secrets_registry.sls— add Gmail OAuth token entry underplatform:section withrotation_days: 7, originexternal, providerGoogle OAuth (westsidebasketball@gmail.com)terraform/modules/monitoring/main.tf— add PrometheusRule for gmail-oauth-token day-6 expiry alertingFiles the agent should NOT touch:
~/gmail-sdk/src/gmail_sdk/auth.py— upstream SDK, not in this repo's scope~/gmail-mcp/— already has SSH reauth tool (done in #6), no changes needed~/pal-e-deployments/— deployment patches are owned by pal-e-deployments repoAcceptance Criteria
scripts/gmail-reauth.shperforms end-to-end reauth: invokes gmail-mcp reauth, reads the refreshed local token, updates k8s secretgmail-oauth-tokeninbasketball-apinamespace, and triggers a rollout restart of basketball-apisalt/pillar/secrets_registry.slshas a newgmail_oauth_tokenentry underplatform:withrotation_days: 7and correct metadatakubectl get secret gmail-oauth-token -n basketball-api -o jsonpath='{.data.gmail-westsidebasketball\.json}'returns the updated token (base64-decoded matches the local file)gmail.send,gmail.readonly,gmail.modify,gmail.labels~/secrets/google-oauth/gmail-westsidebasktball.json(missing 'e') and writes to k8s secret keygmail-westsidebasketball.json(correct spelling), matching the existing k8s conventiongmail-oauth-expiryexists interraform/modules/monitoring/main.tfand fires when thegmail-oauth-tokensecret is older than 6 daysgmail-oauth-westsidebasketballsecret deleted frombasketball-apinamespace (onlygmail-oauth-tokenshould remain)Test Expectations
scripts/gmail-reauth.shand verify basketball-api pod restarts with new token--dry-runflag that prints what it would do without mutating k8s stateConstraints
gmail-westsidebasktball.json(missing 'e' in basketball). The k8s secret key isgmail-westsidebasketball.json(correct spelling). The script MUST bridge this naming mismatch explicitly. Do not rename the local file (gmail-mcp writes to it).copy-gmail-oauth) that copies from the read-only secret volume to a writable emptyDir. A rollout restart is required after secret update for the pod to pick up new data.scripts/update-kustomize-tag.shconventions (bash,set -euo pipefail, usage function, color output).Resolved: Convert pal-e-mail to use a k8s secret instead of a PVC for consistency. Separate ticket in pal-e-deployments to handle the migration. This issue covers basketball-api secret update only.
Resolved: Clean up stale gmail-oauth-westsidebasketball secret. The deployment only references gmail-oauth-token. Delete the stale secret as part of this ticket to reduce confusion.
Resolved: Prometheus alerting rule for day-6 token expiry. Add a PrometheusRule resource that fires when the gmail-oauth-token secret is older than 6 days. Ships with this ticket as an additional file target.
Checklist
Related
pal-e-platform— project this affectsforgejo_admin/gmail-mcp#6— SSH reauth tool (prerequisite, done)arch:google-oauth,type:feature,scope:discovered— NOTE: needsstory:platform-reliabilitylabel added (Betty Sue action)review-359-2026-03-27-v2— QA review that identified the broken issue bodyScope Review: NEEDS_REFINEMENT
Review note:
review-359-2026-03-27Template is complete but four issues must be resolved before this ticket is agent-ready.
story:Xlabel. Suggeststory:platform-reliability.gmail-oauth), not a k8s secret. AC #3 says "pal-e-mail secrets if applicable" but doesn't resolve whether the PVC is in scope or needs a separate ticket.gmail-westsidebasktball.json(typo, no 'e') vs k8s secretgmail-oauth-westsidebasketball(correct spelling). Must be explicitly documented in Constraints so the agent handles the mapping correctly.Additionally: two k8s secrets exist in basketball-api (
gmail-oauth-tokenandgmail-oauth-westsidebasketball) — clarify whether both are active or one is stale.Issue body updated per scope review corrections.
Scope Review: BLOCK
Review note:
review-359-2026-03-27-v2Issue body is the literal string
$NEW_BODY— a shell variable that was never interpolated. No spec exists for an agent to work from.Prior review (
review-359-2026-03-27) found NEEDS_REFINEMENT with 4 issues. A subsequent "Issue body updated" comment did not actually update the body — the broken$NEW_BODYstring remains. All original spec content has been lost.template-issue-feature. Prior review documents what the original content covered.[LABEL]Addstory:platform-reliabilitylabel to board item #359[BODY]Specify day-6 alerting mechanism (Prometheus rule, CronJob, or Salt job) with file target path[BODY]Clarify pal-e-mail sync path — uses PVCgmail-oauth, not a k8s secret[BODY]Documentgmail-westsidebasktball.json(typo) vsgmail-oauth-westsidebasketball(correct) naming mismatch in Constraints[SCOPE]Clarify whether both basketball-api secrets (gmail-oauth-token+gmail-oauth-westsidebasketball) are active or one is staleScope Review: NEEDS_REFINEMENT
Review note:
review-359-2026-03-27-v3Body rewrite is solid — all template sections present, 3 prior decisions resolved, file targets verified. Three mechanical fixes remain before READY:
[LABEL]Addstory:platform-reliabilitylabel to board item #359 (carried from v1+v2, still missing)[BODY]Addterraform/modules/monitoring/main.tfto File Targets — the "Resolved" section commits to a PrometheusRule but the File Targets section omits it[BODY]Add 2 missing ACs: (a) PrometheusRulegmail-oauth-expiryexists in monitoring namespace; (b) stale secretgmail-oauth-westsidebasketballdeleted from basketball-api namespaceNo human decisions needed — all three are mechanical. Once applied, this ticket is READY.
Scope Review: READY (v4)
Review note:
review-359-2026-03-27-v4All 3 v3 mechanical fixes confirmed applied: monitoring/main.tf in File Targets, PrometheusRule AC, stale secret deletion AC. All 7 ACs are concrete and agent-executable. 3 file targets verified against live codebase and k8s cluster.
[LABEL](non-blocking) Addstory:platform-reliabilitylabel to board item #359 before moving tonext_up. Issue body already flags this as a Betty Sue action.This ticket is ready for agent execution.