Skip to content

feat(auth): add Google sign-in#1478

Open
VishnuM049 wants to merge 2 commits into
mainfrom
appy/google-oauth
Open

feat(auth): add Google sign-in#1478
VishnuM049 wants to merge 2 commits into
mainfrom
appy/google-oauth

Conversation

@VishnuM049

@VishnuM049 VishnuM049 commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Purpose / Description

Adds Google as a first-class sign-in option for self-hosted Observal. Admins drop in their OAuth client ID and secret (and, if they want, an email-domain allowlist) and a real "Sign in with Google" button shows up on the login page. It coexists with the existing generic OIDC slot, so an org running Okta or Keycloak can keep that and offer Google on the same screen.

The motivation: the generic OIDC slot already technically supports Google (point it at accounts.google.com/.well-known/openid-configuration and it works), but the button just says "Sign in with SSO". That's fine for one internal IdP and confusing for everyone else. Making Google a named provider gets us a branded button, lets it sit alongside the custom OIDC, and gives us a clean place to plug in Google-specific checks like email_verified and hd-style domain restrictions.

Fixes

  • Supersedes feat(auth): add Google sign-in #1411
  • Fixes deployment.frontend_url default missing :3000 (caused redirect_uri_mismatch on fresh deployments)
  • Fixes login page showing broken "Sign in with SSO" button in ssoOnly mode when only Google is configured

Approach

Backend. A second Authlib client called "google" with the discovery URL hardcoded server-side, so admins only ever set client ID + secret. Two new routes — /api/v1/auth/oauth/google/login and /api/v1/auth/oauth/google/callback — handle the redirect dance.

The duplicated bits from the existing /oauth/callback are pulled into shared helpers (_provision_sso_user and _complete_sso_login) so the Google route reuses them instead of copy-pasting. The generic OIDC callback now also records auth_provider and sso_subject_id on the user row, which it wasn't doing before.

Ordering fix: the SSO_SUCCESS audit event now fires after the DB commit. Before, a failed commit would still log a success.

The Google route adds two checks the generic OIDC doesn't have: it requires Google's email_verified claim to be true, and if GOOGLE_OAUTH_ALLOWED_DOMAINS is set (comma-separated list like acme.com,acme.io), it rejects anything outside the list with a 403 + audit event.

Frontend. /api/v1/config/public exposes a new google_sso_enabled flag. The useDeploymentConfig hook surfaces it. The login page renders a "Sign in with Google" button with an inline SVG Google "G" icon.

Self-hosting. .env.example documents the three new variables. GCP Terraform threads the client ID and secret through Secret Manager and exposes the allowlist as a plain Cloud Run env var. AWS-EC2 uses the existing env_overrides map. Docker-compose pulls from .env directly.

Docs. docs/self-hosting/authentication.md got a new "Google OAuth (first-class provider)" subsection with the GCP Console steps, redirect URI, allowlist behavior, and first-login notes.

No DB migration. User.auth_provider and User.sso_subject_id columns already exist from the SSO work.

How Has This Been Tested?

pytest tests/test_google_oauth.py -v   # 27 tests pass

End-to-end tested with real GCP OAuth credentials on localhost: button renders, Google redirect works, user auto-created on first sign-in, lands in the app authenticated.

Screenshots

image image image image

Checklist

  • You have a descriptive commit message with a short title (first line, max 50 chars).
  • You have commented your code, particularly in hard-to-understand areas
  • You have performed a self-review of your own code
  • UI changes: include screenshots of all affected screens (in particular showing any new or changed strings)

AI Assistance

  • Yes(Please Specify the tool): Claude Code
  • Was the generated code manually reviewed and tested?

Adds Google OAuth alongside the existing generic OIDC slot so an org can
offer both (e.g. Okta for employees + Google for external collaborators).

Backend: Authlib client registered at startup when GOOGLE_OAUTH_CLIENT_ID
and GOOGLE_OAUTH_CLIENT_SECRET are set. Two routes handle the redirect
dance. Shared helpers (_provision_sso_user, _complete_sso_login,
_start_oauth_flow) eliminate duplication with the existing OIDC callback.
Google-specific checks: email_verified enforcement and optional domain
allowlist via GOOGLE_OAUTH_ALLOWED_DOMAINS.

Frontend: /config/public exposes google_sso_enabled flag. Login page
renders a branded "Sign in with Google" button when the flag is true.

Infra: GCP Terraform threads client ID/secret through Secret Manager;
AWS EC2 uses env_overrides; docker-compose inherits from .env.

Co-Authored-By: Apoorv Garg <apoorvgarg.work@gmail.com>
@github-actions github-actions Bot added server Pull request touches server code tests Pull request adds or modifies tests web Pull request touches web frontend code labels Jun 20, 2026
@github-actions

Copy link
Copy Markdown

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.37500% with 15 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
observal-server/api/routes/auth.py 84.44% 14 Missing ⚠️
observal-server/config.py 80.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

server Pull request touches server code tests Pull request adds or modifies tests web Pull request touches web frontend code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant