Skip to content

pywry.auth.providers

OAuth2 provider abstractions and concrete implementations.


OAuthProvider (ABC)

pywry.auth.providers.OAuthProvider

OAuthProvider(client_id: str, client_secret: str = '', scopes: list[str] | None = None, authorize_url: str = '', token_url: str = '', userinfo_url: str = '', revocation_url: str = '')

Bases: ABC

Abstract base class for OAuth2 providers.

Parameters:

Name Type Description Default
client_id str

The OAuth2 client ID.

required
client_secret str

The OAuth2 client secret (empty string for public clients).

''
scopes list[str]

Requested OAuth2 scopes.

None
authorize_url str

The provider's authorization endpoint.

''
token_url str

The provider's token exchange endpoint.

''
userinfo_url str

The provider's userinfo endpoint (optional for non-OIDC).

''
revocation_url str

The provider's token revocation endpoint (RFC 7009).

''

Attributes:

Name Type Description
client_id str

OAuth2 client identifier registered with the provider.

client_secret str

Client secret or empty string for public clients.

scopes list[str]

Scopes requested during the authorization flow.

authorize_url str

Provider authorization endpoint.

token_url str

Provider token endpoint.

userinfo_url str

Provider userinfo endpoint, if supported.

revocation_url str

Provider token revocation endpoint, if supported.

Initialize an OAuth provider.

Parameters:

Name Type Description Default
client_id str

OAuth2 client identifier.

required
client_secret str

OAuth2 client secret for confidential clients.

''
scopes list[str] | None

Requested scopes for authorization.

None
authorize_url str

Authorization endpoint.

''
token_url str

Token endpoint.

''
userinfo_url str

Userinfo endpoint.

''
revocation_url str

Token revocation endpoint.

''

Functions

close async

close() -> None

Close the shared HTTP client.

Notes

Call this from application shutdown hooks to release open sockets.

build_authorize_url

build_authorize_url(redirect_uri: str, state: str, pkce: PKCEChallenge | None = None, extra_params: dict[str, str] | None = None) -> str

Build the full authorization URL.

Parameters:

Name Type Description Default
redirect_uri str

The callback URL to redirect to after authorization.

required
state str

CSRF protection nonce.

required
pkce PKCEChallenge

PKCE challenge for public clients.

None
extra_params dict

Additional query parameters.

None

Returns:

Type Description
str

The full authorization URL.

exchange_code abstractmethod async

exchange_code(code: str, redirect_uri: str, pkce_verifier: str | None = None, nonce: str | None = None) -> OAuthTokenSet

Exchange authorization code for tokens.

Parameters:

Name Type Description Default
code str

The authorization code from the callback.

required
redirect_uri str

The redirect URI used in the authorization request.

required
pkce_verifier str

The PKCE code verifier if PKCE was used.

None
nonce str

The nonce sent in the authorize request (for ID token validation).

None

Returns:

Type Description
OAuthTokenSet

The token set from the provider.

Raises:

Type Description
TokenError

If the code exchange fails.

refresh_tokens abstractmethod async

refresh_tokens(refresh_token: str) -> OAuthTokenSet

Refresh an expired access token.

Parameters:

Name Type Description Default
refresh_token str

The refresh token.

required

Returns:

Type Description
OAuthTokenSet

A new token set with a fresh access token.

Raises:

Type Description
TokenRefreshError

If the refresh fails.

get_userinfo async

get_userinfo(access_token: str) -> dict[str, Any]

Fetch user profile information from the provider.

Parameters:

Name Type Description Default
access_token str

A valid access token.

required

Returns:

Type Description
dict[str, Any]

User profile data from the provider.

Raises:

Type Description
HTTPError

Raised when the userinfo endpoint returns an error response.

revoke_token async

revoke_token(token: str) -> bool

Revoke a token at the provider (RFC 7009).

Posts to the revocation_url if one is configured. Subclasses with non-standard revocation APIs should override.

Parameters:

Name Type Description Default
token str

The token to revoke (access or refresh).

required

Returns:

Type Description
bool

