terraform.tfvars or written dynamically at runtime when users connect their Gmail accounts.
Secret types
Two categories of secrets are used by the Gmail OAuth integration:gmail/user/{user_id}
Per-user OAuth token bundle. Written at runtime when a user connects their Gmail account. Read by every Lambda that accesses the Gmail API.
Google-OAuth-Client-ID
The iOS OAuth client ID from Google Cloud Console. Defined in Terraform and deployed once. Read by Lambda functions when building OAuth credentials for token refresh.
gmail/user/{user_id}
This secret is created or updated by the gmail_store_tokens Lambda each time a user connects (or reconnects) their Gmail account. It is also updated automatically whenever an access token is refreshed.
The secret stores a JSON object with the following shape:
example secret value
Google-OAuth-Client-ID
This secret holds the iOS OAuth client ID string. It is defined in Terraform and its value is supplied via terraform.tfvars.
Terraform configuration
The Secrets Manager resources for credentials are defined insecrets.tf:
secrets.tf
var.google_oauth_client_id variable is sourced from terraform.tfvars, which is listed in .gitignore. Per-user OAuth secrets (gmail/user/{user_id}) are not defined in Terraform — they are created and managed entirely at runtime by the application.
Reading and writing secrets from Python
All Secrets Manager operations go throughsecretsmanager_utils.py in the common Lambda layer.
Storing OAuth tokens
store_oauth_tokens is called by the gmail_store_tokens Lambda after a user grants consent. It updates the secret if it already exists, or creates it if this is the user’s first connection:
secretsmanager_utils.py
Retrieving OAuth tokens
get_oauth_tokens reads the token bundle and annotates it with is_expired: True if the access token has passed its expires_at timestamp:
secretsmanager_utils.py
Updating tokens after refresh
update_oauth_tokens is called by create_gmail_service after a successful token refresh. It preserves the existing scope and Google user info while writing a new access_token and expires_at:
secretsmanager_utils.py
Deleting tokens
delete_oauth_tokens is called when a refresh token is found to be expired or revoked, forcing the user to reconnect. It uses ForceDeleteWithoutRecovery=True to bypass the 30-day recovery window:
secretsmanager_utils.py
Initial secret values with terraform.tfvars
TheGoogle-OAuth-Client-ID secret value is injected at deploy time via a terraform.tfvars file:
terraform.tfvars (example — do not commit real values)
.gitignore and must never be committed to the repository. Each developer or CI environment provides its own copy of terraform.tfvars when running terraform apply.
Per-user secrets (
gmail/user/{user_id}) are not created by Terraform. They are written at runtime by the gmail_store_tokens Lambda the first time a user connects their Gmail account, and are updated automatically whenever tokens are refreshed.