Authentication
OAuth2 authentication base classes and client implementation.
Auth Base
Authentication provider framework base classes and mixins
Implement custom auth providers by subclassing BaseAuthProvider and, where
appropriate, implementing the HTTPHeadersMixin to supply HTTP headers and
LoginLogoutMixin for interactive flows. Optional TokenMixin defines a
canonical way to expose tokens.
Creating a custom provider (example)::
from typing import Dict, Any
from qlam_core.auth.base import BaseAuthProvider, HTTPHeadersMixin, LoginLogoutMixin
class MyTokenProvider(BaseAuthProvider, HTTPHeadersMixin, LoginLogoutMixin):
name = "mytoken" # used by registry
def __init__(self, context_name: str, token: str | None = None) -> None:
# Expose `context_name` publicly: AuthClient uses it to scope
# registered-provider reuse to the owning context.
self.context_name = context_name
self._token = token
def is_authenticated(self) -> bool:
return bool(self._token)
def get_auth_context(self) -> JsonDict:
return {"context": self.context_name, "has_token": self.is_authenticated()}
def get_headers(self) -> Dict[str, str]:
return {"Authorization": f"Bearer {self._token}"} if self._token else {}
def login(self) -> None:
# Implement a real flow; for example, prompt the user or exchange credentials
self._token = "...obtained..."
Registering the provider:
- Either rely on dynamic discovery in
qlam_core.auth.registryif placed underqlam_core.auth.providers, or callauth_registry.register_factory("mytoken", factory).
BaseAuthProvider
Bases: ABC
flowchart TD
qlam_core.auth.base.BaseAuthProvider[BaseAuthProvider]
click qlam_core.auth.base.BaseAuthProvider href "" "qlam_core.auth.base.BaseAuthProvider"
Abstract base class implementing core AuthProvider interface.
Provides only the required methods - other capabilities are mixed in via protocols.
description
abstractmethod
property
description: str
Human-readable description of this authentication provider.
Returns:
| Type | Description |
|---|---|
str
|
Description suitable for help text and user interfaces. |
build_from_settings
classmethod
build_from_settings(*, context_name: str, provider_name: str | None, provider_config: Any) -> 'BaseAuthProvider'
Create provider instance from settings configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
context_name
|
str
|
Context name for the provider. |
required |
provider_name
|
str | None
|
Optional provider name for identification. |
required |
provider_config
|
Any
|
Provider configuration object from settings. |
required |
Returns:
| Type | Description |
|---|---|
'BaseAuthProvider'
|
Configured provider instance. |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
If provider doesn't implement this method. |
Source code in qlam_core/auth/base.py
128 129 130 131 132 133 134 135 136 137 138 139 140 | |
extra_info_from_config
classmethod
extra_info_from_config(provider_config: Any) -> JsonDict
Extract extra display information from provider configuration.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider_config
|
Any
|
Provider configuration object from settings. |
required |
Returns:
| Type | Description |
|---|---|
JsonDict
|
Dictionary of extra information for display purposes. |
Source code in qlam_core/auth/base.py
142 143 144 145 146 147 148 149 | |
get_auth_context
abstractmethod
get_auth_context() -> JsonDict
Get authentication context for use by clients.
Returns:
| Type | Description |
|---|---|
JsonDict
|
Dictionary describing authentication state and metadata. |
Source code in qlam_core/auth/base.py
75 76 77 78 79 80 81 | |
get_credential
abstractmethod
get_credential() -> CredentialBase | None
Return a credential payload as a Pydantic model.
Providers may return a credential with a non-authenticated status
(e.g. status="Not authenticated") to convey metadata such as
refresh capability. Return None only when the provider has no
credential data at all.
Source code in qlam_core/auth/base.py
83 84 85 86 87 88 89 90 91 92 | |
get_user_info
get_user_info(api_base_url: str, *, timeout: float = 30.0, verify_ssl: bool | str = True, follow_redirects: bool = True, headers: dict[str, str] | None = None) -> UserInfo
Return the current authenticated user profile.
Default raises ConfigurationError with
usage-error semantics. OAuth providers override this to fetch
{api_base_url}/userinfo.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
api_base_url
|
str
|
API base URL used to build the userinfo endpoint. |
required |
timeout
|
float
|
Request timeout in seconds. |
30.0
|
verify_ssl
|
bool | str
|
SSL verification setting or CA bundle path. |
True
|
follow_redirects
|
bool
|
Whether to follow HTTP redirects. |
True
|
headers
|
dict[str, str] | None
|
Non-authentication headers to include in the request. |
None
|
Returns:
| Type | Description |
|---|---|
UserInfo
|
Typed user profile from the identity provider. |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If this provider does not support userinfo lookup. |
Source code in qlam_core/auth/base.py
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | |
is_authenticated
abstractmethod
is_authenticated() -> bool
Check if the provider has valid authentication.
Returns:
| Type | Description |
|---|---|
bool
|
True if authenticated, False otherwise. |
Source code in qlam_core/auth/base.py
67 68 69 70 71 72 73 | |
HTTPHeadersMixin
Bases: Protocol
flowchart TD
qlam_core.auth.base.HTTPHeadersMixin[HTTPHeadersMixin]
click qlam_core.auth.base.HTTPHeadersMixin href "" "qlam_core.auth.base.HTTPHeadersMixin"
Protocol for auth providers that can generate HTTP headers.
This protocol defines the interface for providers that can generate authentication headers for HTTP requests. Implementation is left to the concrete provider classes.
get_headers
get_headers() -> Dict[str, str]
Get authentication headers for HTTP requests.
Returns:
| Type | Description |
|---|---|
Dict[str, str]
|
Dictionary of HTTP headers for authentication |
Source code in qlam_core/auth/base.py
161 162 163 164 165 166 | |
LoginLogoutMixin
Mixin providing default login/logout implementations.
login
login() -> None
Default login implementation (no-op).
Override to implement provider-specific login logic.
Source code in qlam_core/auth/base.py
172 173 174 175 176 177 | |
logout
logout() -> None
Default logout implementation (no-op).
Override to implement provider-specific logout logic.
Source code in qlam_core/auth/base.py
179 180 181 182 183 184 | |
RefreshCredentialsMixin
Bases: ABC
flowchart TD
qlam_core.auth.base.RefreshCredentialsMixin[RefreshCredentialsMixin]
click qlam_core.auth.base.RefreshCredentialsMixin href "" "qlam_core.auth.base.RefreshCredentialsMixin"
Mixin for auth providers that can refresh cached credentials.
Providers that support refresh should inherit this mixin and implement the required methods. This gives us a clear, explicit contract (no attribute introspection needed) and works well with dynamic provider loading.
can_refresh_credentials
abstractmethod
can_refresh_credentials() -> bool
Return True if cached credentials can be refreshed non-interactively right now.
Source code in qlam_core/auth/base.py
216 217 218 | |
refresh_credentials
abstractmethod
refresh_credentials(*, force: bool = False) -> bool
Refresh credentials for this provider, updating the cache if needed.
Source code in qlam_core/auth/base.py
212 213 214 | |
TokenMixin
Bases: Protocol
flowchart TD
qlam_core.auth.base.TokenMixin[TokenMixin]
click qlam_core.auth.base.TokenMixin href "" "qlam_core.auth.base.TokenMixin"
Protocol for token-based authentication providers.
This protocol defines the interface for providers that work with access tokens. Implementation of token management is left to concrete provider classes.
token
token() -> str
Return an access token to be injected into requests.
Returns:
| Type | Description |
|---|---|
str
|
Access token string. |
Source code in qlam_core/auth/base.py
196 197 198 199 200 201 | |
supports_refresh_credentials
supports_refresh_credentials(provider: object) -> bool
Return True if provider supports non-interactive credential refresh.
Note
This is intentionally a contract-based check: refresh-capable providers must
inherit RefreshCredentialsMixin.
Source code in qlam_core/auth/base.py
221 222 223 224 225 226 227 228 | |
Auth Client
AuthClient - programmatic authentication operations.
This module defines the programmatic API for authentication management, designed for use by any consumer (Bloqade, web apps, notebooks, CLI shells).
Usage: from qlam_core.auth.client import AuthClient from qlam_core.common.context import AppContext
with AuthClient(AppContext()) as client:
# Login to a specific provider
client.login(provider="oauth")
# Check authentication status
providers = client.list_providers()
# Logout
client.logout(provider="oauth")
AuthClient
AuthClient(ctx: AppContext)
Client for authentication operations.
This provides a presentation-free API for authentication functionality.
Notes:
- This module provides a presentation-free API. It raises domain exceptions
(e.g. QlamCoreError) which consumers handle at their application boundary.
Initialize the auth client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ctx
|
AppContext
|
Application context containing configuration |
required |
Source code in qlam_core/auth/client.py
45 46 47 48 49 50 | |
__enter__
__enter__() -> 'AuthClient'
Context manager entry.
Source code in qlam_core/auth/client.py
52 53 54 | |
__exit__
__exit__(exc_type, exc_val, exc_tb) -> None
Context manager exit.
Source code in qlam_core/auth/client.py
56 57 58 | |
get_credential
get_credential(provider: str) -> CredentialBase | None
Get the credential for a specific provider.
Returns the provider's credential model (e.g. OAuthCredential,
BasicCredential). A returned credential may have a
non-authenticated status; callers should inspect the status field.
Returns None only when the provider has no credential data at all.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str
|
Provider name to retrieve the credential for. |
required |
Returns:
| Type | Description |
|---|---|
CredentialBase | None
|
Provider-specific credential model, or None. |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If the provider is unknown or misconfigured. |
AuthenticationError
|
If the provider raises an expected error. |
Source code in qlam_core/auth/client.py
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 | |
get_user_info
get_user_info(provider: str | None = None) -> UserInfo
Return the current authenticated user profile from {api}/userinfo.
When provider is omitted, resolves
current_context.defaults.auth_provider. The profile is fetched from
the context's api_base_url (/userinfo), not the IdP endpoint.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str | None
|
Auth provider name, or None to use the context default. |
None
|
Returns:
| Type | Description |
|---|---|
UserInfo
|
Typed user profile from the provider. |
Raises:
| Type | Description |
|---|---|
ConfigurationError
|
If no context default or API base URL exists, the provider is unknown/misconfigured, or it does not support userinfo. |
AuthenticationError
|
If the provider raises an expected error. |
QlamCoreError
|
Typed OAuth/domain errors. |
Source code in qlam_core/auth/client.py
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 | |
is_authenticated
is_authenticated(provider: str | None = None) -> bool
Check if authentication is active.
Source code in qlam_core/auth/client.py
469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | |
list_providers
list_providers() -> list[dict[str, Any]]
List all authentication providers in the current context.
Source code in qlam_core/auth/client.py
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 | |
login
login(provider: str | None = None) -> dict[str, bool]
Perform authentication login.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str | None
|
Specific provider name to login to. If None, logs in to all providers. |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, bool]
|
Dictionary mapping provider names to success status |
Raises:
| Type | Description |
|---|---|
ValueError
|
If provider is unknown or doesn't support login |
AuthenticationError
|
If login fails for the specific-provider path. |
QlamCoreError
|
Provider/flow typed domain errors. |
Source code in qlam_core/auth/client.py
306 307 308 309 310 311 312 313 314 315 316 317 318 | |
logout
logout(provider: str | None = None) -> dict[str, bool]
Clear cached credentials.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
provider
|
str | None
|
Specific provider name to logout from. If None, logs out from all. |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, bool]
|
Dictionary mapping provider names to success status |
Raises:
| Type | Description |
|---|---|
ValueError
|
If provider is unknown or doesn't support logout |
AuthenticationError
|
If logout fails for the specific-provider path. |
QlamCoreError
|
Provider/flow typed domain errors. |
Source code in qlam_core/auth/client.py
366 367 368 369 370 371 372 373 374 375 376 377 378 | |
refresh_credentials
refresh_credentials(provider: str | None = None, *, force: bool = False) -> dict[str, bool]
Refresh cached credentials non-interactively (and persist updates).
This is a programmatic API intended for SDK and application usage.
Semantics:
- If provider is provided, errors are surfaced as typed exceptions so callers
can handle specific failures.
- If provider is None, this method returns best-effort results and does not
raise for per-provider failures (only for configuration/usage errors).
Source code in qlam_core/auth/client.py
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 | |
Credential Models
BasicCredential
Bases: CredentialBase
flowchart TD
qlam_core.auth.credentials.models.BasicCredential[BasicCredential]
qlam_core.auth.credentials.models.CredentialBase[CredentialBase]
qlam_core.auth.credentials.models.CredentialBase --> qlam_core.auth.credentials.models.BasicCredential
click qlam_core.auth.credentials.models.BasicCredential href "" "qlam_core.auth.credentials.models.BasicCredential"
click qlam_core.auth.credentials.models.CredentialBase href "" "qlam_core.auth.credentials.models.CredentialBase"
Credential for username/password-based authentication providers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
username
|
Authenticated username. |
required | |
login_time
|
ISO-formatted timestamp of the last login, if known. |
required | |
auth_source
|
Backend or service that validated the credentials, if known. |
required |
CredentialBase
Bases: BaseModel
flowchart TD
qlam_core.auth.credentials.models.CredentialBase[CredentialBase]
click qlam_core.auth.credentials.models.CredentialBase href "" "qlam_core.auth.credentials.models.CredentialBase"
Base credential model returned by authentication providers.
All provider-specific credential types extend this base.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
Provider name that issued this credential. |
required | |
status
|
Current authentication state. |
required |
OAuthCredential
Bases: CredentialBase
flowchart TD
qlam_core.auth.credentials.models.OAuthCredential[OAuthCredential]
qlam_core.auth.credentials.models.CredentialBase[CredentialBase]
qlam_core.auth.credentials.models.CredentialBase --> qlam_core.auth.credentials.models.OAuthCredential
click qlam_core.auth.credentials.models.OAuthCredential href "" "qlam_core.auth.credentials.models.OAuthCredential"
click qlam_core.auth.credentials.models.CredentialBase href "" "qlam_core.auth.credentials.models.CredentialBase"
Credential for OAuth-based authentication providers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
client_id
|
OAuth client identifier. |
required | |
access_token
|
Current access token, if authenticated. |
required | |
refresh_token
|
Refresh token for obtaining new access tokens, if available. |
required | |
expires_at
|
Expiration time of the access token, if known. |
required | |
allows_refresh
|
Whether this credential supports non-interactive token refresh. |
required |
User Profile Model
Typed current-user profile from the OIDC UserInfo endpoint.
QuEra namespaced claims of the form https://v2/{environment}/{claim} are
normalized into canonical fields; unrecognized claims go in extra_claims.
UserInfo
Bases: BaseModel
flowchart TD
qlam_core.auth.user_info.UserInfo[UserInfo]
click qlam_core.auth.user_info.UserInfo href "" "qlam_core.auth.user_info.UserInfo"
Current authenticated user profile from {api_base_url}/userinfo.
Standard OIDC claims are accepted as-is. QuEra claims
https://v2/{environment}/{claim} for user_id, tenant_id,
roles, groups, and permissions fold into the matching fields.
Unrecognized claims (for example timestamp) are preserved in
extra_claims.