Google federation
Audience
PLANA staff using Google accounts. Tenant users authenticating with Google via PLANA Business Cloud should read Tenant auth for the customer-facing view.
PLANA Pulse federates with Google OAuth 2.0 as an upstream identity provider. Staff and tenant users who have a Google account (Workspace or personal) can click "Sign in with Google" on Authentik or on a PLANA Business Cloud tenant login page and authenticate without entering a password.
Federation was configured on 2026-05-28 with a single Google OAuth client serving every PLANA Pulse service.
Why a single Google client
Earlier we considered one Google OAuth client per service (Forgejo, Grafana, each tenant Odoo, etc.) for token-revocation isolation. We rejected this because:
- Each Google OAuth client requires its own consent screen approval, homepage URL, and privacy policy — high admin overhead.
- The redirect URI list is finite; for hundreds of tenants we'd need hundreds of client IDs.
- Token revocation isolation is largely solved by Authentik's session termination, which we already do at the Authentik layer.
The chosen design: one Google OAuth client, Authentik fans out from there. All services authenticate with Authentik; Authentik authenticates with Google.
The flow
User
│
│ 1. Click "Sign in with Google" on (e.g.) Forgejo
▼
Forgejo ─── 2. OIDC redirect to Authentik ─→ Authentik
│
│ 3. Show "Sign
│ in with Google"
▼
Google OAuth
│
│ 4. User auths
│ with Google
▼
Authentik
┌───────┤
5. Local user lookup / create │ │
▼ │
PostgreSQL │
│
6. id_token ────┘
User │
▲ │
└──── 7. id_token to Forgejo ───┘The Google account's email is matched against an Authentik user. If found, the user is logged in. If not found:
- Staff accounts (email in
*@plana.solutions) are auto-linked if the email matches an existing Authentik user (case-insensitive). - Tenant accounts are auto-linked if
plana_authfinds a matching email on the tenant'sres_users. This is the email-fallback flow inplana_auth v18.0.1.1.0; tenants migrated from earlier versions re-link automatically on first Google login.
The Google OAuth client
| Property | Value |
|---|---|
| Project | plana-pulse-prod in Google Cloud Console |
| Client type | Web application |
| Authorized redirect URI | https://auth.planapulse.com/source/oauth/callback/google/ |
| Consent screen | Configured with PLANA logo, privacy policy URL, terms URL |
| Scopes requested | openid, email, profile |
| Verification status | Verified by Google (production-ready) |
| Client ID + Secret | SOPS authentik.google_oauth_client_id + _client_secret |
One redirect URI for every PLANA Pulse service — possible because every service authenticates through Authentik, not directly to Google.
How tenant auth uses federation
The plana_auth module on each tenant trusts Authentik's id_token. Authentik decides whether the user logged in via password, via TOTP + password, or via Google federation — that's transparent to the tenant.
When a user clicks "Sign in" on a tenant page like https://acme.planapulse.app/web/login:
- The page sends the user to Authentik's authorize endpoint
- Authentik presents its login form, which has a "Sign in with Google" button
- The user can choose: password + TOTP, or Google
- After successful Google auth, Authentik issues an
id_tokenfor the tenant client - The tenant Odoo accepts the token and logs the user into the tenant
The tenant Odoo never sees the Google interaction. From the tenant's perspective, the user authenticated with Authentik.
Migrated tenants and email-fallback
Tenants provisioned before 2026-05-28 didn't have the email-fallback linking logic. When such a tenant migrates to v18 (with the newer plana_auth version), the first Google login automatically links the Authentik user to the existing tenant user record matched by email.
This is in plana_auth v18.0.1.1.0 and later. Earlier plana_auth versions require manual relink:
-- Manually link an Authentik user to an existing tenant user record
UPDATE res_users
SET oauth_uid = '<authentik-user-uuid>',
oauth_provider_id = (SELECT id FROM auth_oauth_provider WHERE name='PLANA Authentik')
WHERE email = '<email>';Operational considerations
Limiting the federation domain
The Google OAuth consent screen accepts any Google account by default (Workspace + personal). To restrict to specific Google Workspace domains, set the hd parameter on the Authentik source configuration:
- For staff-only restriction:
hd=plana.solutions - For per-customer restriction: this requires a separate Authentik source per customer, which we have not done
Currently we allow any Google account because customer tenants need this. Customers whose security model requires single-domain enforcement use password + TOTP instead.
Audit logs
Every Google login appears in Authentik's event log:
Authentik admin → Events → Events → filter by action="login"The event includes the source (google), the user, the client (Forgejo / tenant Odoo / etc.), and the source IP. Events are mirrored to Loki for 90-day retention.
Revoking access for a single user
To prevent a specific Google account from logging in:
- Authentik admin → Users → find the user
- Disable the user (removes all sessions)
Their Google account remains valid for Google's own services; only PLANA access is revoked.
Rotating the Google client secret
Google does not rotate secrets automatically. Annual rotation procedure:
- Google Cloud Console → APIs & Services → Credentials → the OAuth client → "Add secret"
- Update SOPS
authentik.google_oauth_client_secretwith the new value - Reconcile the Authentik secret
- Wait ~5 minutes for Authentik to roll over (or restart the pod)
- Remove the old secret in Google Cloud Console
Schedule rotation for off-peak hours; there's a ~1-minute window during restart when Google logins fail.
Where to read more
- Authentik SSO — the IdP that federates to Google
- Tenant auth — customer-facing auth flow
- Two-factor (TOTP) — Google login + TOTP combined