True if revocation succeeded, False if no endpoint is configured or the request failed.


GenericOIDCProvider

pywry.auth.providers.GenericOIDCProvider

GenericOIDCProvider(client_id: str, client_secret: str = '', issuer_url: str = '', scopes: list[str] | None = None, authorize_url: str = '', token_url: str = '', userinfo_url: str = '', revocation_url: str = '', *, require_id_token_validation: bool = True)

Bases: OAuthProvider

Generic OpenID Connect provider.

Supports auto-discovery from /.well-known/openid-configuration if an issuer_url is provided.

Parameters:

Name Type Description Default
client_id str

The OAuth2 client ID.

required
client_secret str

The OAuth2 client secret.

''
issuer_url str

The OIDC issuer URL (used for auto-discovery).

''
scopes list[str]

Requested scopes (defaults to ["openid", "email", "profile"]).

None

Attributes:

Name Type Description
issuer_url str

Base issuer URL used for OIDC discovery and issuer validation.

require_id_token_validation bool

Controls whether ID tokens are validated after token exchange.

Initialize a generic OIDC provider.

Parameters:

Name Type Description Default
client_id str

OAuth2 client identifier.

required
client_secret str

OAuth2 client secret.

''
issuer_url str

OIDC issuer URL used for discovery.

''
scopes list[str] | None

Requested scopes.

None
authorize_url str

Explicit authorization endpoint override.

''
token_url str

Explicit token endpoint override.

''
userinfo_url str

Explicit userinfo endpoint override.

''
revocation_url str

Explicit revocation endpoint override.

''
require_id_token_validation bool

Whether exchanged ID tokens must be validated.

True

Functions

validate_id_token async

validate_id_token(id_token: str, nonce: str | None = None) -> dict[str, Any]

Validate an OIDC ID token.

Checks signature (via JWKS), issuer, audience, expiry, and nonce.

Parameters:

Name Type Description Default
id_token str

The raw ID token JWT string.

required
nonce str

Expected nonce value (if one was sent in the authorize request).

None

Returns:

Type Description
dict[str, Any]

The validated claims from the ID token.

Raises:

Type Description
TokenError

If validation fails for any reason.

exchange_code async

exchange_code(code: str, redirect_uri: str, pkce_verifier: str | None = None, nonce: str | None = None) -> OAuthTokenSet

Exchange authorization code for tokens via OIDC token endpoint.

Parameters:

Name Type Description Default
code str

The authorization code from the callback.

required
redirect_uri str

The redirect URI used in the authorization request.

required
pkce_verifier str

The PKCE code verifier if PKCE was used.

None
nonce str

The nonce sent in the authorize request (for ID token validation).

None

Returns:

Type Description
OAuthTokenSet

Token set returned by the OIDC provider.

Raises:

Type Description
TokenError

Raised when discovery fails, the token endpoint is unavailable, or the token exchange response is invalid.

refresh_tokens async

refresh_tokens(refresh_token: str) -> OAuthTokenSet

Refresh tokens via the OIDC token endpoint.

Parameters:

Name Type Description Default
refresh_token str

Refresh token previously issued by the provider.

required

Returns:

Type Description
OAuthTokenSet

Refreshed token set from the provider.

Raises:

Type Description
TokenRefreshError

Raised when discovery or the refresh request fails.

revoke_token async

revoke_token(token: str) -> bool

Revoke a token via the OIDC revocation endpoint.

Triggers endpoint auto-discovery before delegating to the base implementation.

Parameters:

Name Type Description Default
token str

Access or refresh token to revoke.

required

Returns:

Type Description
bool

True when the provider accepted the revocation request.

close async

close() -> None

Close the shared HTTP client.

Notes

Call this from application shutdown hooks to release open sockets.

build_authorize_url

build_authorize_url(redirect_uri: str, state: str, pkce: PKCEChallenge | None = None, extra_params: dict[str, str] | None = None) -> str

Build the full authorization URL.

Parameters:

Name Type Description Default
redirect_uri str

The callback URL to redirect to after authorization.

required
state str

CSRF protection nonce.

