Skip to content

Identity sessions

reauth.identity_session

IdentitySession dataclass

IdentitySession(
    id: Any | None,
    token_hash: TokenHash,
    expires_at: int,
    identity_id: Any,
    amr: list[AuthenticationMethodReference],
    context: dict[str, Any] | None = None,
    refresh_token_hash: TokenHash | None = None,
    refresh_token_expires_at: int | None = None,
    family_id: Any | None = None,
    replaced_by_id: Any | None = None,
    revoked_at: int | None = None,
)

The authenticated state of an identity, accessed through a session token.

Attributes:

Name Type Description
id Any | None

The stored session ID, or None before insertion.

token_hash TokenHash

The HMAC-SHA256 hash of the session token.

expires_at int

The access token expiration as a Unix timestamp in seconds.

identity_id Any

The ID of the authenticated identity.

amr list[AuthenticationMethodReference]

The authentication methods used to authenticate the identity.

context dict[str, Any] | None

Optional additional data stored with the session.

refresh_token_hash TokenHash | None

The refresh token hash, or None if renewal is disabled.

refresh_token_expires_at int | None

The family's absolute deadline, or None if this session has no refresh token. Replacements inherit the deadline.

family_id Any | None

The initial session's ID, or None before initial insertion.

replaced_by_id Any | None

The replacement session's ID, or None if not replaced.

revoked_at int | None

The revocation timestamp, or None if not revoked.

id instance-attribute

id: Any | None

token_hash instance-attribute

token_hash: TokenHash

expires_at instance-attribute

expires_at: int

identity_id instance-attribute

identity_id: Any

amr instance-attribute

amr: list[AuthenticationMethodReference]

context class-attribute instance-attribute

context: dict[str, Any] | None = None

refresh_token_hash class-attribute instance-attribute

refresh_token_hash: TokenHash | None = None

refresh_token_expires_at class-attribute instance-attribute

refresh_token_expires_at: int | None = None

family_id class-attribute instance-attribute

family_id: Any | None = None

replaced_by_id class-attribute instance-attribute

replaced_by_id: Any | None = None

revoked_at class-attribute instance-attribute

revoked_at: int | None = None

is_expired

is_expired() -> bool

Check if the access token has expired.

Returns:

Type Description
bool

True if the current time is at or past expiration, False otherwise.

IdentitySessionException

IdentitySessionException(message: str | None = None)

Bases: ReauthException

Base exception for identity session errors.

InvalidSessionTokenException

InvalidSessionTokenException(message: str | None = None)

Bases: IdentitySessionException

Raised when an access token is unknown, malformed, revoked, or replaced.

ExpiredSessionException

ExpiredSessionException(message: str | None = None)

Bases: IdentitySessionException

Raised when an access token has expired.

InvalidRefreshTokenException

InvalidRefreshTokenException(message: str | None = None)

Bases: IdentitySessionException

Raised when a refresh token is unknown, malformed, disabled, or revoked.

ExpiredRefreshTokenException

ExpiredRefreshTokenException(message: str | None = None)

Bases: IdentitySessionException

Raised when a refresh token's absolute deadline has passed.

ReusedRefreshTokenException

ReusedRefreshTokenException(message: str | None = None)

Bases: IdentitySessionException

Raised after revoking a family because a consumed refresh token was reused.

IdentitySessionService

IdentitySessionService(
    *,
    hash_secret: str,
    token_prefix: str = "reauth_is_",
    lifetime: timedelta = datetime.timedelta(hours=24),
    refresh_token_prefix: str = "reauth_isr_",
    refresh_token_lifetime: timedelta = datetime.timedelta(
        days=30
    ),
)

Bases: ABC

Abstract base class for managing identity sessions and optional refresh tokens.

Implementers provide token lookups, initial insertion, atomic replacement, and family revocation. Retain replaced sessions until the family's absolute deadline so their hashes can identify refresh token reuse.

Initialize the identity session service.

Parameters:

Name Type Description Default
hash_secret str

The ASCII secret used to compute token hashes.

required
token_prefix str

The session token prefix. Defaults to "reauth_is_".

'reauth_is_'
lifetime timedelta

The access token lifetime. Defaults to 24 hours.

timedelta(hours=24)
refresh_token_prefix str

The refresh token prefix. Defaults to "reauth_isr_".

'reauth_isr_'
refresh_token_lifetime timedelta

The absolute lifetime of a refreshable family, measured from initial issuance. Defaults to 30 days.

timedelta(days=30)

hash_secret instance-attribute

hash_secret = hash_secret

token_prefix instance-attribute

token_prefix = token_prefix

lifetime instance-attribute

lifetime = lifetime

refresh_token_prefix instance-attribute

refresh_token_prefix = refresh_token_prefix

refresh_token_lifetime instance-attribute

refresh_token_lifetime = refresh_token_lifetime

issue async

issue(
    identity_id: Any,
    *,
    amr: list[AuthenticationMethodReference],
    refresh_token: bool = False,
    **context: Any,
) -> tuple[str, str | None, IdentitySession]

