Skip to content

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:
        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.registry if placed under qlam_core.auth.providers, or call auth_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.

:return: 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.

:param context_name: Context name for the provider. :param provider_name: Optional provider name for identification. :param provider_config: Provider configuration object from settings. :return: Configured provider instance. :raises NotImplementedError: If provider doesn't implement this method.

Source code in qlam_core/auth/base.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
@classmethod
def build_from_settings(
    cls, *, context_name: str, provider_name: str | None, provider_config: Any
) -> "BaseAuthProvider":
    """Create provider instance from settings configuration.

    :param context_name: Context name for the provider.
    :param provider_name: Optional provider name for identification.
    :param provider_config: Provider configuration object from settings.
    :return: Configured provider instance.
    :raises NotImplementedError: If provider doesn't implement this method.
    """
    raise NotImplementedError(f"Provider {cls.__name__} must implement build_from_settings")

extra_info_from_config classmethod

extra_info_from_config(provider_config: Any) -> JsonDict

Extract extra display information from provider configuration.

:param provider_config: Provider configuration object from settings. :return: Dictionary of extra information for display purposes.

Source code in qlam_core/auth/base.py
105
106
107
108
109
110
111
112
@classmethod
def extra_info_from_config(cls, provider_config: Any) -> JsonDict:
    """Extract extra display information from provider configuration.

    :param provider_config: Provider configuration object from settings.
    :return: Dictionary of extra information for display purposes.
    """
    return {}

get_auth_context abstractmethod

get_auth_context() -> JsonDict

Get authentication context for use by clients.

:return: Dictionary describing authentication state and metadata.

Source code in qlam_core/auth/base.py
72
73
74
75
76
77
78
@abstractmethod
def get_auth_context(self) -> JsonDict:
    """Get authentication context for use by clients.

    :return: Dictionary describing authentication state and metadata.
    """
    ...

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
80
81
82
83
84
85
86
87
88
89
@abstractmethod
def get_credential(self) -> 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.
    """
    ...

is_authenticated abstractmethod

is_authenticated() -> bool

Check if the provider has valid authentication.

:return: True if authenticated, False otherwise.

Source code in qlam_core/auth/base.py
64
65
66
67
68
69
70
@abstractmethod
def is_authenticated(self) -> bool:
    """Check if the provider has valid authentication.

    :return: True if authenticated, False otherwise.
    """
    ...

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.

:return: Dictionary of HTTP headers for authentication

Source code in qlam_core/auth/base.py
124
125
126
127
128
129
def get_headers(self) -> Dict[str, str]:
    """Get authentication headers for HTTP requests.

    :return: Dictionary of HTTP headers for authentication
    """
    ...

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
135
136
137
138
139
140
def login(self) -> None:
    """Default login implementation (no-op).

    Override to implement provider-specific login logic.
    """
    pass

logout

logout() -> None

Default logout implementation (no-op).

Override to implement provider-specific logout logic.

Source code in qlam_core/auth/base.py
142
143
144
145
146
147
def logout(self) -> None:
    """Default logout implementation (no-op).

    Override to implement provider-specific logout logic.
    """
    pass

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
179
180
181
@abstractmethod
def can_refresh_credentials(self) -> bool:
    """Return True if cached credentials can be refreshed non-interactively right now."""

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
175
176
177
@abstractmethod
def refresh_credentials(self, *, force: bool = False) -> bool:
    """Refresh credentials for this provider, updating the cache if needed."""

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.

:return: Access token string.

Source code in qlam_core/auth/base.py
159
160
161
162
163
164
def token(self) -> str:
    """Return an access token to be injected into requests.

    :return: Access token string.
    """
    ...

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 :class:~qlam_core.auth.base.RefreshCredentialsMixin.

Source code in qlam_core/auth/base.py
184
185
186
187
188
189
190
191
def 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 :class:`~qlam_core.auth.base.RefreshCredentialsMixin`.
    """
    return isinstance(provider, RefreshCredentialsMixin)

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.

:param ctx: Application context containing configuration

Source code in qlam_core/auth/client.py
44
45
46
47
48
49
def __init__(self, ctx: AppContext):
    """Initialize the auth client.

    :param ctx: Application context containing configuration
    """
    self.ctx = ctx

__enter__

__enter__() -> 'AuthClient'

Context manager entry.

Source code in qlam_core/auth/client.py
51
52
53
def __enter__(self) -> "AuthClient":
    """Context manager entry."""
    return self

__exit__

__exit__(exc_type, exc_val, exc_tb) -> None

Context manager exit.

Source code in qlam_core/auth/client.py
55
56
57
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
    """Context manager exit."""
    pass

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.

:param provider: Provider name to retrieve the credential for. :return: Provider-specific credential model, or None. :raises ConfigurationError: If the provider is unknown or misconfigured. :raises AuthenticationError: If the provider raises an expected error.