required
pkce PKCEChallenge

PKCE challenge for public clients.

None
extra_params dict

Additional query parameters.

None

Returns:

Type Description
str

The full authorization URL.

get_userinfo async

get_userinfo(access_token: str) -> dict[str, Any]

Fetch user profile information from the provider.

Parameters:

Name Type Description Default
access_token str

A valid access token.

required

Returns:

Type Description
dict[str, Any]

User profile data from the provider.

Raises:

Type Description
HTTPError

Raised when the userinfo endpoint returns an error response.


GoogleProvider

pywry.auth.providers.GoogleProvider

GoogleProvider(client_id: str, client_secret: str = '', scopes: list[str] | None = None)

Bases: GenericOIDCProvider

Google OAuth2 provider with preset endpoints.

Parameters:

Name Type Description Default
client_id str

Google OAuth2 client ID.

required
client_secret str

Google OAuth2 client secret.

''
scopes list[str]

Requested scopes (defaults to openid, email, profile).

None
Notes

Google authorization requests default to offline access and consent prompts so refresh tokens are returned consistently.

Initialize the Google OAuth provider.

Parameters:

Name Type Description Default
client_id str

Google OAuth client ID.

required
client_secret str

Google OAuth client secret.

''
scopes list[str] | None

Requested scopes.

None

Functions

build_authorize_url

build_authorize_url(redirect_uri: str, state: str, pkce: PKCEChallenge | None = None, extra_params: dict[str, str] | None = None) -> str

Build a Google authorization URL with offline access defaults.

Parameters:

Name Type Description Default
redirect_uri str

Callback URL registered with the provider.

required
state str

CSRF state token.

required
pkce PKCEChallenge | None

PKCE challenge for public clients.

None
extra_params dict[str, str] | None

Additional query parameters to merge into the request.

None

Returns:

Type Description
str

Fully qualified Google authorization URL.

close async

close() -> None

Close the shared HTTP client.

Notes

Call this from application shutdown hooks to release open sockets.

exchange_code async

exchange_code(code: str, redirect_uri: str, pkce_verifier: str | None = None, nonce: str | None = None) -> OAuthTokenSet

Exchange authorization code for tokens via OIDC token endpoint.

Parameters:

Name Type Description Default
code str

The authorization code from the callback.

required
redirect_uri str

The redirect URI used in the authorization request.

required
pkce_verifier str

The PKCE code verifier if PKCE was used.

None
nonce str

The nonce sent in the authorize request (for ID token validation).

None

Returns:

Type Description
OAuthTokenSet

Token set returned by the OIDC provider.

Raises:

Type Description
TokenError

Raised when discovery fails, the token endpoint is unavailable, or the token exchange response is invalid.

refresh_tokens async

refresh_tokens(refresh_token: str) -> OAuthTokenSet

Refresh tokens via the OIDC token endpoint.

Parameters:

Name Type Description Default
refresh_token str

Refresh token previously issued by the provider.

required

Returns:

Type Description
OAuthTokenSet

Refreshed token set from the provider.

Raises:

Type Description
TokenRefreshError

Raised when discovery or the refresh request fails.

get_userinfo async

get_userinfo(access_token: str) -> dict[str, Any]

Fetch user profile information from the provider.

Parameters:

Name Type Description Default
access_token str

A valid access token.

required

Returns:

Type Description
dict[str, Any]

User profile data from the provider.

Raises:

Type Description
HTTPError

Raised when the userinfo endpoint returns an error response.

revoke_token async

revoke_token(token: str) -> bool

Revoke a token via the OIDC revocation endpoint.

Triggers endpoint auto-discovery before delegating to the base implementation.

Parameters:

Name Type Description Default
token str

Access or refresh token to revoke.

required

Returns:

Type Description
bool

True when the provider accepted the revocation request.

validate_id_token async

validate_id_token(id_token: str, nonce: str | None = None) -> dict[str, Any]

Validate an OIDC ID token.

Checks signature (via JWKS), issuer, audience, expiry, and nonce.

Parameters:

Name Type Description Default
id_token str

