08bb0d51b2f63fd4a0fd5ac467fb709c11881c0c
Add README.md with decision matrix, step-by-step provisioning flows, security and compliance checklist, and rollback plan. Add helper scripts: - oauth_token_exchange.py: obtains and outputs a refresh token - gmail_health_check.py: validates API or IMAP connectivity Co-Authored-By: Paperclip <noreply@paperclip.ing>
Gmail OAuth / App Password Provisioning Guide
Scope
This guide documents how the CTO or Chairman provisions OAuth 2.0 or App Password access to the jonathan@cloudinit.dev Google Workspace Gmail account, so that the MAILROOM_AUTOMATION ingestion pipeline can fetch mail in a secure, auditable way.
Decision Matrix
| Path | When to use | Scope | Rotation |
|---|---|---|---|
| OAuth 2.0 (recommended) | Production, long-lived automation | gmail.readonly only |
Refresh token rotation on suspicion or schedule |
| App Password | Fallback / legacy IMAP systems | Full mailbox via IMAP | Revoke the App Password and generate a new one |
OAuth 2.0 Flow (Recommended)
1. Register a Google Cloud project (or reuse an existing one)
- Console: https://console.cloud.google.com/
- Ensure the project belongs to the same Workspace org as
jonathan@cloudinit.dev.
2. Enable the Gmail API
- APIs & Services → Library → Gmail API → Enable.
3. Configure the OAuth consent screen
- APIs & Services → OAuth consent screen → Internal (since this is a Workspace-hosted account).
- Add the following scope:
https://www.googleapis.com/auth/gmail.readonly(least privilege).
4. Create OAuth 2.0 credentials
- APIs & Services → Credentials → Create Credentials → OAuth client ID.
- Application type: Desktop app (or “Other non-UI” if offered).
- Download the JSON client secrets file and place it in a secrets manager (do NOT commit it).
5. Obtain a refresh token
- Run the helper at
scripts/oauth_token_exchange.pyto start the OAuth consent flow. - Authenticate as
jonathan@cloudinit.dev. - Authorize the
gmail.readonlyscope. - The script outputs a
refresh_token; store it as a runtime secret (e.g., Gitea secret / vault).
6. Token hygiene
- Rotate the refresh token quarterly or on any security alert.
- To revoke, delete the token in the Google Account security settings.
7. IMAP enablement
- The Gmail API path does not require IMAP to be enabled.
- If you also need legacy IMAP (for testing or a dual path), keep the App Password section in mind as a fallback.
App Password Flow (Fallback / IMAP)
1. Enable 2-Step Verification
- https://myaccount.google.com/security → 2-Step Verification → On.
2. Generate an App Password
- https://myaccount.google.com/apppasswords
- Select app: Mail (or choose “Other” and name it
mailroom-automation-imap). - Copy the 16-character password and store it as a secret immediately. It will not be shown again.
3. IMAP configuration
- Gmail IMAP host:
imap.gmail.com - Port:
993 - TLS/SSL: Required
- Username:
jonathan@cloudinit.dev - Password: the 16-character App Password
4. Validate connectivity
- Use
scripts/gmail_health_check.py --mode imapto verify the connection without touching the actual ingestion pipeline.
5. Least privilege for IMAP
- App Passwords grant full mailbox IMAP access. Use this path only if the OAuth 2.0 Gmail API path is infeasible.
- Restrict by filtering folders in the mail fetcher rules after connection.
Security & Compliance
- Secrets: Never commit
client_secret.json, refresh tokens, or App Passwords in plain text. - Rotation plan: Quarterly rotation for OAuth refresh tokens; on-demand for App Passwords.
- Rollback: Remove/revoke the OAuth client in Google Cloud Credentials or delete the App Password in Google Account settings. No code redeploy needed because credentials are injected at runtime.
- Audit: Log every token exchange attempt and every health check run (see script exit codes).
- Access model: Automation credentials should be tied to a service account or a delegated admin account, not a personal account, where possible. Discuss with Cybersecurity-Board-Member if a dedicated service account is preferred.
Helper Scripts
scripts/oauth_token_exchange.py
Performs the OAuth consent flow for a Desktop app client ID and saves the refresh token.
Usage:
export GMAIL_CLIENT_SECRET_PATH=/run/secrets/gmail_client_secret.json
python scripts/oauth_token_exchange.py
Exit codes:
0— success, token written to stdout and optionally a file1— missing client secret2— network or Google API error
scripts/gmail_health_check.py
Validates connectivity via Gmail API (OAuth) or IMAP (App Password).
Usage:
# OAuth mode
export GMAIL_REFRESH_TOKEN="1//..."
export GMAIL_CLIENT_SECRET_PATH=/run/secrets/gmail_client_secret.json
python scripts/gmail_health_check.py --mode oauth
# IMAP mode
export GMAIL_APP_PASSWORD="xxxx xxxx xxxx xxxx"
python scripts/gmail_health_check.py --mode imap --user jonathan@cloudinit.dev
Exit codes:
0— connectivity verified, mailbox reachable1— credential or config missing/unreadable2— network or authentication failure3— mailbox accessible but unexpected folder structure (flag for review)
Rollback Plan
| What changed | How to revert | Time to revert |
|---|---|---|
| OAuth client ID created | Delete client ID in Google Cloud Credentials | Immediate |
| Refresh token issued | Revoke token in Google Account → Third-party apps | Immediate |
| App Password created | Delete App Password in Google Account settings | Immediate |
| Gitea secret updated | Overwrite secret in Gitea with dummy value or delete | Immediate |
Next Steps
- Cybersecurity-Board-Member reviews this guide and confirms the chosen credential path.
- The approved credential is stored in Gitea secrets or an external vault.
- Ingestion pipeline references the secret via environment variable.
- Onboarding test: run
gmail_health_check.pyin the target environment before enabling the full fetcher loop.
Revision History
v1— Initial guide (OAuth + App Password, helper scripts, security checklist)
Description
Languages
Python
100%