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

Returns:

Type Description
str

Description suitable for help text and user interfaces.

shows_access_token property

shows_access_token: bool

Whether qsh auth show may print this provider's access token.

The SDK's get_credential() returns it either way.

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
147
148
149
150
151
152
153
154
155
156
157
158
159
@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.

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
161
162
163
164
165
166
167
168
@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.

Returns:

Type Description
JsonDict

Dictionary describing authentication state and metadata.

Source code in qlam_core/auth/base.py
 94
 95
 96
 97
 98
 99
100
@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
102
103
104
105
106
107
108
109
110
111
@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.
    """
    ...

get_display_credential

get_display_credential() -> CredentialBase | None

Return the credential as qsh auth show may print it.

Same as get_credential(), without the access token when shows_access_token is False.

Source code in qlam_core/auth/base.py
66
67
68
69
70
71
72
73
74
75
def get_display_credential(self) -> CredentialBase | None:
    """Return the credential as `qsh auth show` may print it.

    Same as ``get_credential()``, without the access token when
    ``shows_access_token`` is False.
    """
    credential = self.get_credential()
    if credential is None or self.shows_access_token:
        return credential
    return credential.model_copy(update={"access_token": None})

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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
def get_user_info(
    self,
    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`][qlam_core.errors.ConfigurationError] with
    usage-error semantics. OAuth providers override this to fetch
    ``{api_base_url}/userinfo``.

    :param api_base_url: API base URL used to build the userinfo endpoint.
    :param timeout: Request timeout in seconds.
    :param verify_ssl: SSL verification setting or CA bundle path.
    :param follow_redirects: Whether to follow HTTP redirects.
    :param headers: Non-authentication headers to include in the request.
    :return: Typed user profile from the identity provider.
    :raises ConfigurationError: If this provider does not support userinfo lookup.
    """
    provider_name = (
        getattr(self, "provider_name", None)
        or getattr(self, "name", None)
        or self.__class__.__name__
    )
    raise ConfigurationError(
        f"Provider '{provider_name}' does not support user info lookup. "
        "Use an OAuth provider.",
        exit_code=ExitCode.USAGE_ERROR,
    )

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
86
87
88
89
90
91
92
@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.

Returns:

Type Description
Dict[str, str]

Dictionary of HTTP headers for authentication

Source code in qlam_core/auth/base.py
180
181
182
183
184
185
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
191
192
193
194
195
196
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
198
199
200
201
202
203
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
235
236
237
@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
231
232
233
@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.

Returns:

Type Description
str

Access token string.

Source code in qlam_core/auth/base.py
215
216
217
218
219
220
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 RefreshCredentialsMixin.

Source code in qlam_core/auth/base.py
240
241
242
243
244
245
246
247
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 [`RefreshCredentialsMixin`][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.

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
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
52
53
54
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
56
57
58
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.

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
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
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",
    )

get_user_info

get_user_info(provider: str | None = None) -> UserInfo

Return the current authenticated user profile from {api}/userinfo.

When provider is omitted, uses ctx.auth_provider_name, then 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 ctx.auth_provider_name or the context default.

None

Returns:

Type Description
UserInfo

Typed user profile from the provider.

Raises:

Type Description
AuthProviderNotConfiguredError

If ctx.auth_provider_name is used and is not an auth_providers entry in the current context.

ConfigurationError

If no provider is selected or configured as the context default, no 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
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
def get_user_info(self, provider: str | None = None) -> UserInfo:
    """Return the current authenticated user profile from ``{api}/userinfo``.

    When ``provider`` is omitted, uses ``ctx.auth_provider_name``, then
    ``current_context.defaults.auth_provider``. The profile is fetched from
    the context's ``api_base_url`` (``/userinfo``), not the IdP endpoint.

    :param provider: Auth provider name, or None to use ``ctx.auth_provider_name``
        or the context default.
    :return: Typed user profile from the provider.
    :raises AuthProviderNotConfiguredError: If ``ctx.auth_provider_name`` is used
        and is not an ``auth_providers`` entry in the current context.
    :raises ConfigurationError: If no provider is selected or configured as the
        context default, no API base URL exists, the provider is
        unknown/misconfigured, or it does not support userinfo.
    :raises AuthenticationError: If the provider raises an expected error.
    :raises QlamCoreError: Typed OAuth/domain errors.
    """
    from qlam_core.clients.http.resolver import (
        ClientConfigResolver,
        require_configured_auth_provider,
    )

    if provider is None and self.ctx.auth_provider_name is not None:
        require_configured_auth_provider(self.ctx, self.ctx.auth_provider_name)
        provider = self.ctx.auth_provider_name
    if provider is None:
        defaults = self.ctx.config.current_context.defaults
        provider = defaults.auth_provider if defaults else None
        if not provider:
            raise ConfigurationError(
                "No default auth provider configured in the current context. "
                "Pass provider=... or set defaults.auth_provider.",
                exit_code=ExitCode.USAGE_ERROR,
            )

    auth_provider = self._require_provider(provider)
    resolver = ClientConfigResolver(self.ctx)
    return self._call_provider_action(
        action=lambda: auth_provider.get_user_info(
            resolver.resolve_base_url(),
            timeout=resolver.resolve_timeout(),
            verify_ssl=resolver.resolve_verify_ssl(),
            follow_redirects=resolver.resolve_follow_redirects(),
            headers=resolver.resolve_headers(),
        ),
        failure_prefix="Get user info failed",
    )

is_authenticated

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

Check if authentication is active.

Source code in qlam_core/auth/client.py
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
def is_authenticated(self, provider: str | None = None) -> bool:
    """Check if authentication is active."""
    if provider:
        auth_provider = self._get_or_create_provider(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
410
411
412
413
414
415
416
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
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.

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
291
292
293
294
295
296
297
298
299
300
301
302
303
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.

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
346
347
348
349
350
351
352
353
354
355
356
357
358
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
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
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.

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.