Skip to content

Add OIDC_SERVER_METADATA_URL to support providers with non-standard discovery URLs (e.g. Google)#3099

Merged
gantoine merged 2 commits intomasterfrom
copilot/fix-oidc-login-google
Mar 9, 2026
Merged

Add OIDC_SERVER_METADATA_URL to support providers with non-standard discovery URLs (e.g. Google)#3099
gantoine merged 2 commits intomasterfrom
copilot/fix-oidc-login-google

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 9, 2026

Google and some other OIDC providers separate the authorization endpoint from the discovery document root, so appending /.well-known/openid-configuration to OIDC_SERVER_APPLICATION_URL produces an invalid URL (404).

Changes

  • backend/config/__init__.py: Added optional OIDC_SERVER_METADATA_URL config variable
  • backend/decorators/auth.py: Use OIDC_SERVER_METADATA_URL directly as server_metadata_url when set; fall back to get_well_known_url(OIDC_SERVER_APPLICATION_URL) when not set

Usage

For Google, set both:

# The authorization endpoint (existing)
OIDC_SERVER_APPLICATION_URL=https://accounts.google.com/o/oauth2/v2/auth

# The discovery document URL (new — required for Google)
OIDC_SERVER_METADATA_URL=https://accounts.google.com/.well-known/openid-configuration

Other providers that already expose their discovery document at {issuer}/.well-known/openid-configuration (e.g. Authentik, Keycloak) are unaffected — OIDC_SERVER_METADATA_URL is optional and defaults to the existing behavior.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug] OIDC login with Google fails</issue_title>
<issue_description>RomM version
4.6.1

Describe the bug
OIDC login with Google Fails

To Reproduce
Steps to reproduce the behavior:

OIDC_REDIRECT_URI
https://myfqdn.com/api/oauth/openid
OIDC_SERVER_APPLICATION_URL
https://accounts.google.com/o/oauth2/v2/auth
Redirect URI is same on Google side
The Login with Google page shows up but when pressed:

2026-02-22 18:35:22.935378+00:00�[32mINFO�[39m: �[34m[RomM]�[95m[_client]�[36m[2026-02-22 10:35:22] �[0mHTTP Request: GET https://accounts.google.com/o/oauth2/v2/auth/.well-known/openid-configuration "HTTP/1.1 404 Not Found"
2026-02-22 18:35:22.937742+00:00�[32mINFO�[39m: �[34m[RomM]�[95m[httptools_impl]�[36m[2026-02-22 10:35:22] �[0m73.164.156.193:0 - "GET /api/login/openid HTTP/1.0" 500
2026-02-22 18:35:23.059252+00:00�[91mERROR�[39m: �[34m[RomM]�[95m[httptools_impl]�[36m[2026-02-22 10:35:23] �[0mException in ASGI application
2026-02-22 18:35:23.059340+00:00Traceback (most recent call last):
2026-02-22 18:35:23.059355+00:00File "/src/.venv/lib/python3.13/site-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
2026-02-22 18:35:23.059368+00:00result = await app( # type: ignore[func-returns-value]
2026-02-22 18:35:23.059389+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059403+00:00self.scope, self.receive, self.send
2026-02-22 18:35:23.059416+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059428+00:00)
2026-02-22 18:35:23.059447+00:00^
2026-02-22 18:35:23.059459+00:00File "/src/.venv/lib/python3.13/site-packages/uvicorn/middleware/proxy_headers.py", line 60, in call
2026-02-22 18:35:23.059487+00:00return await self.app(scope, receive, send)
2026-02-22 18:35:23.059501+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059521+00:00File "/src/.venv/lib/python3.13/site-packages/fastapi/applications.py", line 1134, in call
2026-02-22 18:35:23.059537+00:00await super().call(scope, receive, send)
2026-02-22 18:35:23.059552+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/starlette.py", line 409, in _sentry_patched_asgi_app
2026-02-22 18:35:23.059567+00:00return await middleware(scope, receive, send)
2026-02-22 18:35:23.059590+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059605+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/asgi.py", line 174, in _run_asgi3
2026-02-22 18:35:23.059621+00:00return await self._run_app(scope, receive, send, asgi_version=3)
2026-02-22 18:35:23.059659+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059675+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/asgi.py", line 276, in _run_app
2026-02-22 18:35:23.059691+00:00raise exc from None
2026-02-22 18:35:23.059706+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/asgi.py", line 271, in _run_app
2026-02-22 18:35:23.059731+00:00return await self.app(
2026-02-22 18:35:23.059748+00:00^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059764+00:00scope, receive, _sentry_wrapped_send
2026-02-22 18:35:23.059784+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059809+00:00)
2026-02-22 18:35:23.059826+00:00^
2026-02-22 18:35:23.059841+00:00File "/src/.venv/lib/python3.13/site-packages/starlette/applications.py", line 113, in call
2026-02-22 18:35:23.059857+00:00await self.middleware_stack(scope, receive, send)
2026-02-22 18:35:23.059873+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/starlette.py", line 200, in _create_span_call
2026-02-22 18:35:23.059894+00:00return await old_call(app, scope, new_receive, new_send, **kwargs)
2026-02-22 18:35:23.059903+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059910+00:00File "/src/.venv/lib/python3.13/site-packages/starlette/middleware/errors.py", line 186, in call
2026-02-22 18:35:23.059920+00:00raise exc
2026-02-22 18:35:23.059927+00:00File "/src/.venv/lib/python3.13/site-packages/starlette/middleware/errors.py", line 164, in call
2026-02-22 18:35:23.059933+00:00await self.app(scope, receive, _send)
2026-02-22 18:35:23.059940+00:00File "/src/.venv/lib/python3.13/site-packages/opentelemetry/instrumentation/asgi/init.py", line 768, in call
2026-02-22 18:35:23.059952+00:00await self.app(scope, otel_receive, otel_send)
2026-02-22 18:35:23.059959+00:00File "/src/.venv/lib/python3.13/site-packages/sentry_sdk/integrations/starlette.py", line 200, in _create_span_call
2026-02-22 18:35:23.059965+00:00return await old_call(app, scope, new_receive, new_send, **kwargs)
2026-02-22 18:35:23.059983+00:00^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2026-02-22 18:35:23.059990+00:00File "/src/.venv/lib/python3.13/site-packages/starlette/middleware/errors.py", line 186, in call
2026-02-22...


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Fix OIDC login failure with Google Add OIDC_SERVER_METADATA_URL to support providers with non-standard discovery URLs (e.g. Google) Mar 9, 2026
@gantoine gantoine marked this pull request as ready for review March 9, 2026 22:07
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Test Results (mariadb)

945 tests   944 ✅  2m 14s ⏱️
  1 suites    1 💤
  1 files      0 ❌

Results for commit ff1c8b6.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

Test Results (postgresql)

945 tests   944 ✅  2m 15s ⏱️
  1 suites    1 💤
  1 files      0 ❌

Results for commit ff1c8b6.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 9, 2026

☂️ Python Coverage

current status: ✅

Overall Coverage

Lines Covered Coverage Threshold Status
13813 9264 67% 0% 🟢

New Files

No new covered files...

Modified Files

File Coverage Status
backend/config/_init_.py 99% 🟢
backend/decorators/auth.py 100% 🟢
TOTAL 100% 🟢

updated for commit: ff1c8b6 by action🐍

@greptile-apps
Copy link
Copy Markdown

greptile-apps bot commented Mar 9, 2026

Greptile Summary

This PR successfully fixes OIDC login failures with Google (and similar providers) by introducing an optional OIDC_SERVER_METADATA_URL environment variable. Previously, the discovery URL was always derived by appending /.well-known/openid-configuration to OIDC_SERVER_APPLICATION_URL, which produces a 404 for Google because its authorization endpoint (/o/oauth2/v2/auth) and discovery document root (accounts.google.com) are at different paths.

Key changes:

  • backend/config/__init__.py: Adds OIDC_SERVER_METADATA_URL: Final[str | None] following the established _get_env pattern for optional variables.
  • backend/decorators/auth.py: Prefers OIDC_SERVER_METADATA_URL directly as server_metadata_url when set; falls back to get_well_known_url(OIDC_SERVER_APPLICATION_URL, external=True) otherwise — preserving full backward compatibility for Authentik, Keycloak, and any provider already following the standard discovery URL convention.

Implementation quality: The code is minimal, correct, and low-risk. The logic properly short-circuits using or, so existing deployments without OIDC_SERVER_METADATA_URL set will see no change in behavior.

Confidence Score: 5/5

  • This PR is safe to merge — the change is minimal, backward-compatible, and directly fixes a well-documented bug in OIDC provider compatibility.
  • The implementation is straightforward and correct. Both files are minimal changes that follow established patterns in the codebase. The fallback logic properly preserves existing behavior for current users while enabling Google and similar providers to configure their non-standard discovery URLs. The change directly addresses the issue reported in the bug.
  • No files require special attention; both changes are straightforward and low-risk.

Sequence Diagram

sequenceDiagram
    participant User
    participant RomM as RomM Backend
    participant Env as Environment Variables
    participant Authlib as Authlib OAuth
    participant Provider as OIDC Provider

    Note over RomM,Env: Application startup
    Env-->>RomM: OIDC_SERVER_METADATA_URL (optional)
    Env-->>RomM: OIDC_SERVER_APPLICATION_URL

    alt OIDC_SERVER_METADATA_URL is set (e.g. Google)
        RomM->>Authlib: register(server_metadata_url=OIDC_SERVER_METADATA_URL)
        Note right of RomM: e.g. https://accounts.google.com/.well-known/openid-configuration
    else OIDC_SERVER_METADATA_URL is not set (e.g. Authentik, Keycloak)
        RomM->>Authlib: register(server_metadata_url=get_well_known_url(OIDC_SERVER_APPLICATION_URL))
        Note right of RomM: e.g. https://authentik.example.com/.well-known/openid-configuration
    end

    User->>RomM: GET /api/login/openid
    RomM->>Provider: GET server_metadata_url
    Provider-->>RomM: Discovery document (authorization_endpoint, token_endpoint, etc.)
    RomM-->>User: Redirect to authorization_endpoint
    User->>Provider: Authenticate
    Provider-->>User: Redirect with auth code
    User->>RomM: GET /api/oauth/openid (callback)
    RomM->>Provider: Exchange code for tokens
    Provider-->>RomM: id_token + access_token
    RomM-->>User: Session established
Loading

Last reviewed commit: ff1c8b6

@gantoine gantoine merged commit 9a9d15d into master Mar 9, 2026
11 checks passed
@gantoine gantoine deleted the copilot/fix-oidc-login-google branch March 9, 2026 22:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] OIDC login with Google fails

2 participants