Issue and persist a session for an authenticated identity.

The caller is responsible for authenticating the identity before issuance. Only token hashes are persisted; plaintext tokens are returned to the caller.

Parameters:

Name Type Description Default
identity_id Any

The ID of the authenticated identity.

required
amr list[AuthenticationMethodReference]

The authentication methods used to authenticate the identity.

required
refresh_token bool

Whether to issue a refresh token. Defaults to False.

False
**context Any

Optional additional data to store with the session.

{}

Returns:

Type Description
str

A tuple of (token, refresh_token, IdentitySession instance). The

str | None

refresh token is None when renewal is disabled.

validate async

validate(token: str) -> IdentitySession

Validate an access token and return its identity session.

Parameters:

Name Type Description Default
token str

The access token to validate.

required

Returns:

Type Description
IdentitySession

The corresponding IdentitySession instance.

Raises:

Type Description
InvalidSessionTokenException

If the token is malformed, unknown, revoked, or belongs to a replaced session.

ExpiredSessionException

If the access token has expired.

refresh async

refresh(
    token: str, *, refresh_token: bool = True
) -> tuple[str, str | None, IdentitySession]

Consume a refresh token and atomically replace its session.

Both previous tokens become invalid. The replacement retains the identity, AMR, context, family, and absolute deadline, even if access has expired. Reuse of a consumed refresh token revokes its whole family.

Parameters:

Name Type Description Default
token str

The refresh token to consume.

required
refresh_token bool

Whether to issue another refresh token. Defaults to True. False issues a final session whose expiry is still capped by the family's deadline, with no further renewal capability.

True

Returns:

Type Description
str

A tuple of (token, refresh_token, IdentitySession instance). The

str | None

refresh token is None when renewal is disabled.

Raises:

Type Description
InvalidRefreshTokenException

If the token is malformed, unknown, revoked, or otherwise no longer refreshable.

ExpiredRefreshTokenException

If the absolute deadline has passed.

ReusedRefreshTokenException

If the token was already consumed. Family revocation is persisted before this exception is raised.

revoke async

revoke(token: str) -> None

Revoke an entire family identified by an access or refresh token.

Expired and replaced tokens can still identify a family. Unknown, malformed, and already-revoked tokens succeed without error.

Parameters:

Name Type Description Default
token str

An access token or refresh token from the family to revoke.

required

insert abstractmethod async

insert(identity_session: IdentitySession) -> typing.Any

Atomically insert a session and initialize its family ID.

If family_id is None, set the stored family_id to the generated record ID in the same transaction. Preserve an explicitly supplied family ID.

Parameters:

Name Type Description Default
identity_session IdentitySession

The complete session model to insert.

required

Returns:

Type Description
Any

The ID of the inserted session.

get_by_token_hash abstractmethod async

get_by_token_hash(
    token_hash: TokenHash,
) -> IdentitySession | None

Retrieve a session by its access token hash, regardless of its validity.

Parameters:

Name Type Description Default
token_hash TokenHash

The access token hash to look up.

required

Returns:

Type Description
IdentitySession | None

The stored session, including expired, replaced, or revoked rows,

IdentitySession | None

or None if not found.

get_by_refresh_token_hash abstractmethod async

get_by_refresh_token_hash(
    refresh_token_hash: TokenHash,
) -> IdentitySession | None

Retrieve a session by its refresh token hash, regardless of its validity.

Parameters:

Name Type Description Default
refresh_token_hash TokenHash

The refresh token hash to look up.

required

Returns:

Type Description
IdentitySession | None

The stored session, including expired, replaced, or revoked rows,

IdentitySession | None

or None if not found.

replace abstractmethod async

replace(
    previous_session: IdentitySession,
    new_session: IdentitySession,
) -> typing.Any | None

Atomically replace a session if its refresh token is still usable.

Serialize with all replacements and revocations in the same family, for example by locking the retained initial session row. Reload the previous session under that lock: its refresh hash must still match, its refresh deadline must be in the future, and it must be neither revoked nor replaced. Also reject a revoked or missing family root.

Insert new_session with the same family ID and set the previous row's replaced_by_id to the new ID. Commit both changes before returning; roll back both on failure. Do not call the public issue() method.

Parameters:

Name Type Description Default
previous_session IdentitySession

The previously retrieved session to replace.

required
new_session IdentitySession

The complete replacement model to persist.

required

Returns:

Type Description
Any | None

The replacement ID, or None with no changes if the previous session

Any | None

is no longer eligible. Propagate storage failures after rollback.

revoke_family abstractmethod async

revoke_family(identity_session: IdentitySession) -> None

Persist revocation of every session in the supplied session's family.

Use identity_session.revoked_at, set by the service, for rows not yet revoked. Preserve earlier revocation timestamps, hashes, and lineage. Serialize with replace() through the same family lock and commit before returning. A caller's subsequent exception must not undo revocation. Missing or already-revoked families succeed without error.

Parameters:

Name Type Description Default
identity_session IdentitySession

The session identifying the family and revocation time.

required