Documentation
¶
Overview ¶
Package session manages opaque, revocable credentials for typed model guards. Persistence adapters own atomic writes; application code supplies verified proofs and consumes models through the ordinary auth.Guard.
Index ¶
- Constants
- Variables
- type Address
- type Backend
- type CheckedBackend
- type CompletionBackend
- type Config
- type ConfirmationBackend
- type Creation
- type DeadlineBackend
- type Digest
- type ID
- type Impersonation
- func (i *Impersonation[A, AK, M, K]) Actor(ctx context.Context) (value.Optional[A], error)
- func (i *Impersonation[A, AK, M, K]) Actors() *Sessions[A, AK]
- func (i *Impersonation[A, AK, M, K]) Resume(ctx context.Context) (Issued[A, AK], error)
- func (i *Impersonation[A, AK, M, K]) Start(ctx context.Context, target model.Reference[M, K], duration time.Duration) (Issued[M, K], error)
- func (i *Impersonation[A, AK, M, K]) Stop(ctx context.Context) error
- func (i *Impersonation[A, AK, M, K]) Targets() *Sessions[M, K]
- func (i *Impersonation[A, AK, M, K]) Validate() error
- func (i *Impersonation[A, AK, M, K]) WithObserver(observer auth.Observer) (*Impersonation[A, AK, M, K], error)
- type Impersonator
- type Info
- func (i Info[M, K]) Assurance() auth.Assurance
- func (i Info[M, K]) ConfirmedAt() value.Optional[temporal.DateTime]
- func (i Info[M, K]) CreatedAt() temporal.DateTime
- func (i Info[M, K]) Device() auth.Device
- func (i Info[M, K]) ExpiresAt() temporal.DateTime
- func (Info[M, K]) Format(s fmt.State, _ rune)
- func (i Info[M, K]) ID() ID[M]
- func (i Info[M, K]) IdleExpiresAt() temporal.DateTime
- func (i Info[M, K]) Impersonated() bool
- func (i Info[M, K]) Impersonator() value.Optional[Impersonator]
- func (i Info[M, K]) LastSeenAt() temporal.DateTime
- func (i Info[M, K]) Remembered() bool
- func (i Info[M, K]) Subject() model.Reference[M, K]
- type IssueOptions
- type Issued
- type Lifetime
- type Record
- type ResumptionBackend
- type SelectiveBackend
- type Sessions
- func (s *Sessions[M, K]) CompleteMFA(ctx context.Context, raw secret.String, factor auth.SecondFactor[M, K], ...) (Issued[M, K], error)
- func (s *Sessions[M, K]) ConfirmCurrent(ctx context.Context) (Info[M, K], error)
- func (s *Sessions[M, K]) Current(ctx context.Context) (Info[M, K], error)
- func (s *Sessions[M, K]) CurrentProof(ctx context.Context) (auth.Proof[M, K], error)
- func (s *Sessions[M, K]) Guard() auth.Guard[M]
- func (s *Sessions[M, K]) Issue(ctx context.Context, proof auth.Proof[M, K], options IssueOptions) (Issued[M, K], error)
- func (s *Sessions[M, K]) List(ctx context.Context, reference model.Reference[M, K]) ([]Info[M, K], error)
- func (s *Sessions[M, K]) Logout(ctx context.Context, credential secret.String) (bool, error)
- func (s *Sessions[M, K]) Prune(ctx context.Context, limit int) (uint64, error)
- func (s *Sessions[M, K]) PruneExpired(ctx context.Context, batch, maxBatches int) (uint64, error)
- func (s *Sessions[M, K]) RequireConfirmed(ctx context.Context, within time.Duration) error
- func (s *Sessions[M, K]) RequireNotImpersonating(ctx context.Context) error
- func (s *Sessions[M, K]) Revocation() (auth.Revocation[M, K], error)
- func (s *Sessions[M, K]) Revoke(ctx context.Context, credential secret.String) (bool, error)
- func (s *Sessions[M, K]) RevokeAll(ctx context.Context, reference model.Reference[M, K]) (uint64, error)
- func (s *Sessions[M, K]) RevokeAllIn(ctx context.Context, tx *database.Tx, reference model.Reference[M, K]) (uint64, error)
- func (s *Sessions[M, K]) RevokeCurrent(ctx context.Context) (bool, error)
- func (s *Sessions[M, K]) RevokeID(ctx context.Context, reference model.Reference[M, K], id ID[M]) (bool, error)
- func (s *Sessions[M, K]) RevokeOthers(ctx context.Context) (uint64, error)
- func (s *Sessions[M, K]) Rotate(ctx context.Context, credential secret.String) (Issued[M, K], error)
- func (s *Sessions[M, K]) Validate() error
- func (s *Sessions[M, K]) WithObserver(observer auth.Observer) (*Sessions[M, K], error)
- type Store
- type TransactionalBackend
Constants ¶
const EncodedSecretBytes = credential.EncodedSecretBytes
const MaxImpersonation = 24 * time.Hour
MaxImpersonation bounds any impersonation session's absolute lifetime.
const MaxLifetime = 365 * 24 * time.Hour
const MaxPageSize = 1024
const MaxSessions = 1024
const SecretBytes = credential.SecretBytes
Variables ¶
var ActorSessionEnded = safeerror.Sentinel(fault.Missing, "the impersonating actor's session has ended")
ActorSessionEnded is the cause Resume reports (as auth.Unauthenticated) when the impersonation ended but the original actor's session had been revoked or had expired meanwhile: the actor must log in again.
Functions ¶
This section is empty.
Types ¶
type Address ¶
type Address struct {
Namespace keyspace.Namespace
Guard auth.GuardName
Provider auth.ProviderName
Model string
}
Address binds persisted credentials to one application/environment, guard, provider and stored model namespace. It is the explicit adapter boundary.
func (Address) SubjectKey ¶
SubjectKey returns the subject's opaque key within the validated address.
type Backend ¶
type Backend interface {
// Create atomically creates a session under the subject's capacity policy.
Create(context.Context, Address, Creation) (Record, error)
// Lookup resolves a live session by digest, optionally recording activity.
Lookup(context.Context, Address, Digest, bool) (value.Optional[Record], error)
// Rotate replaces a live session's secret hash and records activity without reviving
// removed records.
Rotate(context.Context, Address, Digest, Digest) (value.Optional[Record], error)
// Revoke removes the session identified by its credential digest and reports whether
// it existed.
Revoke(context.Context, Address, Digest) (bool, error)
// RevokeID removes the subject's identified session and reports whether it existed.
RevokeID(context.Context, Address, model.Identity, model.ID[Record]) (bool, error)
// RevokeAll removes all of the subject's sessions, serializing with creation.
RevokeAll(context.Context, Address, model.Identity) (uint64, error)
// List returns a bounded page of the subject's session records.
List(context.Context, Address, model.Identity, int) ([]Record, error)
// Prune removes a bounded batch of expired sessions.
Prune(context.Context, Address, int) (uint64, error)
}
Backend owns one authoritative session store. Every mutation is atomic and executes without automatic retry. RevokeAll serializes with creation; sessions issued after that operation are new credentials. Lookup/rotation cannot revive a removed record. Clock sampling occurs after acquiring the relevant lock. Errors may mean an unknown write outcome; they are not missing credentials. Adapters return complete validated records and enforce bounded list/prune work.
type CheckedBackend ¶
type CheckedBackend interface {
// CreateChecked runs the proof check before credential locks and creates the session
// in the same transaction.
CreateChecked(context.Context, Address, Creation, func(context.Context, *database.Tx) error) (Record, error)
}
CheckedBackend verifies a proof's current model in the SAME transaction as creation, before acquiring credential subject locks. The check must lock the model and may run once only. A failed check creates nothing; never retry it.
type CompletionBackend ¶
type CompletionBackend interface {
DeadlineBackend
// ConsumePendingIn locks, revalidates and provisionally deletes the exact pending-MFA
// credential in the caller's transaction.
ConsumePendingIn(context.Context, *database.Tx, Address, Record) error
}
CompletionBackend can replace a pending-MFA credential in checked creation. ConsumePendingIn joins the supplied transaction, locks and revalidates the exact pending record/hash/identity/expiry, and deletes it provisionally. It rejects full credentials. CreateBefore runs the check and creates through the ordinary creation path, then rechecks the pending deadline before commit. Both methods preserve rollback, never retry, and return no secret on failure.
type Config ¶
type Config struct {
Namespace keyspace.Namespace
Regular Lifetime
Remembered Lifetime
Pending Lifetime
MaxPerSubject int
MaxPendingPerSubject int
Limit auth.LimitPolicy
MaxConcurrent int
Timeout time.Duration
}
Config contains store-wide resource limits and explicit credential lifetimes. Changing policy affects new sessions; use revocation to invalidate old sessions. MaxPerSubject caps a subject's live full sessions per guard; Limit selects whether a new login evicts the oldest (default) or is rejected with auth.CredentialLimit. Pending-MFA and impersonation sessions never count toward it: each class has its own MaxPendingPerSubject cap and always replaces its oldest session, so MaxPerSubject + 2*MaxPendingPerSubject must not exceed MaxSessions. Expired sessions never count toward any cap.
func DefaultConfig ¶
DefaultConfig returns default regular, remembered and pending lifetimes, credential capacity and operation bounds.
type ConfirmationBackend ¶
type ConfirmationBackend interface {
// Confirm stamps confirmation on a live, fully authenticated session, omitting the
// result when it is gone.
Confirm(context.Context, Address, model.Identity, model.ID[Record]) (value.Optional[Record], error)
// ConfirmedWithin checks whether the live session confirmed within the duration of the
// authority's current time.
ConfirmedWithin(context.Context, Address, model.Identity, model.ID[Record], time.Duration) (bool, error)
}
ConfirmationBackend stamps ConfirmedAt on one live, fully authenticated session of the subject and returns the updated record, or omits it when the session is gone. ConfirmedWithin reports whether that live session confirmed within the duration of the backend's current time. Both sample its clock.
type Creation ¶
type Creation struct {
ID model.ID[Record]
Subject model.Identity
Hash Digest
Assurance auth.Assurance
Remember bool
Lifetime Lifetime
Maximum int
PendingMaximum int
Limit auth.LimitPolicy
Device auth.Device
// Impersonator marks an impersonation session. Impersonation sessions count
// only against PendingMaximum, like pending MFA, so they never evict or are
// rejected by the subject's own sessions.
Impersonator value.Optional[Impersonator]
}
Creation contains verified identity metadata and a newly generated hash. Maximum is the live full-session bound and PendingMaximum the live pending-MFA bound, both enforced under the subject's write lock for the credential's own kind. Limit selects eviction or rejection for full sessions; pending sessions always evict their oldest. Expired rows never count.
type DeadlineBackend ¶
type DeadlineBackend interface {
CheckedBackend
// CreateBefore performs checked creation and rechecks the supplied deadline before
// commit, rolling back joined writes on expiry.
CreateBefore(context.Context, Address, Creation, temporal.DateTime, func(context.Context, *database.Tx) error) (Record, error)
}
DeadlineBackend performs checked creation and rechecks an existing credential's deadline before commit. Expiry rolls back all joined writes.
type Digest ¶
type Digest struct {
// contains filtered or unexported fields
}
Digest is a SHA-256 credential hash at the explicit adapter boundary. It cannot be submitted in place of the raw session secret.
func HashSecret ¶
HashSecret accepts only a canonical 256-bit random session-secret encoding. Malformed inputs fail before any persistence operation.
func ParseDigest ¶
ParseDigest restores a session digest from its hexadecimal representation.
type ID ¶
type ID[M any] struct { // contains filtered or unexported fields }
ID is a public session identifier owned by model M. It is not an authentication secret or a model primary key, and remains stable across session rotation.
func (ID[M]) MarshalText ¶
MarshalText encodes the session identifier in text form.
type Impersonation ¶
type Impersonation[A model.Identifiable, AK any, M model.Identifiable, K any] struct { // contains filtered or unexported fields }
Impersonation lets an authenticated actor of one session binding act as a model of another (or the same) binding, for support and administration. The impersonation session records the actor, its guard and its own session, so the original actor stays accessible and the session is visibly marked: Info.Impersonated, Sessions.RequireNotImpersonating and ConfirmCurrent refuse sensitive operations and mint no other credential (CurrentProof, RevokeOthers). Sessions are bounded by a maximum duration, never remembered, counted apart from the subject's own sessions, and end when the actor's own session is revoked or expires, so both bindings must share one store.
Authorize the actor (for example with a policy on the target model) before Start: the binding does not decide who may impersonate whom. Observers receive EventImpersonationStarted and EventImpersonationStopped, which an audit or outbox observer can persist.
func NewImpersonation ¶
func NewImpersonation[A model.Identifiable, AK any, M model.Identifiable, K any](actors *Sessions[A, AK], targets *Sessions[M, K], maximum time.Duration) (*Impersonation[A, AK, M, K], error)
NewImpersonation validates the duration bound and requires actor and target sessions to share the same store.
func (*Impersonation[A, AK, M, K]) Actor ¶
Actor returns the original actor behind the current impersonation session of the targets guard, loaded through the actors provider, or an omitted value when the current session is not impersonated.
func (*Impersonation[A, AK, M, K]) Actors ¶
func (i *Impersonation[A, AK, M, K]) Actors() *Sessions[A, AK]
Actors and Targets return the bound session bindings.
func (*Impersonation[A, AK, M, K]) Resume ¶
func (i *Impersonation[A, AK, M, K]) Resume(ctx context.Context) (Issued[A, AK], error)
Resume ends the current impersonation session and returns the original actor's session with a fresh secret, for flows where actor and target share one cookie. The actor session recorded at Start is rotated in place: it keeps its ID, creation time, absolute expiry and remember policy, so impersonation can never extend an actor's session. When the actor's session was revoked, rotated or expired meanwhile, or the actor is no longer eligible, the impersonation still ends and Resume fails with auth.Unauthenticated caused by ActorSessionEnded: the actor must log in again.
func (*Impersonation[A, AK, M, K]) Start ¶
func (i *Impersonation[A, AK, M, K]) Start(ctx context.Context, target model.Reference[M, K], duration time.Duration) (Issued[M, K], error)
Start issues an impersonation session for target, marked with the current actor session of the actors guard, lasting at most duration (and the configured maximum). The actor's own session is not revoked; Resume or Stop returns to it. Nested impersonation and self-impersonation are refused; the target must exist and be eligible through its provider.
func (*Impersonation[A, AK, M, K]) Stop ¶
func (i *Impersonation[A, AK, M, K]) Stop(ctx context.Context) error
Stop ends the current impersonation session. Use it when the actor keeps its own credential (another cookie or token); its session is untouched.
func (*Impersonation[A, AK, M, K]) Targets ¶
func (i *Impersonation[A, AK, M, K]) Targets() *Sessions[M, K]
Targets returns the target session binding.
func (*Impersonation[A, AK, M, K]) Validate ¶
func (i *Impersonation[A, AK, M, K]) Validate() error
Validate checks that actor and target session bindings are configured.
func (*Impersonation[A, AK, M, K]) WithObserver ¶
func (i *Impersonation[A, AK, M, K]) WithObserver(observer auth.Observer) (*Impersonation[A, AK, M, K], error)
WithObserver returns a copy reporting impersonation start and stop.
type Impersonator ¶
Impersonator is the original actor of an impersonation session: its stored identity, the guard that authenticated it and that actor's own session, which Impersonation.Resume and Stop use to return. It is metadata, never authority.
func (Impersonator) Validate ¶
func (i Impersonator) Validate() error
Validate checks the actor identity, guard and nonzero actor session identifier.
type Info ¶
type Info[M, K any] struct { // contains filtered or unexported fields }
Info exposes session metadata with a concrete stored subject reference. It carries no secret/hash and does not authorize the caller to act as that subject.
func (Info[M, K]) ConfirmedAt ¶
ConfirmedAt is when the holder last re-entered its password in this session.
func (Info[M, K]) IdleExpiresAt ¶
IdleExpiresAt returns the session's current inactivity deadline.
func (Info[M, K]) Impersonated ¶
Impersonated reports whether this session was started by impersonation.
func (Info[M, K]) Impersonator ¶
func (i Info[M, K]) Impersonator() value.Optional[Impersonator]
Impersonator is the original actor when this is an impersonation session.
func (Info[M, K]) LastSeenAt ¶
LastSeenAt returns the session's recorded activity time.
func (Info[M, K]) Remembered ¶
Remembered reports whether the session uses the remembered lifetime policy.
type IssueOptions ¶
type IssueOptions struct{ Remember bool }
IssueOptions selects persistence policy after credential verification. Pending MFA credentials cannot request remember-me persistence.
type Issued ¶
type Issued[M, K any] struct { // contains filtered or unexported fields }
Issued owns the newly generated secret. Only Secret exposes it for the explicit transport boundary; routine formatting and JSON never serialize credentials. Losing the response may leave an orphan session until expiry or revocation.
type Lifetime ¶
Lifetime fixes server-side expiry at creation. Sliding can extend idle expiry but never the absolute deadline. Rotation never restarts the absolute lifetime.
func (Lifetime) TouchInterval ¶
TouchInterval is the minimum age of LastSeenAt before a sliding session's activity is written again: max(1 minute, Idle/20), but never more than half the idle lifetime, so a short idle window still slides for an active user. Skipping more frequent writes avoids a row update per request; idle expiry may therefore arrive up to this interval earlier than Idle after the last request.
type Record ¶
type Record struct {
ID model.ID[Record]
Address Address
Subject model.Identity
Hash Digest
Assurance auth.Assurance
Remember bool
Lifetime Lifetime
CreatedAt temporal.DateTime
LastSeenAt temporal.DateTime
IdleExpiresAt temporal.DateTime
ExpiresAt temporal.DateTime
Device auth.Device
// ConfirmedAt is when the holder last re-entered its password (see
// Sessions.ConfirmCurrent). It never outlives the session.
ConfirmedAt value.Optional[temporal.DateTime] `json:",omitzero"`
// Impersonator marks an impersonation session with its original actor.
Impersonator value.Optional[Impersonator] `json:",omitzero"`
}
Record is a bounded, immutable-value adapter result. Adapters never return a raw secret. Public typed consumers receive Info or Issued, not these records.
func (Record) NeedsTouch ¶
NeedsTouch reports whether a live sliding session should record activity now.
type ResumptionBackend ¶
type ResumptionBackend interface {
// ResumeActor runs check and rotates the exact live original actor session in one
// transaction, omitting revoked, rotated, expired or impersonated records.
ResumeActor(context.Context, Address, Record, Digest, func(context.Context, *database.Tx) error) (value.Optional[Record], error)
}
ResumptionBackend returns to the original actor's session after impersonation. ResumeActor runs check first, then, in the same transaction and under the subject lock, locks the exact live, fully authenticated, unimpersonated record (same hash, ID, subject, creation time and absolute expiry) and replaces its secret hash with next, recording activity. The ID, creation time, absolute expiry and remember policy never change. A revoked, rotated, expired or impersonated record returns an omitted value and changes nothing. It never retries.
type SelectiveBackend ¶
type SelectiveBackend interface {
// RevokeOthers removes every session of the subject except keep, returning the count.
RevokeOthers(context.Context, Address, model.Identity, model.ID[Record]) (uint64, error)
}
SelectiveBackend revokes every session of a subject in this address except keep, under the same subject lock as creation. It returns the removed count.
type Sessions ¶
type Sessions[M model.Identifiable, K any] struct { // contains filtered or unexported fields }
Sessions binds one stored model/provider/guard/source to a shared store. Its Guard is constructed once; persisted credentials cannot be rebound to a different guard name by extracting an unscoped strategy. Construction performs no I/O.
func New ¶
func New[M model.Identifiable, K any](store *Store, name auth.GuardName, provider auth.Provider[M, K], source auth.CredentialName) (*Sessions[M, K], error)
New validates and binds a session store, provider, guard name and credential source.
func (*Sessions[M, K]) CompleteMFA ¶
func (s *Sessions[M, K]) CompleteMFA(ctx context.Context, raw secret.String, factor auth.SecondFactor[M, K], options IssueOptions) (Issued[M, K], error)
CompleteMFA replaces a live pending credential from THIS guard with one fresh authenticated credential. The lookup is only a locator; checked creation revalidates and consumes it with the current model and factor in one transaction. Full, expired, revoked, wrong-guard or already-consumed credentials are rejected. No reusable authenticated proof escapes, and failures return no new secrets. Options belong to the server's login policy, not unvalidated client claims.
func (*Sessions[M, K]) ConfirmCurrent ¶
ConfirmCurrent records that the holder of the current session re-entered its password now. Call it only after verifying the password (for example with auth.PasswordLogin.Confirm); RequireConfirmed then admits sensitive actions.
func (*Sessions[M, K]) Current ¶
Current returns the metadata of the session that authenticated this guard in the current auth scope (for example to mark "this device" in List results by comparing IDs). It reuses the scope's verification; no second lookup runs.
func (*Sessions[M, K]) CurrentProof ¶
CurrentProof returns a proof for the current request's model, for issuing a related credential (for example an API token) without constructing an unrestricted proof from a submitted identity. Sessions carry no scope grants. An impersonation session is refused with auth.ImpersonationForbidden: the impersonator must not mint an unmarked token or session for the subject.
func (*Sessions[M, K]) Guard ¶
Guard returns the session authentication guard, or an undefined guard for a nil binding.
func (*Sessions[M, K]) Issue ¶
func (s *Sessions[M, K]) Issue(ctx context.Context, proof auth.Proof[M, K], options IssueOptions) (Issued[M, K], error)
Issue persists a verified proof. This is a trusted login boundary, not password verification. A proof must come from a trusted authentication flow; a parsed client identity or request DTO must never be promoted to a proof here.
func (*Sessions[M, K]) List ¶
func (s *Sessions[M, K]) List(ctx context.Context, reference model.Reference[M, K]) ([]Info[M, K], error)
List returns at most MaxSessions live sessions for this model identity. It exposes typed metadata, never stored hashes or raw secrets. It does not itself authorize the calling user to inspect another user; use an ordinary policy.
func (*Sessions[M, K]) Logout ¶
Logout revokes a presented session secret and reports EventLogout when it removed a session. Browser adapters use it for the cookie's own logout.
func (*Sessions[M, K]) Prune ¶
Prune removes up to limit expired sessions within this binding's address.
func (*Sessions[M, K]) PruneExpired ¶
PruneExpired prunes expired sessions of this guard in batches of batch rows, stopping after a short batch or maxBatches, and reports the rows removed. Schedule it from the application calendar or the configured housekeeping schedule; the auth package does not depend on the scheduler.
func (*Sessions[M, K]) RequireConfirmed ¶
RequireConfirmed returns auth.ConfirmationRequired unless the current session confirmed its password within the given duration, checked against the backend's current time rather than the scope's cached metadata.
func (*Sessions[M, K]) RequireNotImpersonating ¶
RequireNotImpersonating returns auth.ImpersonationForbidden when the current session is an impersonation session. Call it before sensitive operations such as changing the password, email or MFA factors, or deleting the account.
func (*Sessions[M, K]) Revocation ¶
func (s *Sessions[M, K]) Revocation() (auth.Revocation[M, K], error)
Revocation contributes this bound guard to auth.NewRevocations. Construct the group once and pass its Invalidate method to password-reset/domain callbacks.
func (*Sessions[M, K]) Revoke ¶
Revoke hashes the credential and removes its session, reporting whether it existed.
func (*Sessions[M, K]) RevokeAll ¶
func (s *Sessions[M, K]) RevokeAll(ctx context.Context, reference model.Reference[M, K]) (uint64, error)
RevokeAll removes the reference's sessions after checking provider ownership.
func (*Sessions[M, K]) RevokeAllIn ¶
func (s *Sessions[M, K]) RevokeAllIn(ctx context.Context, tx *database.Tx, reference model.Reference[M, K]) (uint64, error)
RevokeAllIn joins a caller's transaction. Its count is provisional and the caller must propagate errors. It never acquires a model lock; credential-change orchestration must lock that model first. Unsupported adapters fail closed.
func (*Sessions[M, K]) RevokeCurrent ¶
RevokeCurrent revokes the session that authenticated this request, for API logout on an authenticated route. It reports EventLogout when it removed it.
func (*Sessions[M, K]) RevokeID ¶
func (s *Sessions[M, K]) RevokeID(ctx context.Context, reference model.Reference[M, K], id ID[M]) (bool, error)
RevokeID removes a listed session belonging to this exact subject and guard. The identifier is not authority; authorize the caller before choosing a subject.
func (*Sessions[M, K]) RevokeOthers ¶
RevokeOthers revokes every other session of the current subject in this guard while keeping the current one ("log out other devices"). It runs under the subject lock shared with issuance and reports EventOtherDevicesLoggedOut. Combine with the model's other credential stores for a full sign-out.
func (*Sessions[M, K]) Rotate ¶
func (s *Sessions[M, K]) Rotate(ctx context.Context, credential secret.String) (Issued[M, K], error)
Rotate atomically changes a live session's secret. The previous secret becomes invalid, while session ID, assurance, creation time and absolute expiry persist. Parallel rotations have at most one winner. Failed/uncertain writes are not retried.
func (*Sessions[M, K]) WithObserver ¶
WithObserver returns a binding sharing this guard that reports EventLogin for full issuance (including MFA completion), EventLogout for Logout and RevokeCurrent, and EventOtherDevicesLoggedOut for RevokeOthers.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store borrows a backend and owns limits shared by its typed session bindings. The caller owns the backend's database/connection lifecycle.
type TransactionalBackend ¶
type TransactionalBackend interface {
// RevokeAllIn removes the subject's sessions within the caller-owned transaction,
// without committing or retrying.
RevokeAllIn(context.Context, *database.Tx, Address, model.Identity) (uint64, error)
}
TransactionalBackend joins a caller-owned transaction. It must verify pool ownership, restore schema state, preserve rollback, and never commit or retry.