Skip to content

Add OidcBrowserAuth: browser PKCE and device code login for OIDC providers - #52

Merged
TejasRGitHub merged 2 commits into
data-dot-all:mainfrom
TejasRGitHub:feat/oidc-browser-auth
Sep 25, 2026
Merged

TejasRGitHub merged 2 commits into
data-dot-all:mainfrom
TejasRGitHub:feat/oidc-browser-auth

Conversation

@TejasRGitHub

@TejasRGitHub TejasRGitHub commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Feature or Bugfix

  • Feature

Detail

  • New auth type OidcBrowserAuth for deployments that use an external OIDC provider (Okta and similar) with SSO/MFA, where CustomAuth's username/password to session-token flow cannot be used:
    • Authorization Code + PKCE (S256) through the system browser, receiving the redirect on a loopback URI (redirect_uri, default http://localhost:8765/callback, optional fallback_redirect_uri when the first port is busy). state is checked with a constant-time compare; the wait times out after 5 minutes.
    • Device Authorization Grant (RFC 8628) when no browser can be used: DATAALL_DEVICE_LOGIN=1, an SSH session without DISPLAY, no loopback port available, or webbrowser.open failing. Polls the token endpoint honouring interval and slow_down.
    • Silent renewal with the refresh token (openid offline_access by default). If the provider rejects the requested scopes (invalid_scope, or a policy access_denied) the login is retried once with openid only.
    • Endpoints come from {idp_domain_url}/.well-known/openid-configuration with the same auth_server convention as CustomAuth. Token requests are form-encoded and include client_secret only when the profile has one, so public clients work.
  • Profile: AuthType.OidcBrowser, optional scopes, fallback_redirect_uri, frontend_url. Unset fields are not written, so existing Cognito and Custom profiles are unchanged.
  • BaseClient sends Origin and Referer from frontend_url when it is set. Some deployments front the API with a WAF that only accepts requests carrying the web UI origin. custom_headers still override.
  • AuthorizationClass.get_jwt_token is unchanged; the username/password prompt moved into an overridable _authenticate_interactive() hook, so CognitoAuth and CustomAuth behave exactly as before.
  • New AuthenticationException carrying the provider's error and error_description.
  • Tests: real loopback server on a free port, second-port fallback, device flow (pending, slow_down, expired, denied), refresh success and failure, scope retry, state mismatch, timeout, client_secret handling, profile round trips, _find_authorizer. Verified manually end to end against an Okta custom authorization server (browser login, API call, forced-expiry refresh).
  • The version is not bumped here; the new profile fields warrant a minor bump at release time.

Relates

Security

  • Input: the loopback handler reads only code, state, error and error_description from the query string on the configured callback path, validates state with hmac.compare_digest, and answers with a plain-text body (no user input is rendered as HTML). Provider responses are decoded with httpx's JSON decoder. No eval, no pickle, no database access.
  • AuthN/AuthZ: standard OAuth 2.0 Authorization Code + PKCE (RFC 7636) and Device Authorization Grant (RFC 8628). Tokens are sent as Bearer exactly as the existing auth classes do and are validated by the deployment's API authorizer. Failed logins raise AuthenticationException with the provider's error; refresh failures are logged before falling back to an interactive login.
  • Cryptography: only the standard library, secrets for the verifier and state and hashlib.sha256 for the PKCE challenge. No keys are stored; tokens go to the existing credentials.yaml location.
  • No new policies, roles or users.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

🤖 Generated with Claude Code

…iders

- Authorization Code + PKCE through the system browser on a loopback
  redirect URI, device authorization grant when no browser is available,
  silent renewal with the refresh token
- Profile: OidcBrowser auth type, scopes, fallback_redirect_uri, frontend_url
- BaseClient sends Origin/Referer from frontend_url for WAF-restricted APIs
- AuthenticationException; interactive prompt moved to an overridable hook

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@TejasRGitHub
TejasRGitHub merged commit 7d0c7ea into data-dot-all:main Sep 25, 2026
2 checks passed
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.

1 participant