The raw ID token JWT string.

required
nonce str

Expected nonce value (if one was sent in the authorize request).

None

Returns:

Type Description
dict[str, Any]

The validated claims from the ID token.

Raises:

Type Description
TokenError

If validation fails for any reason.


GitHubProvider

pywry.auth.providers.GitHubProvider

GitHubProvider(client_id: str, client_secret: str = '', scopes: list[str] | None = None)

Bases: OAuthProvider

GitHub OAuth2 provider.

GitHub uses a non-standard token exchange (no OIDC) and a separate API endpoint for user info.

Parameters:

Name Type Description Default
client_id str

GitHub OAuth2 client ID.

required
client_secret str

GitHub OAuth2 client secret.

''
scopes list[str]

Requested scopes (defaults to ["read:user", "user:email"]).

None
Notes

GitHub is not OIDC-based here, so token exchange and revocation use provider-specific endpoints and payloads.

Initialize the GitHub OAuth provider.

Parameters:

Name Type Description Default
client_id str

GitHub OAuth application client ID.

required
client_secret str

GitHub OAuth application client secret.

''
scopes list[str] | None

Requested scopes.

None

Functions

exchange_code async

exchange_code(code: str, redirect_uri: str, pkce_verifier: str | None = None, nonce: str | None = None) -> OAuthTokenSet

Exchange an authorization code for a GitHub access token.

Parameters:

Name Type Description Default
code str

Authorization code returned by GitHub.

required
redirect_uri str

Redirect URI used during authorization.

required
pkce_verifier str | None

Present for interface compatibility; GitHub ignores it here.

None
nonce str | None

Present for interface compatibility; GitHub does not use it.

None

Returns:

Type Description
OAuthTokenSet

Token set derived from GitHub's token response.

Raises:

Type Description
TokenError

Raised when the exchange request fails or GitHub returns an error payload.

refresh_tokens async

refresh_tokens(refresh_token: str) -> OAuthTokenSet

Refresh GitHub tokens using GitHub's refresh-token flow.

Parameters:

Name Type Description Default
refresh_token str

Refresh token issued by GitHub.

required

Returns:

Type Description
OAuthTokenSet

Refreshed token set from GitHub.

Raises:

Type Description
TokenRefreshError

Raised when the refresh request fails or GitHub returns an error payload.

revoke_token async

revoke_token(token: str) -> bool

Revoke a GitHub token via the Applications API.

Uses DELETE /applications/{client_id}/token with HTTP Basic authentication (client_id / client_secret).

Parameters:

Name Type Description Default
token str

The access token to revoke.

required

Returns:

Type Description
bool

True if GitHub accepted the revocation.

close async

close() -> None

Close the shared HTTP client.

Notes

Call this from application shutdown hooks to release open sockets.

build_authorize_url

build_authorize_url(redirect_uri: str, state: str, pkce: PKCEChallenge | None = None, extra_params: dict[str, str] | None = None) -> str

Build the full authorization URL.

Parameters:

Name Type Description Default
redirect_uri str

The callback URL to redirect to after authorization.

required
state str

CSRF protection nonce.

required
pkce PKCEChallenge

PKCE challenge for public clients.

None
extra_params dict

Additional query parameters.

None

Returns:

Type Description
str

The full authorization URL.

get_userinfo async

get_userinfo(access_token: str) -> dict[str, Any]

Fetch user profile information from the provider.

Parameters:

Name Type Description Default
access_token str

A valid access token.

required

Returns:

Type Description
dict[str, Any]

User profile data from the provider.

Raises:

Type Description
HTTPError

Raised when the userinfo endpoint returns an error response.


MicrosoftProvider

pywry.auth.providers.MicrosoftProvider

MicrosoftProvider(client_id: str, client_secret: str = '', tenant_id: str = 'common', scopes: list[str] | None = None)

Bases: GenericOIDCProvider

Microsoft / Azure AD OAuth2 provider.

Parameters:

Name Type Description Default
client_id str

Azure AD application (client) ID.

required
client_secret str

Azure AD client secret.