Source code in qlam_core/auth/client.py
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
def get_credential(self, 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.

    :param provider: Provider name to retrieve the credential for.
    :return: Provider-specific credential model, or None.
    :raises ConfigurationError: If the provider is unknown or misconfigured.
    :raises AuthenticationError: If the provider raises an expected error.
    """
    auth_provider = self._require_provider(provider)
    return self._call_provider_action(
        action=auth_provider.get_credential,
        failure_prefix="Get credential failed",
    )

is_authenticated

is_authenticated(provider: str | None = None) -> bool

Check if authentication is active.

Source code in qlam_core/auth/client.py
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
def is_authenticated(self, provider: str | None = None) -> bool:
    """Check if authentication is active."""
    from qlam_core.auth.registry import auth_registry

    if provider:
        # Check one provider: try registry first, else create from config.
        auth_provider = auth_registry.get_provider(provider)
        if not auth_provider:
            auth_provider = self._create_provider_from_config(provider)

        if auth_provider:
            try:
                # Query authenticated state (best-effort errors treated as False).
                return auth_provider.is_authenticated()
            except (AttributeError, RuntimeError, ValueError, QlamCoreError):
                return False
        return False

    # Check all providers: any authenticated provider counts as authenticated.
    authenticated = self._get_authenticated_providers()
    return len(authenticated) > 0

list_providers

list_providers() -> list[dict[str, Any]]

List all authentication providers in the current context.

Source code in qlam_core/auth/client.py
417
418
419
420
421
422
423
424
425
426
427
428
429
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
def list_providers(self) -> list[dict[str, Any]]:
    """List all authentication providers in the current context."""
    from qlam_core.auth.registry import auth_registry

    current_context = self.ctx.config.current_context
    if not current_context.auth_providers:
        return []

    provider_data: list[dict[str, Any]] = []
    for auth_provider_config in current_context.auth_providers:
        provider_name = auth_provider_config.name
        provider_type = auth_provider_config.provider

        # Determine status ("authenticated", "available", "error", etc.).
        status = self._provider_status(
            provider_name=provider_name,
            provider_type=provider_type,
            provider_config=auth_provider_config,
        )

        # Gather static metadata/capabilities and optional extra info.
        capabilities = auth_registry.get_capabilities(provider_type)
        description = capabilities.get("description", f"{provider_type} authentication")
        extra_info = self._provider_extra_info(
            provider_type=provider_type,
            provider_config=auth_provider_config,
        )

        provider_info = {
            "name": provider_name,
            "type": provider_type,
            "status": status,
            "description": description,
        }
        provider_info.update(extra_info)
        provider_data.append(provider_info)

    return provider_data

login

login(provider: str | None = None) -> dict[str, bool]

Perform authentication login.

:param provider: Specific provider name to login to. If None, logs in to all providers. :return: Dictionary mapping provider names to success status :raises ValueError: If provider is unknown or doesn't support login :raises AuthenticationError: If login fails for the specific-provider path. :raises QlamCoreError: Provider/flow typed domain errors.

Source code in qlam_core/auth/client.py
293
294
295
296
297
298
299
300
301
302
303
304
305
def login(self, provider: str | None = None) -> dict[str, bool]:
    """Perform authentication login.

    :param provider: Specific provider name to login to. If None, logs in to all providers.
    :return: Dictionary mapping provider names to success status
    :raises ValueError: If provider is unknown or doesn't support login
    :raises AuthenticationError: If login fails for the specific-provider path.
    :raises QlamCoreError: Provider/flow typed domain errors.
    """
    if provider:
        return {provider: self._login_one(provider)}

    return self._login_all()

logout

logout(provider: str | None = None) -> dict[str, bool]

Clear cached credentials.

:param provider: Specific provider name to logout from. If None, logs out from all. :return: Dictionary mapping provider names to success status :raises ValueError: If provider is unknown or doesn't support logout :raises AuthenticationError: If logout fails for the specific-provider path. :raises QlamCoreError: Provider/flow typed domain errors.

Source code in qlam_core/auth/client.py
353
354
355
356
357
358
359
360
361
362
363
364
365
def logout(self, provider: str | None = None) -> dict[str, bool]:
    """Clear cached credentials.

    :param provider: Specific provider name to logout from. If None, logs out from all.
    :return: Dictionary mapping provider names to success status
    :raises ValueError: If provider is unknown or doesn't support logout
    :raises AuthenticationError: If logout fails for the specific-provider path.
    :raises QlamCoreError: Provider/flow typed domain errors.
    """
    if provider:
        return {provider: self._logout_one(provider)}

    return self._logout_all()

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
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
def refresh_credentials(self, 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).
    """
    if provider:
        return {provider: self._refresh_one(provider, force=force)}

    return self._refresh_all(force=force)

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.

:param username: Authenticated username. :param login_time: ISO-formatted timestamp of the last login, if known. :param auth_source: Backend or service that validated the credentials, if known.

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.

:param name: Provider name that issued this credential. :param status: Current authentication state.

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.

:param client_id: OAuth client identifier. :param access_token: Current access token, if authenticated. :param refresh_token: Refresh token for obtaining new access tokens, if available. :param expires_at: Expiration time of the access token, if known. :param allows_refresh: Whether this credential supports non-interactive token refresh.