''
tenant_id str

Azure AD tenant ID (default "common" for multi-tenant).

'common'
scopes list[str]

Requested scopes.

None

Attributes:

Name Type Description
tenant_id str

Azure AD tenant identifier used to build authorize and token endpoints.

Initialize the Microsoft OAuth provider.

Parameters:

Name Type Description Default
client_id str

Azure AD application client ID.

required
client_secret str

Azure AD client secret.

''
tenant_id str

Azure AD tenant identifier.

'common'
scopes list[str] | None

Requested scopes.

None

Functions

close async

close() -> None

Close the shared HTTP client.

Notes

Call this from application shutdown hooks to release open sockets.

build_authorize_url

build_authorize_url(redirect_uri: str, state: str, pkce: PKCEChallenge | None = None, extra_params: dict[str, str] | None = None) -> str

Build the full authorization URL.

Parameters:

Name Type Description Default
redirect_uri str

The callback URL to redirect to after authorization.

required
state str

CSRF protection nonce.

required
pkce PKCEChallenge

PKCE challenge for public clients.

None
extra_params dict

Additional query parameters.

None

Returns:

Type Description
str

The full authorization URL.

exchange_code async

exchange_code(code: str, redirect_uri: str, pkce_verifier: str | None = None, nonce: str | None = None) -> OAuthTokenSet

Exchange authorization code for tokens via OIDC token endpoint.

Parameters:

Name Type Description Default
code str

The authorization code from the callback.

required
redirect_uri str

The redirect URI used in the authorization request.

required
pkce_verifier str

The PKCE code verifier if PKCE was used.

None
nonce str

The nonce sent in the authorize request (for ID token validation).

None

Returns:

Type Description
OAuthTokenSet

Token set returned by the OIDC provider.

Raises:

Type Description
TokenError

Raised when discovery fails, the token endpoint is unavailable, or the token exchange response is invalid.

refresh_tokens async

refresh_tokens(refresh_token: str) -> OAuthTokenSet

Refresh tokens via the OIDC token endpoint.

Parameters:

Name Type Description Default
refresh_token str

Refresh token previously issued by the provider.

required

Returns:

Type Description
OAuthTokenSet

Refreshed token set from the provider.

Raises:

Type Description
TokenRefreshError

Raised when discovery or the refresh request fails.

get_userinfo async

get_userinfo(access_token: str) -> dict[str, Any]

Fetch user profile information from the provider.

Parameters:

Name Type Description Default
access_token str

A valid access token.

required

Returns:

Type Description
dict[str, Any]

User profile data from the provider.

Raises:

Type Description
HTTPError

Raised when the userinfo endpoint returns an error response.

revoke_token async

revoke_token(token: str) -> bool

Revoke a token via the OIDC revocation endpoint.

Triggers endpoint auto-discovery before delegating to the base implementation.

Parameters:

Name Type Description Default
token str

Access or refresh token to revoke.

required

Returns:

Type Description
bool

True when the provider accepted the revocation request.

validate_id_token async

validate_id_token(id_token: str, nonce: str | None = None) -> dict[str, Any]

Validate an OIDC ID token.

Checks signature (via JWKS), issuer, audience, expiry, and nonce.

Parameters:

Name Type Description Default
id_token str

The raw ID token JWT string.

required
nonce str

Expected nonce value (if one was sent in the authorize request).

None

Returns:

Type Description
dict[str, Any]

The validated claims from the ID token.

Raises:

Type Description
TokenError

If validation fails for any reason.


Factory

pywry.auth.providers.create_provider_from_settings

create_provider_from_settings(settings: Any) -> OAuthProvider

Create an OAuthProvider instance from OAuth2Settings.

Parameters:

Name Type Description Default
settings OAuth2Settings

The OAuth2 configuration settings.

required

Returns:

Type Description
OAuthProvider

A configured provider instance.

Raises:

Type Description
AuthenticationError

If the provider type is unknown or settings are invalid.

Notes

The settings object is accessed via getattr so callers may supply configuration objects with compatible attribute names rather than a single concrete settings type.