Help us shape the future of Go! Take the 2026 Go Developer Survey

session

package module
v0.0.0-...-789096f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 27 Imported by: 28

README

Session

Explicit password-bearer issuance

NewPasswordBearerSessionIssuer uses the same prospective password preparation, one-bind/one-issue custody and owned native executor as browser signin, but requires zero IssuerConfig.Cookie and returns no cookie attributes or synchronizer state. It does not remove CSRF from an existing session or turn a structural password projection into authentication. The password owner still performs real comparison, current-authority checks and atomic session/audit/lifecycle persistence. Only an exact acknowledged new commit can deliver the original bearer; historical, ambiguous, cancelled and expired outcomes cannot. Existing constructors retain their cookie requirements and behavior.

Explicit organization-bearer admission

NewOrganizationBearerProfileSessionService retains the selected-method reader contract, but organization-bearing records require bearer transport and cannot retain cookie-bound CSRF state. Ordinary unselected cookie/bearer admission and existing constructors are unchanged. Use this profile when the native owner has not composed selection with browser-state replacement.

The restriction applies to fresh, same-process cached and encrypted-cache admission. Encrypted context binds it, so an older permissive reader's positive cannot cross into the restricted profile. Matching cached evidence keeps its original exclusive deadline; copying, retries and refresh attempts cannot extend it. The owned reader still must enforce every current organization/member and primary authority. This factory does not issue, select or grant an organization.

Exact-session organization selection intent

NewOrganizationSelectionCommand freezes one self-session set/clear CAS for the organization-owned identity.organization.active-set operation. Its ActiveOrganizationSelection binds the exact SessionID, tenant, expected positive SessionVersion and organization-owned authority scope/version. An empty organization ID with zero authority explicitly clears selection; absence never means "leave unchanged". Selection is not membership or permission.

The successor retains original authentication, credential continuation, token lookup, family, remember policy, activity and lifetime. Only the session version/vector and organization dimension change. Version-bound CSRF is cleared, not copied into the successor. No credential, current validity or fresh login is created. Zero/foreign/malformed/overflow inputs fail without a partial command.

This is a storage-neutral prerequisite, not an executable selector. The native organization participant must authenticate the actual current session, validate membership/lifecycle/policy and invoke the session-owned effect in its existing coordinator transaction. It must retain the original evidence deadline and require the successor at final commit. Cookie composition needs separately owned replacement synchronizer delivery; it cannot be enabled by this constructor. Other authority dimensions must be preserved or the unsupported profile denied.

Passkey primary with a separate enrolled factor

NewMFAPasskeySessionIssuer and its WithCSRF variant explicitly select PrepareMFAPasskey followed by the existing one-use BindMFA/Issue path. The current selection completes TOTP, not OTP/recovery or an implicit "UV means all configured MFA is satisfied" policy. Password and magic-link issuers do not admit this origin; the ordinary passkey issuer cannot skip the factor. Only an exact acknowledged new commit can reveal the original bearer/synchronizer; replay, ambiguity, failure or expired delivery reveal none.

NewSessionWithPasskeyMFA and its CSRF variant reconstruct trusted historical projections without authenticating them. Preserve the original credential, PasskeyMFAPrimaryPurpose, phishing-resistant assertion, passkey/factor epochs, independent factor and resolved remember choice. Factor completion cannot renew primary freshness or extend original expiry. The native completion must prove the retained assertion, browser, child, current account/credential/policy and actual factor and commit all effects in one transaction. These structural APIs alone do not enable a login endpoint or native passkey-MFA session reader.

Explicit prospective passkey-only signup

NewPasskeySignupSessionIssuer and its WithCSRF variant select anonymous passkey signup without broadening the existing assertion or password profiles. PreparePasskeySignup freezes the original tokenless prospective session; BindPasskeySignup binds its exact original command once. The signup command's record is the new credential, while the session has its own allocated ID. The owned native executor receives the separate PasskeySignupCommand arm; legacy PasskeyCommand never interprets signup as an authenticated assertion.

Account, credential, authorization, known-empty factor and passkey generations start at one. Original deployment epochs, remember, proof expiry and CSRF remain unchanged. Copies share one issuance attempt, and only an acknowledged new commit can reveal the prepared bearer/synchronizer. Replay, ambiguity, substituted records, failure and late results reveal neither. Native metadata recovery must not prepare or deliver another token.

Preparation is not WebAuthn verification or signup permission. The owned native adapter must prove real registration and original pre-auth/risk custody, then commit account, protocol, RP mapping, factor/policy, session and required lifecycle effects atomically. This issuance contract alone is not a signup workflow or public endpoint and accepts no application-written authority store.

Explicitly unprivileged anonymous recognition

NewAnonymousSessionService selects anonymous-only primary validation and returns AnonymousGetResult, not authenticated-user GetResult. Recognized means only that the original anonymous session credential is currently valid; it grants no verified assurance, permanent-account authority or permission to select an upgrade target. ValidateAt and ValidUntil preserve the original bounded primary-read deadline. Ordinary verified/mixed readers continue to reject anonymous records.

The configured owned reader must establish actual anonymous lifecycle, directory, expiry and exact session authority. This read contract does not issue a session or implement anonymous creation, deletion or upgrade; those native workflows and their explicit composition remain in development. Organization/factor/passkey authority and permanent credentials are rejected by this profile.

For prospective creation, NewAnonymousSessionIssuer (or its explicit CSRF variant) selects a separate, unprivileged issuance profile. PrepareAnonymous retains the original session and remember policy; map its complete tokenless projection into native intent before the one-use BindAnonymous. Existing Issue delivers the original bearer only after an exact new committed receipt. Replay, ambiguity, failure, substituted records and expired delivery withhold it. This preparation is not risk approval or identity creation: native anonymous lifecycle and session persistence must still be connected before deployment. The anonymous request cannot enter verified-proof issuance or proof recovery.

Prospective permanent-session upgrade

NewAnonymousUpgradeSessionIssuer (or its CSRF variant) selects only the native identity.anonymous.upgrade.native-v1 profile. PrepareAnonymousUpgrade retains the permanent target's prospective session, exact guest lifecycle version and earliest original admission deadline, bounded to20s. The guest is the distinct command resource, not its user/actor. Bind the complete session to native intent before BindAnonymousUpgrade; the command must retain target-bearer custody and the exact anonymous.source-version. No scalar projection proves possession.

This single-factor password profile preserves historical authentication metadata and age; it does not fabricate a signin proof. The native executor must verify both actual sessions, consume fresh target-specific reauthentication and the one-use transition, apply supported merges, revoke the guest and persist exactly one permanent session atomically. The guest's resolved remember policy must not change. Other factor/organization/passkey or credential-continuation profiles deny. Issuance uses the original exclusive deadline again after the executor; only an exact new committed receipt permits bearer/CSRF delivery. Historical, unknown and failed results disclose neither. Recovery is the native workflow's credential-free original correlation, never a new preparation or token.

Sessionless phone-recovery pre-authentication

Select PreAuthPhonePasswordRecovery in both PreAuthIssuerConfig.Purpose and the matching native executor profile. It admits only identity.phone.password-reset-request, requires the original canonical-number commitment and rejects every RememberPolicy. The existing issuer, durable pre-auth record and commit-gated flow cookie are reused; no session is created. The distinct recovery cookie domain cannot become a login continuation. This prepares recovery only: canonical capability, SMS/TOTP, risk and the atomic password/session mutation remain the reset workflow owner's responsibility.

The prospective password issuer also accepts the closed identity.username.signin/username-signin v1 binding without relabeling it. It retains the same original password/cookie custody and session projection. The native workflow must still establish current username ownership, actual password comparison, risk, verification and factor policy before committing. This structural support alone does not expose a username login route.

Post-verification email-possession issuance

NewEmailVerificationSessionIssuerWithCSRF is an explicit, disjoint issuer for native registration confirmation followed by signin. PrepareEmailVerification binds the child command to its committed confirmation parent (RecordID), the original signup/grant, verified address versions and original resolved Remember. It reuses historical email-grant provenance (AuthenticationMagicLink), not a password proof. The native owner must authenticate original browser possession and current account/authorization/risk/MFA before committing. Preparation alone grants no authority; replay, recovery, error and ambiguity disclose no token.

This experimental module uses authentication v2, authorization v3 and the matching identity kernel. Supply primitive values from those major imports; older-major types are not interchangeable.

Use NewMagicLinkAuthentication with the original consuming command, request, grant and verified-address versions, then NewSessionWithMagicLink (or NewSessionWithMagicLinkAndCSRF) for trusted complete reconstruction. Store MagicLinkAuthentication().Bindings() alongside the base and synchronizer. Construction is not cryptographic verification or successful consumption. Native login must establish both in the protected issuance transaction.

The original authentication/admission expiry is immutable; it does not shorten an already issued session's resolved remember policy. Updates and rotation retain provenance; encrypted cache promotion cannot renew primary validity. Legacy proof/OTP issuance cannot accept these projections. Organization, MFA and passkey combinations require their real owners and currently fail closed.

NewMethodSessionService restricts primary and cache admission to one method. Owned adapters use NewProfileSessionService to additionally bind the complete selected native authority/store profile into encrypted-cache context. Shared wrapping keys cannot transfer a positive between methods or selected profiles. Changing profile makes old entries cache misses and requires primary refresh; the generic reader-selected constructor retains its historical cache framing. Separate physical stores must also use distinct issuer/environment/deployment context when sharing envelope keys. Original expiry never resets on refresh failure or cache promotion.

Optional signup session issuance

NewPasswordSignupSessionIssuerWithCSRF selects a disjoint prospective registration profile. Use PrepareSignup, map its complete session/CSRF state into the native registration intent, then BindSignup with the original paired prepared-verifier/pre-auth command. The executor receives PasswordSignupCommand, not the signin, OTP or authenticated-proof arm. Original scope, remember choice and deadlines are retained; copies share one binding and issuance attempt.

Preparation is not authentication. The native password owner must enforce that verification and MFA requirements are complete and commit account, password, flow/risk consumption, session and audit/outbox atomically. Only fresh, exact, error-free, non-replayed commit results deliver bearer/CSRF. Unknown outcomes require separate secret-free native recovery; do not prepare replacement tokens. The native signup persistence/effect and full workflow remain in development.

Browser-device correlation for abuse control

NewBrowserDeviceCodec(BrowserDeviceConfig) freezes explicit dedicated key versions, deployment/environment namespace, whole-second lifetime (1 hour to 7 days), and __Host-identity_device host-cookie policy. Use independently generated NewBrowserDeviceKey material; the greatest eligible version issues new cookies, and retained versions verify old ones. Never reuse key versions for different material. Retain old keys for the entire original cookie lifetime, or deliberately invalidate that version. Namespace changes invalidate cookies.

After HTTPS host/origin and IP admission, Issue generates one browser-random correlation cookie. Deliver its sensitive CookieHeader() through Set-Cookie, never JSON, redirects, logs or cacheable responses. On subsequent requests, strictly acquire exactly one cookie value, then Resolve with current resolved tenant/origin and trusted time. Reuse valid custody across new login flows; Resolve returns no cookie header and never renews the original expiry. Absent custody may initialize a fresh browser during explicit flow initiation; malformed, duplicate, mismatched or expired cookies must not silently fall back in Send. Transport integration is still pending; the codec alone exposes no route.

DeviceID() is only tenant/origin/environment-scoped abuse correlation—not login, session, human identity, physical device, browser fingerprint or MFA trust. Clearing or copying cookies evades/shares this signal. Independent network and identifier controls remain mandatory; do not use this cookie to recover an account, skip a factor or authorize any protected operation. The cookie reveals only a random nonce, key version and timeline under a domain-separated MAC. No account, contact, user-agent or IP is stored in it. Original expiry bounds retention; privacy-disabled deployments must not issue it. Existing session revocation is independent, and this signal cannot outlive or bypass authority.

The fixed v1 wire profile is 85 bytes, canonical unpadded base64url (114 bytes): version byte1, big-endian uint32 key version, uint64 issued/expiry Unix seconds, 32-byte CSPRNG nonce, then HMAC-SHA-256. MAC input is golib.browser-device.cookie.v1\x00, uint16-length-framed namespace/tenant/origin, and the first53 bytes. Stable signal is SHA-256 over the distinct golib.browser-device.signal.v1\x00 domain, the same scope frame and nonce. Unknown format/key, noncanonical encoding, unsigned timestamp overflow, future issuance, exact expiry and lifetimes beyond current policy deny uniformly. Methods are concurrent-safe and own no stores, callbacks, goroutines or services. Full browser/reference, coverage/mutation and release qualification remain pending.

OTP authentication provenance prerequisite

OTP is not a password/provider credential. AuthenticationOTP therefore has zero legacy proof and credential fields, and requires a separate immutable OTPAuthentication projection. NewOTPAuthentication validates original consuming/signin and Send command IDs, challenge and attempt identities, the exact verified email/phone identifier and versions, and original successful authentication/continuation times. This is historical metadata, not a proof, code, bearer, current eligibility check or permission to issue a session.

Reconstruct complete trusted storage with NewSessionWithOTP or NewSessionWithOTPAndCSRF; persist Bindings, OTPAuthentication().Bindings() and any CSRFState().Bindings() together. NewSession deliberately rejects an OTP base without its metadata. Original continuation expiry bounds issuance, not the subsequently issued session; RememberPolicy retains the original authentication time for freshness and never extends it on rotation or update. Organization, factor and passkey profiles are currently rejected explicitly.

Core reader admission accepts OTP only through its trusted configured reader's complete current authority observation. Encrypted cache schemas3/4 retain OTP without/with CSRF, while legacy schemas1/2 remain unchanged. Cache copies and restart preserve the original authoritative deadline, including during outage. Metadata updates and rotation preserve OTP provenance; version changes clear or replace exact-version CSRF state. The existing credential-proof issuance route rejects OTP metadata rather than treating it as authentication authority.

This is a core prerequisite, not complete OTP signin. The PostgreSQL OTP record codec is available through its explicit forward migration. The opt-in authoritative reader and atomic OTP-to-session effect are still required; existing proof-only native profiles fail closed for OTP. Do not supply consumer-written credential rows or a second transaction to bridge that gap. No store, coordinator or replay journal is added by this projection.

NewCookieSignOutService(base, eligibleKeys) selects a strict cookie-only variant of the existing self-signout workflow. Supply 1..4 independent dedicated CSRF keys with distinct positive versions; the constructor copies the slice. The deployment owns eligibility and retirement of current/retained keys. CSRFKey.Version() exposes only rotation metadata, never key material. Construction rejects an executor without the explicit CSRFRevokeOneExecutor contract; strict execution invokes ExecuteRevokeOneWithCSRF, never its legacy method. Merely accepting the new request type cannot enable browser protection.

Call SignOut(ctx, request, csrfToken) after HTTP has enforced trusted origin, strict cookie extraction and one canonical token channel. The request retains the existing SignOutRequest shape and must select CredentialCookie. An active session requires the exact state-named eligible key and matching token. Absent/inactive credentials retain idempotent success without an impossible active-state check. Bearer transport cannot enter this variant. Existing SignOutService.SignOut remains the trusted direct/bearer API; it is not by itself a browser CSRF enforcement layer.

PrepareRevokeOneWithCSRF retains the original private caller admission and opaque token without renewing its deadline. Trusted executors inspect optional RevokeOneRequest.CSRFToken() custody without revealing it. They must choose their own trusted named key and recheck against the exact original active primary session under the original protected transaction's mutation fences. An executor lacking that profile must reject before reservation. The raw token and key must never enter durable command intent, audit, recovery or errors. Prechecking is not a substitute for transactional admission.

This core prerequisite is not yet qualified against the native executor or an HTTP endpoint. The owned native factory/enforcement is the next integration step; do not wire a legacy executor and claim browser protection. No new store, transaction coordinator, crypto engine or recovery journal is introduced.

Synchronizer CSRF state prerequisite

CSRFToken holds exactly 32 random bytes, not a session bearer or a signed stateless token. NewCSRFKey copies dedicated 32..64-byte material and a positive version; never reuse session-lookup or other credential keys. Explicitly select the newest issuance key and retain named old keys only during configured overlap. Key-ring selection and overlap policy are not implemented by these values.

token.Digest(key, CSRFBinding{TenantID, SessionID, SessionVersion}) produces immutable digest-only CSRFState. Its documented HMAC framing uses the domain identity-csrf-v1 followed by NUL, length-prefixed exact canonical tenant and session IDs, big-endian session version and the 32 raw token bytes. Lengths prevent ambiguous concatenation of different identifier pairs. Persist only Bindings()' complete scope/key-version/digest projection, never the raw token. NewCSRFState rejects incomplete state; zero state denies every check.

Check compares the exact binding and named-key digest without consuming the token or renewing authority. It is structural agreement, not authentication: the durable owner must read/fence current active state with the protected mutation. A cached session, caller-supplied projection or prior successful check cannot establish current validity. Formatting/automatic serialization redact or deny; copies share one reveal permission. The original issuance owner must withhold delivery until its exact new commit, including on recovery or ambiguity.

Native record and original delivery

NewSessionWithCSRF(baseSpec, state) rejects state bound to a different tenant, session or version. Existing SessionSpec, configurations and result structs retain their shapes. Session.Bindings() retains the original base projection; complete storage must also persist Session.CSRFState().Bindings(). Rebuilding only the base creates an explicitly tokenless legacy record, not an equivalent CSRF-bearing session. Native equality compares both projections semantically, including independently reconstructed immutable state.

Select NewSessionIssuerWithCSRF(executor, config, newestKey) for cookie issuance. Prepare generates separate bearer and CSRF custody and freezes only their digests in the command. After the exact new error-free Issue, retrieve the original prepared.CSRFToken() and explicitly reveal it at approved no-store HTTP delivery. Precommit, replay, recovery-only, error, cancellation, expired or unknown execution grants no CSRF delivery. Repeated access shares the original reveal permission; a later rejected retry cannot retract custody already obtained from the original successful execution.

NewSessionRotatorWithCSRF replaces cookie synchronizer state at the new session version, with the same delivery gates through PreparedRotation. Bearer rotation clears state and emits no CSRF credential or cookie. A legacy rotator cannot silently downgrade a CSRF-bearing cookie session. Metadata updates advance session version and clear state without issuing a new token; the source remains immutable. Future protected cookie mutations then deny until an owned authorized flow issues replacement state.

Encrypted-cache schema 2 preserves digest-only state and the original admission deadline. Schema 1 remains unchanged and tokenless; unknown, partial or misbound state falls back to bounded primary validation, never synthetic CSRF validity. A warm restored state still cannot prove current primary CSRF authorization.

This is not complete CSRF protection. Primary/OTP codecs, atomic lifecycle invalidation, configured key overlap, and HTTP origin/channel enforcement remain pending. Do not compose this opt-in profile with legacy lossy adapters; consumers must not implement private stores to bridge those gaps.

Canonical pre-auth continuation

PreAuthPrepareInput.IdentifierBinding optionally retains a server-derived, tenant/purpose/comparison-profile-bound commitment to the canonical identifier. The flow owner computes and requires it before credential verification; it is not plaintext, a client-selected hash or authentication. It remains in the immutable PreAuthIntent and its equality check. Bound flows use a separate cookie-digest domain; zero keeps the exact existing unbound cookie framing. Changing or clearing a retained commitment cannot reuse original possession. Persistence must retain it unchanged; never silently load a bound flow as legacy.

PreAuthTransaction freezes the original ID, tenant, action, exact origin, callback/no-redirect choice, server nonce, selected policy, resolved remember policy and original issued/exclusive-expiry times. General configured TTL is 1..10 minutes; reference initiation uses exactly five minutes. Token.PreAuthDigest uses a dedicated named key and a separate complete-binding HMAC domain, never a session-cookie lookup digest. Retain the original key while the flow is live; copies and retries must not regenerate the binding, nonce, expiry or choice.

These are private structural values, not authentication or primary active-state proof. Check requires authoritative time after locks and never consumes the flow. Owned PreAuthIssuer freezes configured origin/redirect policy and the __Host-identity_flow transport policy. Durable primary reservation/finalization are available in PostgreSQL; complete OTP continuation registration with final session issuance/linking remains under development. No caller-written store or continuation-ID-only authority can substitute for that composition.

PreAuthIssueCommand and PreAuthIssueExecutor are storage-neutral native initiation/recovery contracts. The server retains the same original private record and command ID across retries; execution and restart recovery return only historical command metadata, never a cookie or renewed authentication. The PostgreSQL adapter owns atomic execution; core PreAuthIssuer owns original server entropy and commit-gated reveal-once delivery metadata.

PreAuthIssuanceExecutor adds PreAuthIssueExecution for future commit-gated delivery without changing the receipt-only interface. A committed receipt is not sufficient: the issuer must also require Replayed == false, exact original scope, no error/cancellation and an unexpired original flow. Only acquisition of the sole execution reservation clears Replayed; restart recovery and terminal observations never permit credential delivery. Formatting and implicit JSON/text export of execution metadata redact or deny original custody.

Owned original flow issuance

Compose NewPreAuthIssuer(ownedExecutor, PreAuthIssuerConfig{...}) with the owned PostgreSQL NewPreAuthIssueExecutor. Both configurations must select the same exact trusted service actor, action, origin, callback (or empty for no redirect), policy ID and version. Use a retained dedicated pre-auth digest key, trusted clock, 1ms..30s execution budget, 32..64-byte token and validated __Host-identity_flow Lax/Strict cookie policy. General flow TTL is 1..10 minutes; the reference choice is five minutes. No callback allowlist, actor or policy may be selected directly from client input. Core does not own a store or journal.

Prepare(PreAuthPrepareInput{CommandID, TenantID, CorrelationID, Remember}) accepts the already-resolved session choice and validates before generating the canonical random flow ID, 32-byte nonce and cookie commitment. It performs no durable work or authentication. Retain the returned preparation unchanged; copies share a single local attempt. Command() exposes safe original custody for recovery, never the bearer. Calling Prepare again is not a retry.

Issue(ctx, prepared) preserves earlier deadlines, executes the exact original command, validates its complete receipt and returns a reveal-once Token plus credential-free cookie attributes only on new commitment. Cookie expiry uses whole remaining seconds rounded down within the original flow deadline for both remember choices; a persistent final session never extends the unauthenticated flow. HTTP explicitly reveals the token and sets Cookie.Value only at delivery, without logging. HTTP still owns origin/CSRF checks, mixed or duplicate cookie rejection, no-store response policy and opt-in routes.

Replay/recovery, errors, cancellation, malformed receipt, panic, expired flow and subsecond remaining lifetime deliver no credential. Known commitment is preserved when delivery fails. Unknown requires Recover(ctx, originalCommand) under current service policy; it never reexecutes, returns flow payload, renews time or delivers a credential, even after original expiry. A reconstructed caller projection is not proof of the historical persisted payload. This composition does not authenticate a user or complete a browser login.

Experimental Go 1.27 session policy module. This first batch implements shared remember-policy resolution, lifetime evaluation, secure host-cookie attributes and opaque token/key custody with tenant-bound lookups. Authenticated cookie issuance orchestration is available through SessionIssuer; owned durable executor composition is available in the PostgreSQL adapter. Stateful opaque SessionService.Get validation is available against its trusted owned-reader contract, with an owned primary reader and revocation executor in the PostgreSQL adapter. Public self-signout is available through SignOutService and the owned PostgreSQL factory. Authenticated ListService and its owned PostgreSQL page-reader composition are available. Core fresh bulk-revocation orchestration is available; native set mutation remains pending. Rotation, complete revocation services and transfers remain unfinished; this is not a usable login service. Complete authority-vector construction and exact comparison are available, but do not read primary authority or prove activity/freshness.

Immutable complete session records and exact-bound native issue commands are also available for trusted storage/adapters. They are not session issuance: caller-created authentication.Proof metadata and AuthenticationVerified cannot establish authentication authority. No command by itself executes or opens a transaction, reserves a proof, writes a record or reveals a token.

Quick start and API

Compose NewCookieCache(encryptedCodec, CookieCacheConfig{Credential: originalCookiePolicy, Cache: companionCookiePolicy, MaximumCookieBytes: 3800}). Both policies must be validated __Host- host-only root-path policies with the same explicit Lax/Strict choice and distinct names. Enable this composition explicitly; absence disables it. The codec maximum age must be 1 second through 5 minutes. The entire emitted header, not just plaintext or binary ciphertext, is bounded at 512..3800 bytes, including fixed Priority=High. Over-limit output fails without truncation, chunking or weakening attributes.

cache.Put(ctx, authenticGetResult) accepts only original same-service cookie admission, returning a redacted CacheCookie. Explicitly export its bounded HeaderValue() for the owned HTTP transport. Browser-session remember choices omit persistence; persistent cache cookies cannot exceed the original session expiry or five minutes. Encryption latency never extends the cookie deadline. This is a companion cookie, not the original credential: ciphertext alone cannot authenticate and never upgrades a bearer result into cookie transport.

HTTP supplies cache.Get(ctx, originalGetRequest, selectedCompanionValues) with zero or one exact configured cookie values. Duplicate companion values deny before IO. Missing, corrupt, oversized or noncanonical values require primary validation; the original credential must still match tenant, digest and cookie transport. Positive authority retains its original exclusive deadline, including when Put is called again on a warm result. A failed refresh after expiry never uses stale authorization. No cache write is hidden inside Get.

cache.Deletion() emits the exact companion scope with negative Max-Age and a past expiry; it neither deletes the original credential nor revokes authority. Cookies/header values contain correlated ciphertext and must never be logged. Formatting and implicit JSON/text export redact or deny. HTTP still owns origin, CSRF, mixed original-credential rejection, no-store headers and opt-in routes. Standard-library cookie/parser/jar behavior is tested; full browser-family, reference-server and release acceptance remain pending. This composition does not implement Valkey or the fully stateless profile. NewSessionService keeps its existing stateful primary profile; opt in through this explicit composition.

Bounded positive admission reuse

primarySessions.CacheAdmission(authenticatedGetResult, maximumAge) returns an opaque CachedAdmission only for an unchanged live result minted by that exact service. Age is 1ms..5m but positive reuse is clipped to the original Get deadline (at most 20 seconds from its earliest authority read, conservatively reduced for clock uncertainty and session expiry). The configured trusted clock owns the cache observation. Copies and repeated promotion cannot renew either the original deadline or a previously shortened age.

primarySessions.GetCached(ctx, originalRequest, cachedAdmission) accepts a warm entry only for the exact service, tenant, bearer digest and transport. It retains the complete original session/authority and authenticated-result custody; cookie admission cannot be reused as bearer admission. A zero, stale, foreign or substituted entry uses bounded primary Get. Failed refresh returns no authentication, never stale fallback. Dropped invalidation events therefore cannot extend the original positive-evidence window. Backward clocks and caller cancellation deny; explicit invalidation may discard a handle earlier.

The handle owns no raw bearer, cache store, goroutine or invalidation journal. It is process-local and cannot be JSON/text serialized. It is not a signed or encrypted cookie, durable Valkey projection, stateless codec or new storage profile; those implementations remain unfinished. Consumers must not turn structural Session data or a public Authenticated flag into cache authority. Authorization is still a separate current-policy decision on every action.

Non-authoritative display enrichment

NewEnrichmentService(callback, EnrichmentConfig{Schema: EnrichmentSchema{ Version: 1, FieldNames: []string{"label"}, MaxBytes: 1024}, MaximumDuration: time.Second, FailurePolicy: EnrichmentFail}) freezes a bounded schema. The callback implements SessionEnricher.Enrich(ctx, source, schema) and returns one UTF-8 string per declared field, in schema order. The complete immutable session is the declared source; the callback must honor cancellation and be safe for concurrent calls. Earlier caller deadlines win.

Call the service after independently authenticating and authorizing the source. A structurally valid Session is not proof of current activity. Enrichment is display-only: it never changes the principal, authority, authentication time or session lifetime. Output is untrusted text; transport must escape it and select exported fields explicitly. Implicit JSON and diagnostic export are denied.

Every invocation re-evaluates the complete source without caches, store locks, transactions or background goroutines. Source changes cannot reuse a retained projection. Do not cache output independently of its complete source and any external inputs the callback reads. Cache-profile composition remains separate unfinished work. Callbacks that ignore context cannot be forcibly interrupted; the service does not leak detached goroutines to hide that contract violation.

EnrichmentFail returns a redacted error on callback failure. EnrichmentOmit returns nil display values on callback error or panic only. Cancellation/deadline and malformed successful output always return errors, without partial display values. An empty individual field is valid; omission is not a schema-shaped success. Returned slices and callback schema copies are independently owned. Existing authentication and persistence APIs are unchanged.

Commit-gated session rotation

NewSessionRotator(primarySessions, ownedExecutor, RotationConfig{...}) borrows the exact configured reader and durable rotation executor. The configured lookup key must be retained by that reader with identical version and material. Prepare(originalGetResult, commandID, correlationID) requires opaque original caller admission and an eligible refresh time; premature refresh returns ErrRotationDeferred without execution. Ordinary refresh requires no fresh login. Preparation freezes the exact source and successor without durable IO.

Rotate(ctx, preparation) makes one bounded attempt. It changes only the lookup digest, accepted activity and session/authority version. Original absolute issuance, authentication time, family, remember policy, scope and unrelated authority remain unchanged: rotation cannot turn an old login into fresh authentication. Copies share one attempt, and only a new successful committed result within original admission/context limits returns a reveal-once token. Cookie attributes have an empty value; original bearer transport returns no cookie. HTTP owns extraction, CSRF/origin policy and explicit credential delivery.

Retain preparation.Request() before execution. Replay, error, ambiguity, cancellation and Recover(ctx, originalRequest) never return a credential. Known commitment remains observable even when ancillary metadata is unavailable; recovery observes the historical command under the adapter's current exact result-access policy rather than executing again or renewing caller authority. The storage-neutral core is available; native PostgreSQL atomic digest retirement, reuse-family revocation and durable rotation recovery remain pending. Do not replace those missing effects with an application-written store or journal.

Authenticated session listing

NewListService(primarySessions, ownedPages, ListConfig{Authorization: policy, PolicyRevision: revision, MaximumDuration: budget}) composes the existing authentication and authorization owners. Each List request selects trusted tenant, credential, safe correlation, explicit Limit (1..100) and optional cursor/IncludeInactive; no current-session or user ID can replace a credential. Ordinary self-listing requires current policy, not fresh login. The reader seam is for the owned primary adapter, not an application-written domain store. Its native PostgreSQL implementation is available through its owned factory.

Results contain only device display metadata, exact recorded expiry and current/ inactive flags. Labels are bounded untrusted text, not MFA trusted devices. Inactive records are filtered by default. Work is bounded to the requested number of raw rows, so a filtered page can be empty with a continuation. Continue with its cursor; do not restart at the first page to fill the result. The cursor binds tenant/user/audience/inactive selection but is unsigned and non-authoritative: arbitrary markers may alter traversal, never access policy. Every call authenticates and authorizes anew. Keyset traversal uses exclusive bytewise session-ID order; concurrent inserts before the marker are not revisited. Cancellation, outage, corrupt pages or expired original caller admission return no partial metadata. HTTP owns explicit authorized DTO serialization.

Fresh self-service bulk revocation

NewSetRevocationService(primarySessions, ownedExecutor, SetRevocationConfig{...}) borrows the exact configured primary reader and an owned durable executor. Select explicit policy ID/version, a whole-set bound of 1..100000 active rows and a 1ms..30s whole-call budget. This is storage-neutral orchestration; the native PostgreSQL set executor and atomic recovery are not yet implemented. Consumers must not substitute application-written stores or transactions.

RevokeOther accepts tenant, actual cookie/bearer credential and host-generated command/correlation IDs, never caller-selected user/session IDs. It preserves the authenticating session. RevokeAll additionally requires an explicit IncludeCurrent decision and the positive exact ExpectedSubjectVersion from the authenticated user authority. Targets span that owner's sessions in the same tenant across audiences; another tenant or user is never selected. Bulk actions require fresh authentication, unlike ordinary signout/listing.

Private PrepareRevokeSet custody is bound to the original Get provenance, entire source record and the earlier original authority/freshness deadline. Copies, activity or repeated preparation cannot renew either deadline. The durable owner must serialize against issuance and recheck current source, owner and policy before applying the complete bounded set in one transaction. Exceeding the bound must deny without partial revocation, not truncate or page.

Receipt and recovery RecordID bind the source session whose version advances. SubjectVersion is the unchanged user-authority CAS; SessionVersion is the source successor. A survivor must retain its original bearer, lifetime and authentication timestamps with its matching session-version binding. Unknown or in-progress outcomes retain exact scoped recovery; do not mint a replacement command. Cancellation or expiry after a known commit preserves its outcome but withholds counts/disposition. A failed retained-metadata read likewise preserves the exact known commit with a redacted error and zero success metadata; use scoped recovery rather than issuing another mutation. HTTP clears only the selected transport after successful CurrentSessionRevoked; this core service emits no cookie itself.

Idempotent self-signout

NewSignOutService(reader, executor, SignOutConfig{...}) borrows the exact configured primary SessionService and owned RevokeOneExecutor. Use the PostgreSQL executor configured with that same reader, explicit policy ID/version, 1ms..30s whole-operation duration and the same host-cookie policy as issuance. Construction performs no IO and accepts no application domain store or callback.

SignOut(ctx, SignOutRequest{TenantID: tenant, CommandID: commandID, CorrelationID: correlationID, Transport: CredentialCookie, Credential: credential}) authenticates through Get, freezes the original caller as the exact target and executes revocation through the existing durable owner. The configured native adapter authorizes current policy and rechecks current owners under the sole transaction. No fresh login is required. Supply a canonical host-generated command ID even for an absent credential; this is not permission or authentication. HTTP must reject mixed sources and enforce origin/CSRF before invoking cookie signout. HTTP transport and automatic cookie writing are not provided here.

Missing or primary-denied credentials return idempotent SignedOut without a second transition. Cookie transport returns ClearCookie and secure, empty-valued deletion attributes; bearer transport returns ClearBearer without touching a cookie. Other sessions and families are not selected. Outages, denial, malformed receipts, cancellation and unknown outcomes do not become successful logout. An exact receipt's CommitOutcome remains visible even alongside a later error; no outcome observation is CommitOutcomeInvalid, not inferred rollback. On ambiguity retain CommandID and Recovery, then use the owned native executor's scoped historical query under current result-access policy. Do not mint a replacement command or treat the recovery scope as authentication.

NewRevokeOneCommand(binding, record) prepares a single-session transition with the complete original target and a representable version successor. Its tenant, user and session ID must exactly match the command binding. RevokeOne() exposes a copy; formatting and serialization remain redacted. This command does not revoke a family, authenticate a caller or execute logout. The PostgreSQL contributor executes this variant atomically with audit and lifecycle effects. SignOutService targets the authenticating session; arbitrary target management and absent/expired target semantics remain pending.

service.PrepareRevokeOne(getResult, command) retains opaque caller admission from that exact configured SessionService, the original exclusive deadline, and the independent complete target command. A public reconstructed result, another configured reader, wrong owner/tenant/audience or a substituted same-ID record is rejected. Ordinary logout needs no fresh login. The owned executor must validate the request against its trusted service/time before reservation and final commit, recheck source and target active owners and current policy, and handle absent/revoked targets idempotently. Caller() and Command() are structural projections only; neither can replace original opaque custody. Preparation performs no transaction, mutation, validity refresh or logout.

policy, err := session.ResolveRememberPolicy(session.BrowserSession, session.LifetimeConfig{
    Default: session.PersistentSession,
    AbsoluteTTL: 7 * 24 * time.Hour,
    IdleTTL: 24 * time.Hour,
    RefreshAfter: 12 * time.Hour,
    FreshFor: 24 * time.Hour,
})

Check err, resolve once before issuing an authentication continuation, and carry the returned immutable policy unchanged through every factor. The executable example demonstrates lifetime/cookie composition without inventing authentication or persistence. Reference defaults belong to deployment.

Stateful opaque validation

NewSessionService(reader, ServiceConfig{...}) requires an owned SessionReader, explicit StorageStatefulOpaque, configured audience, trusted clock, 1ms..5s maximum duration, 1ms..5s clock uncertainty and 1..4 retained independent digest keys with distinct versions. Selection is copied; key retirement removes only that version's lookup support. Other storage profiles currently fail construction rather than silently emulate their revocation guarantees. Use the PostgreSQL adapter's owned primary reader; structural repository Get/Lookup must not be passed off as an authoritative reader or replaced by consumer-written glue.

NewCredential(CredentialCookie, parsedToken) or CredentialBearer selects exactly one transport. HTTP owns extraction, ambiguity rejection and browser origin/CSRF policy. Both paths authenticate the same opaque session, not an OAuth access token. Get(ctx, GetRequest{TenantID: tenant, Credential: credential}) sends bounded tenant/key-bound digests, never plaintext, to the reader. It checks the returned tenant, audience, digest, verified-authentication discriminator, complete unchanged authority vector and original absolute/idle lifetime. The reader must independently establish every applicable authority's active state, exact owner-derived scope, authenticating credential ID/version and native session/family status; a structurally reconstructed record does not establish any of those facts. No activity update, refresh, token issue or policy Allow runs.

Positive validity is bounded by the earliest source read plus at most 20 seconds, the original source deadline, the start of this operation and session expiry, with clock uncertainty deducted. Copies, cache promotion and delayed reads cannot restart freshness. GetResult.ValidUntil() returns that original exclusive deadline. Call ValidateAt(trustedCurrentTime) before reuse; the public Authenticated flag and historical Session alone cannot authorize. Public result reconstruction or field substitution cannot produce private admission custody. Refresh eligibility is advisory and does not renew activity or authority.

Inactive, stale, absent and mismatched credentials return an empty result with no error. Invalid input is ErrInvalidInput; incomplete authority, clock or dependency failures are redacted ErrUnavailable. Cancellation/deadline retain typed identity classifications. There is no stale fallback or automatic cache. Anonymous state is not elevated to authenticated identity. All protected actions still require the existing authorization service. Tests of the core reader seam do not prove real primary, cache or provider interoperability; those adapter and release checks remain pending.

  • LifetimeConfig requires explicit durations and an explicit default.
  • RememberPolicy.Bindings exports the explicit choice and all four resolved durations for trusted persistence. NewRememberPolicy reconstructs exactly: unresolved, out-of-bounds or clamp-requiring values fail. Store the complete projection, not just absolute expiry; never resolve a deployment default again when loading a session or continuing authentication. Neither API proves current authority or changes original authentication timestamps.
  • RememberPolicy.Evaluate takes authoritative original issuance, accepted-use and completed authentication timestamps. It returns earliest idle/absolute expiry, ordinary freshness and advisory refresh eligibility without a store.
  • NewCookiePolicy selects an immutable __Host- Lax/Strict profile.
  • CookiePolicy.Attributes creates an empty standard-library cookie. Persistent Max-Age uses whole remaining absolute-lifetime seconds capped at seven days; pass Lifetime.AbsoluteExpiresAt, not the idle deadline. Server validation independently enforces Lifetime.ExpiresAt. Browser sessions omit Max-Age and Expires. Only the transport populates the credential.
  • DeletionAttributes matches issuance scope but does not revoke authority.
  • NewToken generates 32..64 random bytes; ParseToken checks bounded, canonical unpadded base64url credentials. Neither operation issues a session.
  • Token.Reveal permits one explicit delivery across all value copies, including concurrent copies. A recipient already holding wire bytes can parse again: this is custody protection, not replay prevention. Never reveal uncommitted/unknown issuance, or mint replacements to recover an outcome.
  • NewDigestKey defensively copies 32..64 independently generated key bytes and a positive version. Token.Digest derives a tenant/version/domain-bound HMAC-SHA-256 lookup without exposing or storing raw credentials.
  • NewAuthoritySnapshot freezes all eight required authority bindings and explicit organization/factor/passkey applicability. Use Bindings only for trusted persistence/composition. CompareCurrent denies any scope, version, selection or presence change, including version increases and regressions.
  • NewSession reconstructs a complete bounded SessionSpec: exact IDs and record/family versions, original issuance/activity/authentication times, resolved remember policy, one full authority vector and versioned token lookup digest. Bindings returns an owned projection; Lifetime calculates recorded expiry/freshness only. Neither method verifies current activity.
  • AuthenticationMetadata explicitly separates completed-authentication metadata from anonymous state. Verified metadata retains the proof ID/version, exact authenticating credential ID/version and original proof projection. Anonymous state cannot assert credential proof, factor or passkey authority. The snapshot's aggregate credential dimension remains separate from the exact credential's version. The future issuer must validate live proof and the credential. It must also check each applicable factor or passkey and the exact derived authority scope.
  • NewIssueCommand freezes exact root CommandBinding plus one new version1 session, preserving family version. IssueOperation declares its v1 mapping. Issue exposes the native projection; ValidateIssueAt rechecks temporal preparation only. Authenticated issue requires session-issue proof purpose, exact tenant/subject/audience, unexpired proof and original freshness. The actual issuer must still verify expected private proof authority and current operation policy/vector before reserve/apply through the sole identity/postgres coordinator. This command cannot activate that adapter.

Adoption, security and tradeoffs

NewOTPSessionIssuer(executor, config) selects OTP without fabricating a credential proof; config.Authority must be nil. Select NewOTPSessionIssuerWithCSRF for independent synchronizer custody. Both profiles reuse the same duration, lookup-key, cookie, outcome and reveal-once rules.

The owned native adapter performs two-phase preparation before any reservation:

  1. Call PrepareOTP(binding, spec, originalMetadata) with zero lookup, creation version1 and original issuance/activity. It generates the bearer/digest and optional CSRF exactly once, but cannot execute yet.
  2. Map prepared.Session() completely into the native consuming intent, retaining original OTP provenance, remember choice, digest and CSRF state. Bind that final opaque code/pre-auth command with BindOTP before the kernel fingerprints or reserves it. Only one bind succeeds across preparation copies.
  3. Call Issue on the returned bound preparation once. The native executor uses IssueRequest.OTPCommand() to obtain original custody and the exact session. It must authenticate the original recipient and flow, recheck current authority and atomically consume OTP/pre-auth with session/audit/outbox.

The closed v1 identity.otp.signin descriptor is record-free: its feature receipt is0→0, while session creation is an independently bound atomic effect. User-bound scope must match the final user. Anonymous scope remains anonymous; it cannot be promoted or trusted to choose a user. The native effect resolves the eligible recipient from the original protected continuation. Actor and session owner remain distinct. No callback, second store or journal bridges this transaction.

Exact new committed execution alone permits delivery, still bounded by the original OTP issuance deadline. Errors, cancellation, ambiguity and replay never disclose bearer or CSRF custody. Request() returns false for OTP, and core Recover rejects it: submitted codes are not restart-recovery inputs. Code-free recovery of original outcome/session identity, native atomic Signin and authoritative reader composition remain pending. This core seam is not a usable login endpoint and does not authorize application-written workflows.

NewSessionIssuer freezes the configured proof authority, trusted clock, bounded execution duration, independent lookup key, token size and host-cookie policy. IssueExecutor is a storage-neutral boundary for the platform's owned durable execution service, not an invitation to supply an application domain store or another journal. The native PostgreSQL repository now implements session effects; the public owned execution-service composition is the next adapter batch. This core contract alone is not a usable login service.

Prepare accepts the original command binding, complete session projection, resolved RememberPolicy and final opaque authenticated proof. The projection's lookup must be zero. Preparation validates before generating one random token, then binds that exact token's tenant/key-version digest into the native command. PreparedIssuance exposes only its safe Request; it never exposes token bytes. Retain that original preparation rather than preparing again on a retry.

Issue makes one bounded attempt across all copies of a preparation. It accepts only an exact valid creation receipt and native record: original digest, family, authority vector, authentication, remember policy and times cannot be replaced. Only fresh non-replayed committed execution without dependency error or cancellation returns a Token and credential-free cookie attributes. The cookie uses the original absolute deadline, not a renewed TTL. Explicitly reveal once at the authorized response boundary; automatic serialization is forbidden.

Malformed output or a panic during durable execution is Unknown, not assumed rollback. A valid exact receipt preserves its known outcome even if subsequent delivery fails. Recover queries the original command through the primary executor and returns safe historical metadata only, never a replacement bearer or new session. Proof expiry does not erase historical outcome recovery; the adapter still enforces current result-access policy. Process-restart recovery requires retaining the original safe command/proof bindings through owned durable composition; this in-memory preparation is not a persistence system.

The original opaque proof is available through IssueRequest.AuthenticatedProof for the owned adapter's protected coordinator admission. It cannot be fabricated from public metadata and must still be checked against the configured private authority and current lifecycle under the sole transaction owner. Anonymous, bearer-continuation, session-container limits and rotations remain separate unfinished contracts; this cookie issuer does not approximate those profiles.

NewAuthenticatedIssueRequest binds a closed SessionCommand to the upstream opaque authentication.AuthenticatedProof, including its original proof and credential versions. Its Validate requires the expected configured AuthorityAuthenticator and trusted time; a request-selected or foreign authority cannot substitute provenance. Structural metadata is not a proof, and anonymous sessions require their separate unprivileged path. The immutable Command projection intentionally loses proof admission.

Validation admits final authentication only: it does not read current lifecycle authority, reserve or finalize proof use, issue a token, persist a session or commit required audit/outbox effects. The authoritative adapter must retain the original request and perform those checks and effects atomically under the sole coordinator. A positive result alone must not authenticate a stored session.

Zero policies are invalid; use the constructors. Redacted sentinel errors work with errors.Is. Values are immutable and concurrency-safe, and returned cookies are caller-owned copies. Policy methods perform no IO. Token generation uses standard-library secure OS entropy. No callback, goroutine or hidden clock exists. Root identity APIs remain unchanged.

Token/key formatting redacts; automatic JSON/text serialization fails closed. Explicitly revealed strings are secrets, no longer protected by wrappers. Custody neither erases memory nor prevents recipient retention. Keys must be CSPRNG-derived and independent of other cryptographic purposes. Never reuse versions for different key material. Retain old lookup keys until all required session/tombstone paths are retired. Key provisioning, encrypted durable recovery custody and rotation readiness remain unfinished composition requirements. Raw tokens must never become database lookup keys or cache projections; stable digests should not be logged because they correlate usage.

Authority keys are canonical dimension-qualified keys supplied by each durable lifecycle owner, not normalized user inputs. Their exact tenant and aggregate IDs must be derived from the session/proof; construction does not check a database, active status, membership, proof applicability or freshness. Never accept a credential solely because two caller-created snapshots match. Primary-authority adapters must compare the complete vector, check active state and expiry, and retain the original bounded read evidence. JSON encoding of the opaque wrapper fails rather than silently persisting an empty object. Extract the complete scalar projection for trusted storage; do not log its scope data.

Browser sessions cap server lifetime at 24 hours. Browser restoration may retain nonpersistent cookies; expiry and revocation remain necessary. Activity never renews authentication freshness or absolute lifetime. Expiry equality denies; invalid/future timelines fail closed without silent skew. Sensitive operations need a separate stricter freshness gate. Calculations are not authoritative shared-issuer validity evidence.

Completed authentication may precede session issuance. Preserve its original timestamp: replacing it with issuance would renew sensitive-operation freshness. Activity must still be at/after issuance, and future authentication denies. Proof expiry is historical record metadata, not the session's lifetime deadline; new issue preparation separately checks exclusive proof expiry. Stored proof projections are not authority, and arbitrary matching authority keys are not primary evidence. No default, normalization, callback or implicit upgrade is introduced by record reconstruction. These APIs preserve existing root contracts and consume pinned, unreleased identity/authentication revisions; published clean-consumer, typed catalog and complete release checks remain pending.

Cookie attributes fix Secure, HttpOnly, path /, no Domain and no partitioning. The reference profile's High priority attribute awaits HTTP serialization; standard-library http.Cookie does not represent it. This is not yet the complete reference transport profile. None/cross-site cookies belong to a separate flow-correlation owner. CSRF, origin checks, duplicate-cookie rejection and no-store headers remain HTTP requirements. A populated http.Cookie contains a secret: never log it.

FAQ and operations

Self-session device-label preparation

NewUpdateCommand(binding, caller.Session, label) freezes only a label and checked session-version successor. Use UpdateOperation() for the binding; the source record's version is the expected CAS. Empty clears the label; UTF-8 text is bounded to128 bytes and excludes control runes. Treat it as untrusted display text and escape it when rendered, never as device trust.

service.PrepareUpdate(caller, command) requires an unchanged authentic GetResult from that exact service and the exact authenticating session, not another same-user device. The opaque UpdateCommandRequest retains original transport and exclusive admission deadline. Copying or retrying does not renew authority. Label updates do not require fresh login, rotate credentials or extend activity, lifetime, remember choice or authentication freshness.

NewSessionUpdater(service, ownedExecutor, UpdateConfig) freezes the selected policy and whole-call budget. Prepare(caller, UpdatePreparation) checks the exact authenticating session ID and positive expected version before creating original-custody intent. Then Update(ctx, request) delegates current policy, primary owners and atomic label/CAS/audit/lifecycle effects to the owned executor. Successful results expose safe historical session/device metadata, never a credential or a renewed Get admission. Empty labels clear display metadata.

Retain the request and scoped result after ambiguity; Recover(ctx, request) authorizes current exact result access through the owner and observes the same command without executing or requiring expired source custody to become valid. Recovery returns outcome only, no session/device or apparent active-state claim. Known commitment survives cancellation, expiry and ancillary read failure; these errors withhold metadata rather than pretending rollback. Malformed receipts and post-entry panic are unknown; do not substitute a new command. Errors before owner entry return an invalid/unobserved outcome, not evidence that the original command is absent or rolled back. Retain its recovery scope.

Preparation is not authorization or a durable update. Core creates no store, journal or transaction; PostgreSQL writer/list integration, HTTP composition and release gates remain pending. Consumers must not implement a private store or assume a structural successor or recovered receipt authenticates a session.

Encrypted admission cache

NewEncryptedCacheCodec(service, envelopeService, config) adds explicit encrypted persistence to stateful opaque credential validation. Obtain an authentic GetResult through SessionService.Get, then Seal(ctx, result). Persist only the returned caller-owned ciphertext. On reuse call codec.Get(ctx, originalRequest, ciphertext); the original opaque credential is still required. Never log ciphertext, key references or decoded projections.

Use github.com/faustbrian/go-secret-envelope/v2 with a concurrent-safe bounded key provider. The codec does not invent encryption or accept client-selected keys. Configure issuer, environment and a positive deployment epoch explicitly; changing these invalidates all prior cached custody. Rotate the active key reference while retaining previous read keys for their bounded lifetime. Removing a read key requires primary validation rather than accepting that cache.

Every payload contains the complete original immutable session, remember policy, authority vector, transport and admission timestamps. Five-minute maximum age is a payload ceiling, not five minutes of positive authority. The original exclusive source deadline (at most 20 seconds, less read/clock/lifetime budget) wins, including after process restart or resealing. After expiry, an unavailable primary denies. Corrupt/foreign entries and unavailable key services use bounded primary validation; never stale fallback. Unknown or noncanonical projections never establish positive state. Callbacks must honor the session service's bounded context; no detached work is started to hide a provider that violates cancellation.

The binary envelope limit is explicit and checked before parsing or crypto. HTTP must additionally enforce the maximum encoded cookie size and Secure, HttpOnly, SameSite, CSRF/origin and no-store rules. This codec is not yet cookie transport, a Valkey adapter or a fully stateless deployment. Existing stateful constructor behavior is unchanged; the other storage-profile flags still deny until their real composition is implemented.

Continuing sessions over password replacement

ContinuePasswordSession is a pure mapping for the session adapter inside a password-change transaction. Supply the original command ID and exact current credential-authority and credential-reference predecessors. Both advance by one; user authority, all other authority dimensions, original authentication proof/time/version, session/family versions, remember choice, activity, lookup and synchronizer state stay unchanged. It does not prove that any row is active, that the command committed or that the caller is authorized.

EffectiveCredentialVersion is the separate successor linkage; the base authentication metadata continues to describe the original login. Trusted storage must retain CredentialContinuation together with Bindings and CSRFState and reconstruct through NewContinuedPasswordSession. Reconstructing only base bindings is lossy. Update/rotation retain continuation; encrypted cache schemas 5/6 preserve it without renewing the original validity deadline. Older cache schemas and ordinary session constructors remain unchanged.

The current continuation supports verified password provenance. Native PostgreSQL session-selection/revocation wiring and other authentication profiles remain pending; cache promotion is not a credential-continuation mechanism.

Atomic password-login preparation

NewPasswordSessionIssuer and its WithCSRF variant explicitly select native password signin. PreparePassword retains original prospective AuthenticationVerified password/single-factor metadata, the complete vector and resolved remember choice; it does not mint an authenticated proof. Map the returned tokenless PreparedIssuance.Session into the owned password-signin v1 record-free command and call BindPassword once. Only the configured native password executor can establish actual comparison, pre-auth/risk consumption, optional upgrade and session/audit/outbox effects in one coordinator transaction. Applications must not supply workflow glue.

IssueRequest.PasswordCommand lends original Secret/pre-auth custody to that executor. The caller still owns Secret.Destroy; commands/preparations are not safe recovery input. Request, proof accessors and issuer recovery reject this profile. Native recovery must use credential-free command correlation. Delivery requires the exact new known commit before original proof expiry; replay, cancellation, error, unknown or substituted results disclose no token or synchronizer. PostgreSQL atomic password signin remains in development.

Does refresh reset expiry? No: preserve original issuance. RefreshDue is advisory and authorizes neither a refresh nor a new token.

Can fractional expiry create a persistent cookie with Max-Age zero? No: less than one second denies. The 15-minute configuration minimum applies to issuance, not a lower bound that could extend remaining lifetime.

Why no defaults? All sign-in methods must share one selected policy instead of silently choosing different lifetimes. Resolve before MFA, not after it.

NewMFAMagicLinkSessionIssuer (or its WithCSRF variant) prepares only the explicit native TOTP-completion profile. PrepareMFAMagicLink freezes original primary provenance, factor/continuation metadata and the already resolved remember policy before generating token custody. BindMFA binds once to the unchanged opaque code/pre-auth command. IssueRequest.MFACommand lends that command to the native executor; it is never safe restart-recovery input.

The owned durable MFA executor must verify the original primary, child, browser, factor and current policy and atomically commit successful replay, continuation, child consumption, session and required audit/lifecycle. Applications must not implement this domain orchestration. The core profile alone is not usable MFA; the PostgreSQL completion service and reference wiring are still in development.

MFAAuthentication is separate historical metadata, not a new credential-issued proof or permission to issue a session. NewSessionWithMagicLinkMFA preserves the original primary authentication time for freshness. Factor completion cannot upgrade remember policy or replace primary provenance. Complete stores retain both projections and optional CSRF. Updates, rotations and encrypted cache retain all metadata; lost or changed factor projections fail closed. Cached admission keeps the earliest original authoritative deadline even across promotion/outage. Legacy single-factor metadata and cache schemas are unchanged.

Is logout implemented? Only deletion attributes and the closed native NewRevokeFamilyCommand(binding, expectedVersion) preparation contract. RevokeFamilyOperation targets one family, not user-wide logout; exact scope and a representable version successor are required. An opaque command is not authorization, a durable receipt or an HTTP endpoint. Durable logout workflows, unknown-commit recovery and lifecycle integration are pending. This batch has no core migrations or runtime services. Mutation, public API/release gates and full session-unit acceptance remain pending. See CHANGELOG.md.

Documentation

Overview

Package session owns shared session lifetime and transport policy. Durable session issuance and authentication are separate from these policy values.

Index

Examples

Constants

View Source
const PasskeyMFAPrimaryPurpose auth.Purpose = "identity.passkey.mfa-primary"

PasskeyMFAPrimaryPurpose identifies an original verified UV assertion that still requires the configured independent enrolled factor. It is not a final session-issue proof, and a passkey signin is not itself a TOTP/OTP enrollment.

View Source
const PasswordMFAPrimaryPurpose auth.Purpose = "identity.password.mfa-primary"

PasswordMFAPrimaryPurpose identifies historical, non-final password comparison evidence in a completed MFA session. It is not a completed signin proof and must never be accepted by a single-factor or AuthenticatedProof issuer.

Variables

View Source
var (
	// ErrInvalidAuthority rejects missing or malformed authority vectors without
	// disclosing identifiers. Construction is not proof of current authority.
	ErrInvalidAuthority = errors.New("session: invalid authority snapshot")
	// ErrAuthorityMismatch denies any changed scope, version or presence. It does
	// not disclose which dimension changed or treat a newer version as refresh.
	ErrAuthorityMismatch = errors.New("session: authority mismatch")
	// ErrAuthoritySerialization rejects implicit snapshot encoding, which could
	// omit the private vector or disclose internal scope data.
	ErrAuthoritySerialization = errors.New("session: authority serialization forbidden")
)
View Source
var (
	// ErrInvalidCSRF rejects malformed token, key or structural state without
	// disclosing credentials or correlated session identifiers.
	ErrInvalidCSRF = errors.New("session: invalid CSRF input")
	// ErrCSRFDenied uniformly rejects absent or mismatched synchronizer state.
	// It does not indicate whether the named session exists or is active.
	ErrCSRFDenied = errors.New("session: CSRF denied")
)
View Source
var (
	// ErrInvalidIssuer rejects incomplete trusted composition, without IO.
	ErrInvalidIssuer = errors.New("session: invalid issuer configuration")
	// ErrInvalidIssuance rejects zero, substituted or foreign preparation.
	ErrInvalidIssuance = errors.New("session: invalid issuance")
	// ErrIssuanceAlreadyAttempted requires scoped recovery of the same command;
	// it does not assert that the previous attempt committed or rolled back.
	ErrIssuanceAlreadyAttempted = errors.New("session: issuance already attempted")
	// ErrIssuanceAlreadyBound rejects a second bind of original OTP custody.
	ErrIssuanceAlreadyBound = errors.New("session: issuance already bound")
	// ErrIssuerUnavailable redacts a dependency failure before durable execution.
	ErrIssuerUnavailable = errors.New("session: issuer unavailable")
)
View Source
var (
	// ErrInvalidPolicy means configuration, choice or an uninitialized policy
	// cannot safely determine session behavior. It contains no request data.
	ErrInvalidPolicy = errors.New("session: invalid policy")
	// ErrInvalidTime means the supplied authoritative timeline is inconsistent.
	ErrInvalidTime = errors.New("session: invalid timeline")
	// ErrExpired means a session or transport lifetime has ended.
	ErrExpired = errors.New("session: expired")
)
View Source
var (
	// ErrInvalidPreAuthTransaction rejects malformed private flow state without
	// retaining origins, redirects, nonce, correlation or cookie input.
	ErrInvalidPreAuthTransaction = errors.New("session: invalid pre-auth transaction")
	// ErrPreAuthDenied is uniform for missing, different or expired binding.
	// It does not prove whether any flow exists or whether a cookie is valid.
	ErrPreAuthDenied = errors.New("session: pre-auth transaction denied")
)
View Source
var (
	// ErrInvalidInput rejects malformed session operation input without scope data.
	ErrInvalidInput = errors.New("session: invalid input")
	// ErrUnauthenticated denies absent, expired or inactive session authority.
	ErrUnauthenticated = errors.New("session: unauthenticated")
	// ErrUnavailable redacts unavailable or inconsistent authoritative reads.
	ErrUnavailable = errors.New("session: unavailable")
)
View Source
var (
	// ErrInvalidToken rejects invalid size, zero or noncanonical bearers without
	// disclosing input. Token construction alone proves no session authority.
	ErrInvalidToken = errors.New("session: invalid token")
	// ErrTokenAlreadyRevealed denies another delivery through any value copy.
	ErrTokenAlreadyRevealed = errors.New("session: token already revealed")
	// ErrInvalidDigest rejects invalid lookup scope or uninitialized digest keys.
	ErrInvalidDigest = errors.New("session: invalid digest input")
	// ErrSecretSerialization prevents automatic JSON/text disclosure of custody.
	ErrSecretSerialization = errors.New("session: secret serialization forbidden")
)
View Source
var ErrBrowserDeviceDenied = errors.New("session: browser device denied")

ErrBrowserDeviceDenied uniformly rejects invalid, expired or mismatched browser-device custody. It reveals no token, key or previously seen browser.

View Source
var ErrFreshnessRequired = errors.New("session: fresh authentication required")

ErrFreshnessRequired denies a sensitive session action after the original completed authentication's configured freshness interval. Reading activity, copying admission or rotating a session cannot renew that interval.

View Source
var ErrInvalidIssueRequest = errors.New("session: invalid issue request")

ErrInvalidIssueRequest rejects a zero, anonymous or proof-mismatched request without exposing account, credential or proof identifiers.

View Source
var ErrInvalidSession = errors.New("session: invalid record")

ErrInvalidSession rejects malformed records without disclosing scope data.

View Source
var ErrInvalidSessionCommand = errors.New("session: invalid command")

ErrInvalidSessionCommand rejects zero, unsupported or misbound commands.

View Source
var ErrRotationDeferred = errors.New("session: rotation deferred")

ErrRotationDeferred means the original policy's refresh interval has not elapsed. No token, command reservation or accepted-activity update is made.

Functions

func IssueOperation

func IssueOperation() identity.FeatureOperation

IssueOperation returns the exact v1 native issue mapping. This declaration conveys no registered contributor or runtime readiness; core never imports PostgreSQL, opens a transaction, accepts a callback or creates a journal.

func OrganizationSelectionOperation

func OrganizationSelectionOperation() identity.FeatureOperation

OrganizationSelectionOperation retains the logical organization's active-set ownership without importing it into the session module. Its native participant invokes a session-owned effect; this is not another session-owned operation or permission to dispatch a second feature in the protected transaction.

func PreAuthIssueOperation

func PreAuthIssueOperation() identity.FeatureOperation

PreAuthIssueOperation identifies the closed original-flow creation contract. It grants no authority and is returned by value for adapter composition.

func RevokeAllOperation

func RevokeAllOperation() identity.FeatureOperation

RevokeAllOperation identifies fresh self-service set revocation with explicit source disposition, not administrative revocation or global account blocking.

func RevokeFamilyOperation

func RevokeFamilyOperation() identity.FeatureOperation

RevokeFamilyOperation identifies the native storage transition, not an HTTP endpoint or the user-wide RevokeAll operation. Its security action is identity.session.revoke; its lifecycle event is session_family.revoked.v1.

func RevokeOneOperation

func RevokeOneOperation() identity.FeatureOperation

RevokeOneOperation identifies the single-session native transition. It is distinct from family revocation and carries no execution or HTTP authority.

func RevokeOtherOperation

func RevokeOtherOperation() identity.FeatureOperation

RevokeOtherOperation identifies fresh self-service revocation excluding the authenticating source. This is distinct from a family or single-session command.

func RotateOperation

func RotateOperation() identity.FeatureOperation

RotateOperation identifies the exact refresh/rotation command. Ordinary token rotation is distinct from family revocation and does not renew authentication.

func UpdateOperation

func UpdateOperation() identity.FeatureOperation

UpdateOperation identifies the native session metadata mutation. The sole durable coordinator must atomically retain label, CAS, audit/lifecycle and recovery receipt; core neither imports an adapter nor opens a transaction.

Types

type ActiveOrganizationSelection

type ActiveOrganizationSelection struct {
	SessionID      string
	TenantID       identity.TenantID
	SessionVersion SessionVersion
	OrganizationID string
	Authority      AuthorityBinding
}

ActiveOrganizationSelection is trusted, non-secret selection intent for one exact session and tenant. SessionVersion is the expected source version. An empty OrganizationID clears selection and requires zero Authority. A present ID is bounded opaque ASCII and requires the organization's canonical scope and positive authority version. The organization owner must derive and validate that binding, active membership and lifecycle; these fields alone prove none of them. Selection is never permission or authentication.

type AnonymousGetResult

type AnonymousGetResult struct {
	Recognized bool
	Session    Session
	// contains filtered or unexported fields
}

AnonymousGetResult identifies a recognized original anonymous session only. It grants no permanent-account authority, verified assurance, credential or permission to select an upgrade target. Zero is unrecognized; public fields alone cannot forge private admission. Copies retain the original exclusive validity deadline. Never log, serialize or concurrently mutate this value.

func (AnonymousGetResult) Format

func (AnonymousGetResult) Format(s fmt.State, _ rune)

Format redacts correlated anonymous-session and validity state.

func (AnonymousGetResult) MarshalJSON

func (AnonymousGetResult) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit admission export.

func (AnonymousGetResult) MarshalText

func (AnonymousGetResult) MarshalText() ([]byte, error)

MarshalText rejects implicit admission text/map-key export.

func (AnonymousGetResult) ValidUntil

func (r AnonymousGetResult) ValidUntil() time.Time

ValidUntil returns the original conservative primary-read deadline, or zero. Copying or reading this metadata neither renews nor proves admission.

func (AnonymousGetResult) ValidateAt

func (r AnonymousGetResult) ValidateAt(now time.Time) error

ValidateAt checks retained custody, unchanged public metadata and exclusive original source/session validity. Trusted current time is required. It makes no primary read and grants neither verified assurance nor mutation authority.

type AnonymousSessionService

type AnonymousSessionService struct {
	// contains filtered or unexported fields
}

AnonymousSessionService validates explicitly unprivileged anonymous session credentials. It uses the same bounded primary reader, exact digest/vector and original-validity checks as other session profiles, but exposes no GetResult or authenticated-user admission. A recognized anonymous subject is not a verified user or credential proof. The owned anonymous adapter must establish current anonymous lifecycle, expiry and primary directory authority on every observation. Dependencies are borrowed, concurrency-safe and context-bounded.

func NewAnonymousSessionService

func NewAnonymousSessionService(reader SessionReader, config ServiceConfig) (*AnonymousSessionService, error)

NewAnonymousSessionService freezes the explicit anonymous-only read profile without IO, resource ownership or issuance. Config retains ServiceConfig's limits and immutable key selection. A verified session, organization authority or second-factor/passkey authority can never enter this profile. Existing general and mixed session services continue to reject anonymous credentials.

func (*AnonymousSessionService) Configured

func (s *AnonymousSessionService) Configured() bool

Configured reports immutable constructor validity without IO or clock calls. Nil/zero owners are false. This does not establish dependency health, guest possession, current authority or a validity lease; Get must still admit each credential. Concurrent inspection never changes the service or its evidence.

func (*AnonymousSessionService) Format

func (*AnonymousSessionService) Format(s fmt.State, _ rune)

Format redacts configured dependencies and correlated session state.

func (*AnonymousSessionService) Get

Get recognizes one exact anonymous credential under the current complete authority vector and original lifetime. Absent, expired, revoked, wrong-kind and organization-scoped records return zero,nil. Invalid input, cancellation, unavailable authority and panics retain the shared redacted classifications. No token, verified GetResult, activity update or cached fallback is exposed.

func (*AnonymousSessionService) MarshalJSON

func (*AnonymousSessionService) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit runtime configuration export.

type AuthenticationKind

type AuthenticationKind uint8

AuthenticationKind distinguishes completed authentication metadata from explicitly unprivileged anonymous state. Zero and unknown values are invalid.

const (
	// AuthenticationVerified selects completed-authentication metadata only;
	// the discriminator itself proves no authentication.
	AuthenticationVerified AuthenticationKind = iota + 1
	// AuthenticationAnonymous selects explicitly unprivileged anonymous state.
	AuthenticationAnonymous
	// AuthenticationOTP selects explicit historical OTP provenance, never a
	// fabricated persistent credential or an authority-issued proof.
	AuthenticationOTP
	// AuthenticationMagicLink selects original email-grant possession metadata,
	// never a fabricated persistent credential or opaque authentication proof.
	AuthenticationMagicLink
)

type AuthenticationMetadata

type AuthenticationMetadata struct {
	Kind              AuthenticationKind
	Proof             authentication.Proof
	ProofVersion      uint64
	CredentialID      string
	CredentialVersion uint64
	AnonymousAt       time.Time
}

AuthenticationMetadata preserves original authentication and credential linkage for trusted storage. Proof is authentication's caller-owned projection, NOT an authority-issued proof. Kind cannot certify successful authentication. Verified records require ProofVersion and a credential ID/version. Anonymous records require AnonymousAt and every verified field zero; they confer no authenticated assurance. The session issuer must independently validate final authority-issued proof, every applicable factor/passkey and live authority. CredentialVersion is the exact authenticating credential's version; it is not a substitute for the snapshot's aggregate credential invalidation dimension.

type AuthorityBinding

type AuthorityBinding struct {
	ScopeKey string
	Version  uint64
}

AuthorityBinding is a caller-owned non-secret projection of one positive lifecycle version. ScopeKey is the canonical, dimension-qualified key produced by that dimension's owner, 1..256 visible ASCII bytes. It is not a user-input normalizer. The owner must derive it from the exact tenant and aggregate IDs; version equality on the wrong key is never sufficient. Zero is invalid.

type AuthoritySnapshot

type AuthoritySnapshot struct {
	// contains filtered or unexported fields
}

AuthoritySnapshot owns an immutable complete vector. Zero is invalid. Copies and comparisons are concurrency-safe; construction validates structure only, not the existence, activity, provenance or freshness of any authority. Primary session adapters must derive current keys from the exact session/proof and require all applicable authorities active under the lifecycle read policy. This value alone must never authorize issuance or credential acceptance.

func NewAuthoritySnapshot

func NewAuthoritySnapshot(s AuthoritySnapshotSpec) (AuthoritySnapshot, error)

NewAuthoritySnapshot validates all dimensions and freezes their scope bytes. Dimension-qualified keys must be distinct even when aggregate IDs coincide. Unknown dimensions cannot be injected through an extensible map. Optional absence must be explicit, and organization selection is not membership proof. No callback, IO, clock, counter update or authority refresh occurs.

func (AuthoritySnapshot) Bindings

Bindings returns a caller-owned scalar projection for trusted persistence and composition. Mutating it cannot change retained state. Do not log the scope keys: they may identify people or correlate activity. A projection is not an authority proof and must not replace the exact original snapshot in a cache.

func (AuthoritySnapshot) CompareCurrent

func (s AuthoritySnapshot) CompareCurrent(current AuthoritySnapshot) error

CompareCurrent requires exact equality of every scope key, positive version, selected organization and optional applicability. Any newer, regressed, cross-scope or missing value denies; refresh must not replace the stored vector to resurrect a stale session. The adapter owns primary reads, active-state denial, clock/read budgets and expiry. Neither success nor copying creates a new validity lease or proves that current was actually read from authority.

Example
package main

import (
	"errors"
	"fmt"

	"github.com/faustbrian/go-identity/session"
)

func main() {
	// Synthetic structural input, not an authenticated or primary-read result.
	spec := session.AuthoritySnapshotSpec{
		Global:        session.AuthorityBinding{ScopeKey: "global:deployment", Version: 1},
		Tenant:        session.AuthorityBinding{ScopeKey: "tenant:tenant-a", Version: 1},
		User:          session.AuthorityBinding{ScopeKey: "user:tenant-a:user-a", Version: 1},
		Identifier:    session.AuthorityBinding{ScopeKey: "identifier:tenant-a:user-a", Version: 1},
		Credential:    session.AuthorityBinding{ScopeKey: "credential:tenant-a:user-a", Version: 1},
		SessionFamily: session.AuthorityBinding{ScopeKey: "family:tenant-a:family-a", Version: 1},
		Session:       session.AuthorityBinding{ScopeKey: "session:tenant-a:session-a", Version: 1},
		Authorization: session.AuthorityBinding{ScopeKey: "authorization:tenant-a:user-a", Version: 1},
	}
	stored, err := session.NewAuthoritySnapshot(spec)
	if err != nil {
		panic(err)
	}
	spec.Credential.Version++
	current, err := session.NewAuthoritySnapshot(spec)
	if err != nil {
		panic(err)
	}
	// Never replace stored with current to resurrect a stale session.
	err = stored.CompareCurrent(current)
	fmt.Println(errors.Is(err, session.ErrAuthorityMismatch))
}
Output:
true

func (AuthoritySnapshot) Format

func (s AuthoritySnapshot) Format(state fmt.State, _ rune)

Format redacts snapshot scope data in ordinary value formatting. Pointer custody also prevents inline scope disclosure through unexported compositions.

func (AuthoritySnapshot) MarshalJSON

func (s AuthoritySnapshot) MarshalJSON() ([]byte, error)

MarshalJSON rejects automatic encoding. Trusted persistence must explicitly extract Bindings and retain all dimensions, never serialize an empty wrapper.

type AuthoritySnapshotSpec

type AuthoritySnapshotSpec struct {
	Global, Tenant, User, Identifier, Credential, SessionFamily, Session, Authorization AuthorityBinding
	ActiveOrganizationID                                                                string
	Organization, Factor, Passkey                                                       OptionalAuthorityBinding
}

AuthoritySnapshotSpec is the complete caller-owned structural input for one session vector. Required dimensions are never omitted. Organization presence must match ActiveOrganizationID exactly; Factor and Passkey must preserve the authenticating/step-up proof's applicability. Their absence is not permission to remove an existing authentication binding. Do not mutate this input while constructing. It contains no bearer, authentication proof or validity lease.

type BrowserDevice

type BrowserDevice struct {
	// contains filtered or unexported fields
}

BrowserDevice is immutable non-authoritative correlation and original expiry. Zero is invalid. Only Issue retains a cookie header; Resolve cannot renew or redeliver it. Explicit projections are sensitive. No account authority or durable identity is established by any field or successful resolution.

func (BrowserDevice) CookieHeader

func (d BrowserDevice) CookieHeader() string

CookieHeader exposes sensitive Set-Cookie only for the original Issue result. It is reusable delivery metadata, not a one-time or authentication credential.

func (BrowserDevice) DeviceID

func (d BrowserDevice) DeviceID() string

DeviceID exposes the scoped non-authoritative abuse correlation, never a credential. It must not become an authentication, user or MFA device ID.

func (BrowserDevice) ExpiresAt

func (d BrowserDevice) ExpiresAt() time.Time

ExpiresAt returns the original cookie expiry; it cannot be refreshed by Resolve.

func (BrowserDevice) Format

func (BrowserDevice) Format(s fmt.State, _ rune)

Format redacts token and stable device correlation.

func (BrowserDevice) LogValue

func (BrowserDevice) LogValue() slog.Value

LogValue redacts token and stable device correlation.

func (BrowserDevice) MarshalJSON

func (BrowserDevice) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit correlation export.

func (BrowserDevice) MarshalText

func (BrowserDevice) MarshalText() ([]byte, error)

MarshalText denies implicit correlation export.

type BrowserDeviceCodec

type BrowserDeviceCodec struct {
	// contains filtered or unexported fields
}

BrowserDeviceCodec owns no store, callbacks or goroutines. It issues and verifies a bounded server-random browser correlation cookie, not a session, authentication proof, hardware fingerprint or MFA trusted-device credential. Clearing/copying cookies can evade/share this signal; IP and identifier abuse controls must remain independent. Zero denies; methods are concurrency-safe.

func NewBrowserDeviceCodec

func NewBrowserDeviceCodec(c BrowserDeviceConfig) (*BrowserDeviceCodec, error)

NewBrowserDeviceCodec validates explicit policy and freezes key selection without entropy or IO. It does not select an HTTP route or issue a cookie.

Example
package main

import (
	"context"
	"crypto/rand"
	"fmt"
	"net/http"
	"time"

	"github.com/faustbrian/go-identity/session"
)

func main() {
	// Real deployments retain and distribute dedicated keys securely; do not
	// generate a new key on each request or process restart.
	var material [32]byte
	rand.Read(material[:])
	key, err := session.NewBrowserDeviceKey(1, material[:])
	if err != nil {
		panic(err)
	}
	cookie, err := session.NewCookiePolicy(session.CookieConfig{Name: "__Host-identity_device", SameSite: http.SameSiteLaxMode})
	if err != nil {
		panic(err)
	}
	codec, err := session.NewBrowserDeviceCodec(session.BrowserDeviceConfig{Namespace: "example-environment", Keys: []session.BrowserDeviceKey{key}, ActiveVersion: 1, Lifetime: 24 * time.Hour, Cookie: cookie})
	if err != nil {
		panic(err)
	}
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	now := time.Date(2026, 10, 9, 12, 0, 0, 0, time.UTC)
	issued, err := codec.Issue(ctx, now, "tenant-a", "https://tenant.example")
	if err != nil {
		panic(err)
	}
	// The HTTP owner delivers this only via a secure no-store Set-Cookie,
	// then strictly acquires one original cookie on the next request.
	header, err := http.ParseSetCookie(issued.CookieHeader())
	if err != nil {
		panic(err)
	}
	observed, err := codec.Resolve(ctx, now.Add(time.Minute), "tenant-a", "https://tenant.example", header.Value)
	if err != nil {
		panic(err)
	}
	fmt.Println(observed.DeviceID() == issued.DeviceID(), observed.ExpiresAt() == issued.ExpiresAt(), observed.CookieHeader() == "")
}
Output:
true true true

func (*BrowserDeviceCodec) Format

func (*BrowserDeviceCodec) Format(s fmt.State, _ rune)

Format redacts retained keys.

func (*BrowserDeviceCodec) Issue

func (c *BrowserDeviceCodec) Issue(ctx context.Context, now time.Time, tenant identity.TenantID, origin string) (BrowserDevice, error)

Issue creates one fresh random correlation cookie after trusted transport admission. now is trusted time; tenant/origin must be the exact HTTPS mapping resolved by the current request, not JSON or arbitrary headers. Context must be nonnil and live. The only entropy source is standard-library crypto/rand; no resource ownership transfers. Time is rounded down to whole UTC seconds, never extending Lifetime. Call once per deliberate browser initialization, reuse an existing valid cookie across flows, and never mint on ambiguity.

func (*BrowserDeviceCodec) LogValue

func (*BrowserDeviceCodec) LogValue() slog.Value

LogValue redacts retained keys.

func (*BrowserDeviceCodec) MarshalJSON

func (*BrowserDeviceCodec) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit owner export.

func (*BrowserDeviceCodec) MarshalText

func (*BrowserDeviceCodec) MarshalText() ([]byte, error)

MarshalText denies implicit owner export.

func (*BrowserDeviceCodec) Resolve

func (c *BrowserDeviceCodec) Resolve(ctx context.Context, now time.Time, tenant identity.TenantID, origin, token string) (BrowserDevice, error)

Resolve verifies exactly one canonical 114-byte unpadded base64url value. The transport must first reject duplicate/alternative cookie channels and validate HTTPS host/origin. Missing, malformed, unknown-key, cross-scope, future-issued, expired or policy-incompatible cookies uniformly deny. It never issues credentials, extends expiry, touches a store or authenticates.

type BrowserDeviceConfig

type BrowserDeviceConfig struct {
	Namespace     string
	Keys          []BrowserDeviceKey
	ActiveVersion uint32
	Lifetime      time.Duration
	Cookie        CookiePolicy
}

BrowserDeviceConfig is copied at construction. Namespace is the stable deployment/environment separation (1..128 visible ASCII bytes). Keys contains 1..16 distinct dedicated versions; ActiveVersion must be the greatest version. Lifetime is whole seconds in 1 hour..7 days. Cookie must use the existing __Host-identity_device Lax/Strict host-only profile. Policy/key removal may deliberately invalidate old cookies; it must never renew their original TTL.

func (BrowserDeviceConfig) Format

func (BrowserDeviceConfig) Format(s fmt.State, _ rune)

Format redacts configuration and keys.

func (BrowserDeviceConfig) LogValue

func (BrowserDeviceConfig) LogValue() slog.Value

LogValue redacts configuration and keys.

func (BrowserDeviceConfig) MarshalJSON

func (BrowserDeviceConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit configuration export.

func (BrowserDeviceConfig) MarshalText

func (BrowserDeviceConfig) MarshalText() ([]byte, error)

MarshalText denies implicit configuration export.

type BrowserDeviceKey

type BrowserDeviceKey struct {
	// contains filtered or unexported fields
}

BrowserDeviceKey is immutable dedicated HMAC material. It cannot substitute for session lookup, CSRF or MFA keys. Deploy independent CSPRNG material, never reuse a version for different bytes, and retain old versions until all issued cookies expire. Zero is invalid; copies are safe for concurrent use.

func NewBrowserDeviceKey

func NewBrowserDeviceKey(version uint32, material []byte) (BrowserDeviceKey, error)

NewBrowserDeviceKey copies 32..64 bytes under a positive rotation version. All-zero material denies. Source erasure and key distribution are caller-owned.

func (BrowserDeviceKey) Format

func (BrowserDeviceKey) Format(s fmt.State, _ rune)

Format redacts key material.

func (BrowserDeviceKey) LogValue

func (BrowserDeviceKey) LogValue() slog.Value

LogValue redacts key material.

func (BrowserDeviceKey) MarshalJSON

func (BrowserDeviceKey) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit key export.

func (BrowserDeviceKey) MarshalText

func (BrowserDeviceKey) MarshalText() ([]byte, error)

MarshalText denies implicit key export.

type CSRFBinding

type CSRFBinding struct {
	TenantID       identity.TenantID
	SessionID      string
	SessionVersion uint64
}

CSRFBinding identifies exactly one tenant/session/version. Canonical IDs are 1..128 visible ASCII bytes; version is positive. It proves no authentication, primary activity, authority freshness or transaction reservation.

type CSRFKey

type CSRFKey struct {
	// contains filtered or unexported fields
}

CSRFKey owns an immutable dedicated 32..64-byte key and positive rotation version. It cannot be passed as a session lookup key. Deployment must supply independent CSPRNG material, never reuse versions for different material, issue with the newest key and retire retained keys after configured overlap. Zero is invalid; copies are safe for concurrent reads, with no resources.

func NewCSRFKey

func NewCSRFKey(version uint32, material []byte) (CSRFKey, error)

NewCSRFKey copies dedicated key material; it does not generate keys, register versions or authorize overlap. Source-buffer erasure remains caller-owned.

func (CSRFKey) Format

func (CSRFKey) Format(f fmt.State, _ rune)

Format redacts all key formatting.

func (CSRFKey) MarshalJSON

func (CSRFKey) MarshalJSON() ([]byte, error)

MarshalJSON rejects key serialization.

func (CSRFKey) MarshalText

func (CSRFKey) MarshalText() ([]byte, error)

MarshalText rejects text and map-key key serialization.

func (CSRFKey) Version

func (k CSRFKey) Version() uint32

Version returns the immutable non-secret rotation identifier; zero returns zero. Select only the exact state-named eligible key from trusted deployment policy, never try alternate keys or treat a matching version as authority.

type CSRFRevokeOneExecutor

type CSRFRevokeOneExecutor interface {
	ExecuteRevokeOneWithCSRF(context.Context, RevokeOneRequest) (identity.CommandResult, error)
}

CSRFRevokeOneExecutor is the explicit owned transactional CSRF profile, not the legacy direct executor. It must authenticate original request custody, select its own eligible named key, acquire existing source/target mutation fences and check the token against exact active primary state on the original protected transaction before mutation. Errors abort that transaction; raw tokens/keys never enter durable intent, audit or recovery. Implementations lacking this profile cannot be selected for CookieSignOutService. Context, outcome/recovery and concurrency semantics follow RevokeOneExecutor.

type CSRFState

type CSRFState struct {
	// contains filtered or unexported fields
}

CSRFState freezes structural synchronizer state. Zero denies every check. Copies are safe for concurrent reads. Reconstruction or Check is NOT primary authentication, current authority or atomic lifecycle invalidation. The owned durable adapter must read/fence active exact state with protected work, not accept a caller projection or previously cached session as current state.

func NewCSRFState

func NewCSRFState(s CSRFStateSpec) (CSRFState, error)

NewCSRFState reconstructs complete trusted digest-only storage without IO. Absence, partial state and zero digest are rejected, never a legacy bypass.

func (CSRFState) Bindings

func (s CSRFState) Bindings() (CSRFStateSpec, error)

Bindings returns an owned private storage projection, not a validity lease.

func (CSRFState) Check

func (s CSRFState) Check(b CSRFBinding, t CSRFToken, k CSRFKey) error

Check compares exact structural binding and named-key digest in constant time. It never falls back to a different version, consumes a token or renews any validity. Call only with active primary state under the durable owner's mutation fence; standalone success must never authorize protected work.

func (CSRFState) Format

func (CSRFState) Format(f fmt.State, _ rune)

Format redacts scope and digest correlators.

func (CSRFState) MarshalJSON

func (CSRFState) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit state export; use trusted Bindings instead.

func (CSRFState) MarshalText

func (CSRFState) MarshalText() ([]byte, error)

MarshalText rejects implicit text or map-key export.

type CSRFStateSpec

type CSRFStateSpec struct {
	Binding    CSRFBinding
	KeyVersion uint32
	Digest     [32]byte
}

CSRFStateSpec is a private digest-only storage projection. Persist all fields atomically with the exact session; no raw token is stored. It must not be exposed as a credential or logged, because it correlates session activity.

type CSRFToken

type CSRFToken struct {
	// contains filtered or unexported fields
}

CSRFToken owns exactly 32 random bytes encoded as canonical unpadded base64url. Copies share one atomic Reveal permission, independent of session bearer custody. It is not a signed token, authentication or replay authority. Zero is invalid. Digest and formatting do not consume delivery permission.

func NewCSRFToken

func NewCSRFToken() (CSRFToken, error)

NewCSRFToken allocates a fresh 32-byte CSPRNG token, not a durable session or command. Only the session issuance owner may deliver it after the exact original transaction commits; unknown, aborted and historical outcomes must reveal nothing. Retrying must not manufacture replacement token state.

func ParseCSRFToken

func ParseCSRFToken(wire string) (CSRFToken, error)

ParseCSRFToken copies exactly one 32-byte canonical transport credential. It performs no session lookup or origin/channel validation. Parsing already possessed bytes creates new reveal custody; it is not one-time-use control.

func (CSRFToken) Digest

func (t CSRFToken) Digest(k CSRFKey, b CSRFBinding) (CSRFState, error)

Digest computes HMAC-SHA-256 with dedicated named key over exact framing: "identity-csrf-v1\x00", uint16 big-endian tenant-byte length, tenant bytes, uint16 big-endian session-byte length, session bytes, uint64 big-endian session version, and the 32 decoded random token bytes. Length framing makes variable identifiers unambiguous; key version is persisted beside the digest. It creates structural state only, without consuming or revealing the token.

func (CSRFToken) Format

func (CSRFToken) Format(f fmt.State, _ rune)

Format prevents automatic credential disclosure for every formatting verb.

func (CSRFToken) MarshalJSON

func (CSRFToken) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit credential export.

func (CSRFToken) MarshalText

func (CSRFToken) MarshalText() ([]byte, error)

MarshalText rejects implicit text and map-key credential export.

func (CSRFToken) Reveal

func (t CSRFToken) Reveal() (string, error)

Reveal returns the original credential once across concurrent copies. The trusted issuance owner, not this value, enforces commitment before delivery.

type CacheCookie

type CacheCookie struct {
	// contains filtered or unexported fields
}

CacheCookie owns one immutable encrypted Set-Cookie value. Copies are safe concurrently. It contains correlated ciphertext, never the original bearer; it is not sufficient to authenticate alone. Zero is invalid. Formatting and implicit JSON/text export redact or deny. HeaderValue is the explicit HTTP delivery boundary; never log its returned value.

func (CacheCookie) Format

func (CacheCookie) Format(s fmt.State, _ rune)

Format redacts correlated ciphertext and deployment cookie names.

func (CacheCookie) HeaderValue

func (c CacheCookie) HeaderValue() (string, error)

HeaderValue explicitly exports the owned immutable Set-Cookie value for HTTP delivery. Repeated export does not renew expiry or authoritative freshness.

func (CacheCookie) MarshalJSON

func (CacheCookie) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit response or diagnostic export.

func (CacheCookie) MarshalText

func (CacheCookie) MarshalText() ([]byte, error)

MarshalText denies implicit map-key and text export.

type CachedAdmission

type CachedAdmission struct {
	// contains filtered or unexported fields
}

CachedAdmission owns immutable same-process positive Get custody. Zero is a miss. Copies preserve the original exclusive deadline and complete Session; there is no second authority vector or caller-constructible positive state. It stores no raw bearer and owns no cache, goroutine, pool or invalidation journal. It is not a serializable cookie/Valkey snapshot or a stateless token. Those profiles require their separate authenticated persistence composition.

func (CachedAdmission) Format

func (CachedAdmission) Format(s fmt.State, _ rune)

Format redacts correlation and original authentication custody.

func (CachedAdmission) MarshalJSON

func (CachedAdmission) MarshalJSON() ([]byte, error)

MarshalJSON denies turning process custody into an unauthenticated cache blob.

func (CachedAdmission) MarshalText

func (CachedAdmission) MarshalText() ([]byte, error)

MarshalText denies implicit cache/map-key export.

type CookieCache

type CookieCache struct {
	// contains filtered or unexported fields
}

CookieCache composes encrypted positive admission and secure browser framing. Concurrent calls are safe with concurrent-safe codec dependencies. It owns no HTTP handler, store, background work or authority. HTTP must select only its configured companion values, reject mixed original credential sources and enforce origin/CSRF/no-store rules; this type cannot validate those requests. No optional cache error authorizes stale state. Removal is not revocation.

func NewCookieCache

func NewCookieCache(codec *EncryptedCacheCodec, config CookieCacheConfig) (*CookieCache, error)

NewCookieCache validates explicit browser cache policy without IO. The credential cookie cannot be overwritten or widened by cache configuration. This encrypted profile is required because the full projection is private.

func (*CookieCache) Deletion

func (c *CookieCache) Deletion() (CacheCookie, error)

Deletion returns the exact companion scope with negative Max-Age, past Expires and High priority. It clears only cache; HTTP must separately clear the original credential and commit the required durable revocation.

func (*CookieCache) Format

func (*CookieCache) Format(s fmt.State, _ rune)

Format redacts companion policy and deployment configuration.

func (*CookieCache) Get

func (c *CookieCache) Get(ctx context.Context, request GetRequest, values []string) (GetResult, error)

Get accepts only an explicit original cookie credential and zero or one cache values selected by HTTP. Duplicate companion cookies deny before any IO. Absent, oversized or noncanonical base64 cache values invoke bounded primary validation. A valid envelope still requires the exact tenant/digest/transport and original deadline; an outage after expiry never falls back to stale state. Caller must not mutate values during the call. No cookies are silently issued or renewed: call Put separately on the authenticated result if cache policy permits it. Bearer authentication must not read companion cookies.

func (*CookieCache) MarshalJSON

func (*CookieCache) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit deployment configuration export.

func (*CookieCache) Put

func (c *CookieCache) Put(ctx context.Context, result GetResult) (out CacheCookie, err error)

Put frames only genuine same-service cookie admission. It preserves the resolved remember choice: browser cookies omit Expires/Max-Age; persistent cache cookies are bounded by at most five minutes and original session expiry. Encryption latency is subtracted, not added to the cookie deadline. Less than one remaining second denies rather than becoming an accidental session cookie. Exact total size is checked; no truncation, chunking or cookie-attribute downgrade occurs. Errors return no header. Cookie persistence never extends the payload's original exclusive authoritative validity deadline.

type CookieCacheConfig

type CookieCacheConfig struct {
	Credential, Cache  CookiePolicy
	MaximumCookieBytes int
}

CookieCacheConfig selects an opt-in encrypted companion cookie. Credential and Cache are distinct validated host-only policies with identical SameSite. MaximumCookieBytes is 512..3800 and bounds the entire emitted Set-Cookie value, including name, base64 payload, all attributes and fixed Priority=High. The codec's payload maximum age must be 1s..5m. Zero is disabled/unconfigured, not an implicit profile. Cache cookies never replace the original credential.

type CookieConfig

type CookieConfig struct {
	Name     string
	SameSite http.SameSite
}

CookieConfig selects the secure host-only session-cookie profile. Name must start with __Host-, contain a suffix and be at most 128 ASCII token bytes. SameSite is explicitly Lax or Strict. Cross-site correlation cookies are distinct from session cookies and are not supported by this profile.

type CookiePolicy

type CookiePolicy struct {
	// contains filtered or unexported fields
}

CookiePolicy is an immutable validated host-cookie policy. Zero is invalid. It owns attributes only, not session issuance, token custody, CSRF validation or writing HTTP responses. Copies may be used concurrently.

func NewCookiePolicy

func NewCookiePolicy(c CookieConfig) (CookiePolicy, error)

NewCookiePolicy rejects unsafe or implicit transport policy. The secure, HttpOnly, host-only, root-path and unpartitioned attributes cannot be weakened.

func (CookiePolicy) Attributes

func (c CookiePolicy) Attributes(p RememberPolicy, now, absoluteExpiresAt time.Time) (http.Cookie, error)

Attributes returns a fresh, credential-free standard-library cookie. The transport must assign only its issued opaque token to Value and must not log that populated cookie. absoluteExpiresAt must be the original authoritative absolute expiry, never inferred from client input. Persistent cookies use whole remaining seconds capped at seven days, never a refreshed TTL; browser cookies omit both Max-Age and Expires. Fractional lifetimes round down, and less than one second is denied rather than becoming an accidental session cookie. The 15-minute configuration minimum applies to issuance, not a lower bound that could extend the remaining session lifetime. Cookie attributes alone convey no authentication or revocation guarantee.

func (CookiePolicy) DeletionAttributes

func (c CookiePolicy) DeletionAttributes() (http.Cookie, error)

DeletionAttributes returns an empty host cookie with the exact same scope and security attributes, negative Max-Age and a past expiry. HTTP logout must revoke server authority independently; deleting a cookie is not revocation.

type CookieSignOutService

type CookieSignOutService struct {
	// contains filtered or unexported fields
}

CookieSignOutService selects strict cookie-CSRF self-signout without changing the existing trusted direct SignOutService API or public struct shapes. It borrows that service and copies 1..4 eligible dedicated CSRF keys. Dependencies must outlive calls; immutable instances may be shared concurrently. No stores, goroutines, transactions, workflow journals or alternate crypto are created.

func NewCookieSignOutService

func NewCookieSignOutService(base *SignOutService, keys []CSRFKey) (*CookieSignOutService, error)

NewCookieSignOutService validates explicit cookie composition without IO. Keys have distinct positive versions; their current/retained eligibility is trusted deployment policy. Caller slice changes cannot alter selection. The base executor MUST implement same-transaction CSRF admission for requests carrying CSRFToken; a legacy executor is not a supported browser backend. Use the owned native factory rather than application-written transaction glue.

func (*CookieSignOutService) Configured

func (s *CookieSignOutService) Configured() bool

Configured reports immutable strict cookie composition without IO, key disclosure or authentication. Nil/zero owners are false. It is not current key eligibility, health or CSRF admission; SignOut retains those checks. Safe concurrently with independent calls.

func (CookieSignOutService) Format

func (CookieSignOutService) Format(s fmt.State, _ rune)

Format prevents traversal of borrowed services and key-selection metadata.

func (CookieSignOutService) MarshalJSON

func (CookieSignOutService) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit runtime composition export.

func (CookieSignOutService) MarshalText

func (CookieSignOutService) MarshalText() ([]byte, error)

MarshalText rejects text and map-key export of runtime composition.

func (*CookieSignOutService) SignOut

func (s *CookieSignOutService) SignOut(ctx context.Context, request SignOutRequest, token CSRFToken) (SignOutResult, error)

SignOut accepts cookie transport only. HTTP must already enforce exact trusted origin, strict cookie parsing and a single canonical CSRF input channel. An active caller requires its exact session-bound token and eligible named key; successful parsing/prechecking alone never authorizes protected work. The executor receives opaque token custody and must recheck under original primary fences before mutation. Raw token/key material is never persisted here. Absent/inactive credentials retain idempotent success without an impossible active-state token check. All other outcomes and commit-dependent cookie clearing follow the original SignOutService; no fresh login is required.

type Credential

type Credential struct {
	// contains filtered or unexported fields
}

Credential privately retains one canonical token and an exact transport. Zero is invalid. Copies share Token custody; no credential bytes are exposed. Parsing transport and rejecting mixed cookie/header sources belongs to HTTP.

func NewCredential

func NewCredential(kind CredentialKind, token Token) (Credential, error)

NewCredential selects one transport for an already parsed bounded Token. This grants no session authority and does not reveal or consume the token.

func (Credential) Digest

func (c Credential) Digest(key DigestKey, tenant string) (TokenDigest, error)

Digest derives the existing tenant-bound lookup commitment without exposing or consuming the original bearer. It permits owned adapters to prove original possession for exact metadata-only recovery after that operation revokes its own session. A digest grants no active session, current authority or permission to reexecute: those require the appropriate primary reader and native checks. Zero/unknown transport, absent token/key and invalid tenant fail closed. Copies retain Token's concurrent-safe custody; this method performs no IO or entropy.

func (Credential) Format

func (Credential) Format(s fmt.State, _ rune)

Format redacts credential custody for every diagnostic verb.

func (Credential) Kind

func (c Credential) Kind() CredentialKind

Kind returns the retained transport; zero returns zero.

func (Credential) MarshalJSON

func (Credential) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit credential encoding.

func (Credential) MarshalText

func (Credential) MarshalText() ([]byte, error)

MarshalText rejects implicit credential text/map-key encoding.

type CredentialContinuationSpec

type CredentialContinuationSpec struct {
	CommandID                                       identity.CommandID
	BeforeAuthorityVersion, BeforeCredentialVersion uint64
}

CredentialContinuationSpec is the original password-change command and its independent credential-authority and credential-reference predecessors. Scope comes from the complete session. This projection is not authorization, a proof, a freshness lease or evidence that the command committed. A native adapter must compare all current owners and persist the transition in the same password-change transaction. Never derive it from a cache refresh.

type CredentialKind

type CredentialKind uint8

CredentialKind identifies transport, never authentication strength or grants.

const (
	// CredentialCookie requires browser transport to enforce its CSRF policy.
	CredentialCookie CredentialKind = iota + 1
	// CredentialBearer selects explicit header transport without cookie fallback.
	CredentialBearer
)

type Device

type Device struct {
	SessionID             string
	Label                 string
	LastSeenAt, ExpiresAt time.Time
	Current, Inactive     bool
}

Device is safe, authorized display metadata only. Label is untrusted text, LastSeenAt is original accepted activity, and Inactive includes revoked session/family or exact recorded expiry. Current refers to this credential's exact session, never a client-selected active index. No digest, proof, family ID, authority snapshot or bearer is exposed; metadata confers no device trust.

func (Device) Format

func (Device) Format(s fmt.State, _ rune)

Format redacts identifying and user-controlled display metadata.

func (Device) MarshalJSON

func (Device) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit identifying display metadata export.

type DigestKey

type DigestKey struct {
	// contains filtered or unexported fields
}

DigestKey owns a defensive immutable copy of 32..64 key bytes and a positive rotation version. Zero is invalid; fmt/JSON/text operations never disclose it. Use independent CSPRNG-derived session-lookup material, not capability signing, password, API-key or envelope keys. This is in-memory key custody, not durable encrypted storage or a key provider. The deployment owns rotation/retirement.

func NewDigestKey

func NewDigestKey(version uint32, material []byte) (DigestKey, error)

NewDigestKey copies key material after bounded validation. The caller owns source-buffer erasure and cryptographic entropy. Versions must never be reused for different material; retain old keys while their session/tombstone lookup paths remain required. Key generation and provider readiness are composition.

func (DigestKey) Format

func (k DigestKey) Format(s fmt.State, _ rune)

Format redacts all key formatting.

func (DigestKey) MarshalJSON

func (k DigestKey) MarshalJSON() ([]byte, error)

MarshalJSON denies key serialization.

func (DigestKey) MarshalText

func (k DigestKey) MarshalText() ([]byte, error)

MarshalText denies text and map-key key serialization.

type EncryptedCacheCodec

type EncryptedCacheCodec struct {
	// contains filtered or unexported fields
}

EncryptedCacheCodec encrypts the complete owned session projection and its original admission deadline. It is safe for concurrent calls with concurrent safe dependencies. It owns no store, resource, goroutine or independent authority vector. Envelope keys are trusted deployment credentials, not user callbacks or client-selected keys. Provider calls share the session service's bounded context and must honor cancellation. Retain wrapping keys only as long as their cache entries remain eligible; removal fails closed or uses primary. This is a stateful cache codec, not fully stateless authentication or HTTP.

func NewEncryptedCacheCodec

func NewEncryptedCacheCodec(service *SessionService, crypto *envelope.Service, config EncryptedCacheConfig) (*EncryptedCacheCodec, error)

NewEncryptedCacheCodec freezes explicit encrypted-cache configuration without IO. Only the owning SessionService may mint payloads. Another process with the same trusted profile/keys may restore them, without restarting validity.

func (*EncryptedCacheCodec) Format

func (*EncryptedCacheCodec) Format(s fmt.State, _ rune)

Format prevents key/profile identifiers from leaking through diagnostics.

func (*EncryptedCacheCodec) Get

func (c *EncryptedCacheCodec) Get(ctx context.Context, request GetRequest, blob []byte) (out GetResult, err error)

Get authenticates a bounded encrypted projection then reuses only exact tenant/digest/transport custody. Corrupt, foreign, stale or absent entries use bounded primary Get. A provider outage may use primary, never stale evidence. Every restored result retains the complete original authority/lifetime and exclusive source deadline, including after restarts, copies and key rotation. Matching ciphertext alone does not authenticate without the original bearer.

func (*EncryptedCacheCodec) MarshalJSON

func (*EncryptedCacheCodec) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit profile/key-reference export.

func (*EncryptedCacheCodec) Seal

func (c *EncryptedCacheCodec) Seal(ctx context.Context, result GetResult) (out []byte, err error)

Seal returns caller-owned authenticated ciphertext, never a raw bearer or plaintext projection. Only genuine unchanged same-service admission can seal. Cached/promoted results retain their earlier deadline. Crypto work is bounded; expired, canceled or backward-clock work returns no payload. Errors redact all provider diagnostics. Explicit bytes are for trusted cache persistence; never log them. Transport remains dependent on the original opaque credential.

type EncryptedCacheConfig

type EncryptedCacheConfig struct {
	Issuer, Environment string
	DeploymentEpoch     uint64
	KeyReference        string
	MaximumAge          time.Duration
	MaximumBytes        int
}

EncryptedCacheConfig binds a deployment's encrypted positive-cache profile. Issuer and Environment are canonical visible ASCII identifiers (1..256 and 1..128 bytes); DeploymentEpoch is positive and changes on compromise or cache reset. KeyReference names the active wrapping key; retained read keys belong to the envelope provider. MaximumAge is 1ms..5m, never renewed authority. MaximumBytes is the binary envelope limit, 256..32768, checked before parsing. Browser composition must separately bound base64/cookie framing and attributes.

type Enrichment

type Enrichment struct{ Values []string }

Enrichment is an ordered display-only projection, never authentication or authorization evidence. On success Values corresponds exactly to FieldNames; empty individual strings are valid. Nil Values means deliberate omission, not a schema-shaped successful projection. Returned slices are caller-owned. Treat values as untrusted display text; transport owners must escape them.

func (Enrichment) Format

func (Enrichment) Format(s fmt.State, _ rune)

Format redacts display content and field identities from diagnostics.

func (Enrichment) MarshalJSON

func (Enrichment) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit display-data export; transport selects fields explicitly.

type EnrichmentConfig

type EnrichmentConfig struct {
	Schema          EnrichmentSchema
	MaximumDuration time.Duration
	FailurePolicy   EnrichmentFailurePolicy
}

EnrichmentConfig freezes the schema and failure policy. MaximumDuration is 1ms..5s; earlier caller deadlines win. Zero configuration is invalid.

func (EnrichmentConfig) Format

func (EnrichmentConfig) Format(s fmt.State, _ rune)

Format redacts borrowed callback configuration from diagnostics.

func (EnrichmentConfig) MarshalJSON

func (EnrichmentConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit callback configuration export.

type EnrichmentFailurePolicy

type EnrichmentFailurePolicy uint8

EnrichmentFailurePolicy explicitly controls display callback failure. It never controls authentication admission or suppresses context cancellation.

const (
	// EnrichmentFail returns a redacted error and no projection on failure.
	EnrichmentFail EnrichmentFailurePolicy = iota + 1
	// EnrichmentOmit omits display data on callback errors or panics only.
	// Malformed successful output still fails closed rather than being cached.
	EnrichmentOmit
)

type EnrichmentSchema

type EnrichmentSchema struct {
	Version    uint64
	FieldNames []string
	MaxBytes   uint32
}

EnrichmentSchema declares an ordered display-only output schema. Version is positive, FieldNames has 1..32 unique visible ASCII names of at most 64 bytes, and MaxBytes is 1..16384 total UTF-8 value bytes. The complete immutable Session (all bindings, authority and lifetime policy) is always the source. No output field overrides a source field, principal or authorization fact. Configuration freezes a copy; callback and consumer projections are owned.

func (EnrichmentSchema) Format

func (EnrichmentSchema) Format(s fmt.State, _ rune)

Format redacts schema identities from diagnostics.

func (EnrichmentSchema) MarshalJSON

func (EnrichmentSchema) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit schema export.

type EnrichmentService

type EnrichmentService struct {
	// contains filtered or unexported fields
}

EnrichmentService performs uncached display projection on every invocation. Complete source changes therefore always rerun enrichment; it owns no cache, store lock, goroutine, transaction or authority vector. Calls are safe to run concurrently if the borrowed callback is. Keep it alive until calls finish. A context budget cannot interrupt a callback that violates its cancellation contract; no detached goroutine is created to conceal that violation.

func NewEnrichmentService

func NewEnrichmentService(provider SessionEnricher, config EnrichmentConfig) (*EnrichmentService, error)

NewEnrichmentService validates and freezes composition without invoking the callback or IO. It neither authenticates sessions nor configures transport.

func (*EnrichmentService) Enrich

func (s *EnrichmentService) Enrich(ctx context.Context, source Session) (out Enrichment, err error)

Enrich returns schema-ordered, bounded, defensively copied display values. A zero session is invalid; a valid structural session is not necessarily active. Call this after independent authentication/authorization, and never merge its output into principal facts. No authority freshness is renewed. Errors and panics are redacted. Cancellation/deadline always return their typed classification, never optional fallback or partial output.

func (EnrichmentService) Format

func (EnrichmentService) Format(s fmt.State, _ rune)

Format redacts runtime composition from diagnostics.

func (EnrichmentService) MarshalJSON

func (EnrichmentService) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit runtime export.

type GetRequest

type GetRequest struct {
	TenantID   identity.TenantID
	Credential Credential
}

GetRequest selects one exact tenant and credential, never a user override. Zero is invalid. The caller must not mutate the request during a call.

func (GetRequest) Format

func (GetRequest) Format(s fmt.State, _ rune)

Format redacts credential-bearing input.

func (GetRequest) MarshalJSON

func (GetRequest) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit request export.

type GetResult

type GetResult struct {
	Authenticated     bool
	Session           Session
	NeedsRefresh      bool
	RefreshEligibleAt time.Time
	// contains filtered or unexported fields
}

GetResult is historical session/refresh metadata plus private admission custody. Zero represents unauthenticated. Only Get establishes positive custody; constructing/mutating public fields cannot authenticate. Copies preserve the original exclusive validity and never renew it. ValidateAt with trusted time before each reuse; a stored Session or Authenticated flag alone cannot authorize. Never mutate a result concurrently with its consumer.

func (GetResult) Format

func (GetResult) Format(s fmt.State, _ rune)

Format redacts historical session and positive custody metadata.

func (GetResult) MarshalJSON

func (GetResult) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit result export and loss of private admission.

func (GetResult) ValidUntil

func (r GetResult) ValidUntil() time.Time

ValidUntil returns the original conservative exclusive acceptance deadline. Zero returns zero. This time alone cannot prove provenance or current access.

func (GetResult) ValidateAt

func (r GetResult) ValidateAt(now time.Time) error

ValidateAt verifies original result custody, unchanged metadata and lifetime. now must be trusted current time, never client-selected or a cached timestamp. Backward time, exact deadline and public-field substitution deny. This is not a fresh primary read or an authorization decision and cannot renew a lease.

type IssueCommandSpec

type IssueCommandSpec struct {
	Binding identity.CommandBinding
	Session Session
}

IssueCommandSpec is the native storage-neutral projection of new issuance. Binding targets exactly Session and declares policy/schema/actor separately from the effective user. It is not authority, proof consumption or a commit. Adapters must validate the complete native schema and every effect before mapping to identity's command fingerprint protocol. No transaction is exposed.

type IssueExecution

type IssueExecution struct {
	Receipt  identity.CommandResult
	Session  Session
	Replayed bool
}

IssueExecution carries a durable receipt and exact native historical record. Session is present only on committed outcomes. Replayed forbids delivery; it cannot change a receipt's outcome. Public reconstruction is structural, not authority: only the trusted durable executor establishes these facts. Do not mutate a returned value concurrently with its consumer.

type IssueExecutor

type IssueExecutor interface {
	ExecuteIssue(context.Context, IssueRequest) (IssueExecution, error)
	RecoverIssue(context.Context, IssueRequest) (IssueExecution, error)
}

IssueExecutor is the storage-neutral boundary implemented by the owned durable adapter, not an application workflow or another command journal. ExecuteIssue must validate the selected profile's original opaque proof or OTP or password/pre-auth custody, current lifecycle and policy, consume required one-time proofs and persist the exact session plus required audit/outbox effects under the sole authoritative command owner. Replayed is true for any historical terminal observation. RecoverIssue must authorize exact scope and read that same command on the primary; it must never execute, refresh inputs or infer absence from cancellation. Both methods must be concurrent-safe, honor ctx and never return bearer material.

type IssueRequest

type IssueRequest struct {
	// contains filtered or unexported fields
}

IssueRequest retains one closed proof, consuming-OTP, password, magic-link, passkey or MFA variant. Zero is invalid; copies are immutable and concurrency safe. Proof requests require Validate against the configured authority. OTP requests are created only by BindOTP; signin requests by BindPassword, signup requests by BindSignup and magic-link requests by BindMagicLink, assertion requests by BindPasskey, passkey-signup requests by BindPasskeySignup and MFA requests by BindMFA. Native owners must establish successful authentication and all effects atomically, not treat prospective metadata as a checked proof. This value cannot reserve, consume, commit or reveal a credential on its own. OTP password and magic-link custody is ephemeral; never persist it or use it for recovery.

func NewAuthenticatedIssueRequest

func NewAuthenticatedIssueRequest(command SessionCommand, proof authentication.AuthenticatedProof) (IssueRequest, error)

NewAuthenticatedIssueRequest preserves a command's complete authority vector, resolved remember policy and original proof/credential versions while binding its metadata exactly to the opaque authenticated proof. Anonymous and partial authentication cannot use this constructor. No caller-created projection can replace the proof. A proof from another valid composition may be structurally bound, but Validate rejects it against the issuer's expected authority. No IO, token generation or consumption occurs. Invalid input returns zero.

func (IssueRequest) AnonymousCommand

func (r IssueRequest) AnonymousCommand() (identity.Command, Session, bool)

AnonymousCommand lends the original prospective command and tokenless session to the owned native executor. Other profiles and zero return false. It is not evidence of risk admission, persisted creation or verified authentication. Recovery must use the native credential-free original-command correlation, not execute this request again or construct a replacement bearer.

func (IssueRequest) AnonymousUpgradeCommand

func (r IssueRequest) AnonymousUpgradeCommand() (identity.Command, Session, uint64, time.Time, bool)

AnonymousUpgradeCommand lends original command, target session, guest version and unchanged admission deadline only to the trusted native executor. The result is prospective custody, not authentication, consumed proof or committed session authority. Zero/other profiles deny. Never persist the secret-bearing command or use it as a recovery query.

func (IssueRequest) AuthenticatedProof

func (r IssueRequest) AuthenticatedProof() (authentication.AuthenticatedProof, bool)

AuthenticatedProof returns the original upstream opaque proof for the owned durable adapter's protected command admission. Zero, OTP and password deny. It exposes no bearer or fabrication capability; the configured authority must still validate its private provenance and exact scope inside the authoritative transaction. Bindings or Command projections cannot substitute this value.

func (IssueRequest) Command

func (r IssueRequest) Command() (SessionCommand, bool)

Command returns the proof-route projection; zero, OTP and password deny. This projection intentionally loses proof admission; it cannot replace the original request or grant execution authority to an adapter.

func (IssueRequest) EmailVerificationCommand

func (r IssueRequest) EmailVerificationCommand() (identity.Command, Session, bool)

EmailVerificationCommand returns the exact native post-verification command and tokenless prospective session, without authenticating either. Only the explicitly selected native executor may use it; all other profiles deny.

func (IssueRequest) Format

func (IssueRequest) Format(s fmt.State, _ rune)

Format redacts command scope and authentication linkage for every fmt verb.

func (IssueRequest) MFACommand

func (r IssueRequest) MFACommand() (identity.Command, Session, bool)

MFACommand lends the exact native completion command and tokenless session to its configured executor. It carries opaque submitted code/browser custody; never serialize it or use it for restart recovery. Recovery must be code-free and cannot regenerate, renew or disclose a credential.

func (IssueRequest) MagicLinkCommand

func (r IssueRequest) MagicLinkCommand() (identity.Command, Session, bool)

MagicLinkCommand lends the exact prospective native command and tokenless session to the configured consuming executor. Zero and all other profiles deny. Never serialize it or use it for restart recovery; native recovery is proof-free and cannot issue or renew credentials.

func (IssueRequest) MarshalJSON

func (IssueRequest) MarshalJSON() ([]byte, error)

MarshalJSON prevents accidental request/proof serialization.

func (IssueRequest) MarshalText

func (IssueRequest) MarshalText() ([]byte, error)

MarshalText prevents text and map-key disclosure.

func (IssueRequest) OTPCommand

func (r IssueRequest) OTPCommand() (identity.Command, Session, bool)

OTPCommand lends original opaque code/pre-auth custody and the exact prepared record to the configured native consuming executor. Zero and proof requests return false. The projection is not a checked proof; native owners must verify exact original intent and current state atomically. Never persist/serialize the opaque command or use it for recovery; restart recovery must be code-free.

func (IssueRequest) PasskeyCommand

func (r IssueRequest) PasskeyCommand() (identity.Command, Session, bool)

PasskeyCommand lends the original command and prospective tokenless session only to the configured durable executor. It is not a VerifiedAssertion or authority-issued proof. The native owner must retain and verify genuine WebAuthn custody itself; metadata must never replace cryptographic admission.

func (IssueRequest) PasskeySignupCommand

func (r IssueRequest) PasskeySignupCommand() (identity.Command, Session, bool)

PasskeySignupCommand lends only the original native anonymous signup command and prospective tokenless session to its configured durable executor. It is neither an assertion nor authenticated proof, current authority or signup permission. The native owner must establish all real cryptographic and transactional admission before returning a new committed result.

func (IssueRequest) PasswordCommand

func (r IssueRequest) PasswordCommand() (identity.Command, Session, bool)

PasswordCommand lends original opaque password/pre-auth custody and exact prospective session to the configured native executor. Zero/proof/OTP variants return false. This is not successful comparison or current authority. Native owners must prove those in the consuming transaction; never persist or recover with this secret-bearing command. The caller retains Secret destruction.

func (IssueRequest) PasswordSignupCommand

func (r IssueRequest) PasswordSignupCommand() (identity.Command, Session, bool)

PasswordSignupCommand lends original paired verifier/pre-auth custody and the prospective session only to the configured native executor. Zero, signin, OTP and proof variants deny. Success proves no authentication or policy completion. Do not persist, log or use this secret-bearing command for outcome recovery.

func (IssueRequest) Validate

func (r IssueRequest) Validate(authority *authentication.AuthorityAuthenticator, now time.Time) error

Validate checks private proof provenance against the expected configured authority, exact scope and exclusive expiry, then original session freshness and lifetime at trusted now. It performs no IO or authority refresh. The authority must come from trusted composition, not a request-selected instance. Success is final-authentication admission only, not current account/credential validity, one-time use or session authentication. Those checks and required audit/outbox effects belong to the protected authoritative transaction.

type IssueResult

type IssueResult struct {
	CommandID     identity.CommandID
	CommitOutcome identity.CommitOutcome
	Session       Session
	Token         Token
	Cookie        http.Cookie
	Replayed      bool
	RetryAfter    time.Duration
	// DeliveryValidUntil is the original exclusive native delivery deadline for
	// anonymous upgrade. Transports must preserve it through final commitment,
	// not derive another lease from the returned session or their own clock.
	// Zero means no deadline was projected: other issuance profiles, replay,
	// recovery or failure. It is not current authentication or reusable proof.
	DeliveryValidUntil time.Time
}

IssueResult preserves the authoritative outcome even when delivery is withheld. Session is historical metadata, never current authentication. Token and credential-free Cookie are returned only on exact new committed execution with no error, cancellation or expired original lifetime. Copies share Token's reveal-once permission. Replays and recovery return no token. The explicit password-bearer issuer returns a zero Cookie. Cookie.Value is always empty; explicitly populate it only at authorized HTTP delivery, never in logs or general serialization.

func (IssueResult) Format

func (IssueResult) Format(f fmt.State, _ rune)

Format redacts all scope and transport metadata.

func (IssueResult) MarshalJSON

func (IssueResult) MarshalJSON() ([]byte, error)

MarshalJSON rejects accidental serialization of issuance custody.

func (IssueResult) MarshalText

func (IssueResult) MarshalText() ([]byte, error)

MarshalText rejects accidental text or map-key serialization.

type IssuerClock

type IssuerClock interface{ Now() time.Time }

IssuerClock supplies trusted time. It must be concurrent-safe and nonblocking. Neither client timestamps nor a returned receipt may select this clock.

type IssuerConfig

type IssuerConfig struct {
	Authority       *authentication.AuthorityAuthenticator
	Clock           IssuerClock
	MaximumDuration time.Duration
	LookupKey       DigestKey
	TokenSize       int
	Cookie          CookiePolicy
}

IssuerConfig freezes cookie issuance composition. Authority is the configured private proof authority for NewSessionIssuer; it must be nil for the explicit OTP, password and passkey profiles. MaximumDuration is 1ms..30s; dependencies must honor it. TokenSize is 32..64 bytes. LookupKey is independent session-lookup custody. Cookie is the validated host-only transport profile, except the explicit NewPasswordBearerSessionIssuer profile requires it to be zero. OTP pre-auth flows may retain anonymous command scope while the native effect resolves the final user. Anonymous sessions and bearer continuations require separate admission.

type Lifetime

type Lifetime struct {
	AbsoluteExpiresAt time.Time
	ExpiresAt         time.Time
	RefreshDue        bool
	Fresh             bool
}

Lifetime is a read-only calculation, not authoritative validity evidence. Revocation and all authority versions must still be checked by the session owner. RefreshDue is advisory: it does not authorize refresh or token rotation.

type LifetimeConfig

type LifetimeConfig struct {
	Default      RememberChoice
	AbsoluteTTL  time.Duration
	IdleTTL      time.Duration
	RefreshAfter time.Duration
	FreshFor     time.Duration
}

LifetimeConfig is explicit deployment policy, not a package default. All fields are required. AbsoluteTTL is 15 minutes..30 days, IdleTTL is 5 minutes..AbsoluteTTL, RefreshAfter is 1 minute..IdleTTL and FreshFor is 15 minutes..24 hours. Sensitive-operation freshness is a separate stricter gate.

type ListConfig

type ListConfig struct {
	Authorization   authorization.Service
	PolicyRevision  authorization.Revision
	MaximumDuration time.Duration
}

ListConfig requires the existing authorization engine, a positive selected policy revision and a 1ms..5s whole-call budget. Earlier caller and original credential-validity deadlines win. Policy callbacks must honor ctx and be bounded, concurrency-safe and nonblocking outside their documented IO.

func (ListConfig) Format

func (ListConfig) Format(s fmt.State, _ rune)

Format redacts policy and runtime configuration.

func (ListConfig) MarshalJSON

func (ListConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit correlated metadata/credential export. HTTP owns explicit authorized field selection, not serialization of internal results.

type ListRequest

type ListRequest struct {
	TenantID        identity.TenantID
	Credential      Credential
	CorrelationID   string
	Cursor          string
	Limit           uint16
	IncludeInactive bool
}

ListRequest selects a credential and bounded raw scan, never a user override. Limit is 1..100 with no implicit default; Cursor is empty or the canonical <=216-byte opaque marker returned by this service. It is a non-authoritative keyset locator, not a secret, snapshot or authorization grant. Changing tenant, authenticated user, audience or IncludeInactive invalidates it. CorrelationID is 1..128 canonical visible ASCII bytes, not policy authority. Zero is invalid.

func (ListRequest) Format

func (ListRequest) Format(s fmt.State, _ rune)

Format redacts credential, tenant and pagination scope.

func (ListRequest) MarshalJSON

func (ListRequest) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit credential and correlated-scope export.

func (ListRequest) MarshalText

func (ListRequest) MarshalText() ([]byte, error)

MarshalText denies implicit credential/cursor map-key disclosure.

type ListResult

type ListResult struct {
	Sessions   []Device
	NextCursor string
}

ListResult is an owned <=Limit display projection. Filtering expired/revoked rows can produce an empty page with a NextCursor; work stays bounded to Limit raw records. Keyset traversal preserves bytewise order, not an MVCC snapshot: concurrent inserts before the marker are not revisited. NextCursor is based on the last scanned row, including filtered rows; it is never access authority.

func (ListResult) Format

func (ListResult) Format(s fmt.State, _ rune)

Format redacts identifying display projections and cursor linkage.

func (ListResult) MarshalJSON

func (ListResult) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit display projection and cursor export.

func (ListResult) MarshalText

func (ListResult) MarshalText() ([]byte, error)

MarshalText denies implicit display projection/cursor export.

type ListService

type ListService struct {
	// contains filtered or unexported fields
}

ListService owns authenticated, currently authorized self-listing. Borrowed reader/policy dependencies must outlive calls. It owns no store, transaction, goroutine, authority vector, replay engine or cursor-signing service. Calls are concurrency-safe when dependencies satisfy their contracts.

func NewListService

func NewListService(sessions *SessionService, pages SessionPageReader, config ListConfig) (*ListService, error)

NewListService freezes explicit composition without IO. Use the owned primary SessionService and page reader; neither structural rows nor a caller-selected user/current-session ID can replace credential authentication.

func (ListService) Format

func (ListService) Format(s fmt.State, _ rune)

Format redacts borrowed runtime dependencies and configuration.

func (*ListService) List

func (s *ListService) List(ctx context.Context, request ListRequest) (out ListResult, err error)

List authenticates on the primary, authorizes current self-list policy, scans one bounded page and rechecks unchanged original caller validity before any disclosure. No fresh login is required. Unsupported, absent or revoked callers deny; outage, cancellation, hostile collaborator or corrupt/foreign/unordered pages return no partial metadata. Reader data must not renew caller freshness.

type MFAAuthentication

type MFAAuthentication struct {
	// contains filtered or unexported fields
}

MFAAuthentication freezes historical completion metadata. Zero is invalid; copies are immutable and concurrency-safe. Native issuance must independently authenticate the original primary, child and factor and commit their effects.

func NewMFAAuthentication

func NewMFAAuthentication(p MFAAuthenticationSpec) (MFAAuthentication, error)

NewMFAAuthentication validates and copies bounded metadata without IO, clock reads or proof creation. All IDs are canonical random128 identities, versions positive and residual continuation lifetime at most five minutes. Rebuilding historical state does not recheck current authority or renew authentication.

func (MFAAuthentication) Bindings

Bindings returns owned historical metadata, not proof or issuance permission.

func (MFAAuthentication) Format

func (MFAAuthentication) Format(s fmt.State, _ rune)

Format redacts correlated factor and continuation metadata for every verb.

func (MFAAuthentication) MarshalJSON

func (MFAAuthentication) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit metadata export; trusted stores use Bindings.

func (MFAAuthentication) MarshalText

func (MFAAuthentication) MarshalText() ([]byte, error)

MarshalText rejects implicit export and map-key disclosure.

type MFAAuthenticationSpec

type MFAAuthenticationSpec struct {
	CommandID, PrimaryCommandID, ContinuationID identity.CommandID
	ContinuationScopeDigest                     [32]byte
	Method, FactorID                            string
	RecoverySetID                               identity.CommandID `json:",omitempty"`
	RecoverySetVersion                          uint64             `json:",omitempty"`
	EnrollmentVersion, FactorAuthorityVersion   uint64
	ContinuationVersion                         uint64
	Remember                                    RememberPolicySpec
	VerifiedAt, ValidUntil                      time.Time
}

MFAAuthenticationSpec is historical, secret-free second-factor provenance. CommandID names completion, PrimaryCommandID the original primary admission, and ContinuationID/ScopeDigest the unchanged one-use child. ContinuationVersion is the version before completion. OTP, TOTP and recovery-code profiles are distinct; recovery requires its immutable set identity/epoch in addition to the original factor enrollment. Set regeneration cannot silently substitute that provenance. it never treats a passkey sign-in as an enrolled factor. Remember is the exact original resolved policy, not a new default. VerifiedAt is factor time, never the session's primary-authentication freshness origin. ValidUntil is the original continuation expiry, not a positive-authority lease or session expiry. Filling these fields does not certify authentication or committed effects.

type MagicLinkAuthentication

type MagicLinkAuthentication struct {
	// contains filtered or unexported fields
}

MagicLinkAuthentication freezes one original grant's historical projection. Copies are immutable and concurrency-safe; zero is invalid. Native issuance must establish cryptographic provenance, current authority and atomic one-use.

func NewMagicLinkAuthentication

func NewMagicLinkAuthentication(p MagicLinkAuthenticationSpec) (MagicLinkAuthentication, error)

NewMagicLinkAuthentication validates and copies bounded projections without IO, proof verification, consumption or clock reads. Command IDs are canonical nonzero random128 IDs, identifier IDs use the kernel policy, capability IDs are 1..128 visible ASCII bytes, and both versions are positive. Times are normalized to UTC without changing instants; expiry must follow authentication.

func (MagicLinkAuthentication) Bindings

Bindings returns an owned historical projection, never proof or permission. Zero returns redacted ErrInvalidSession. Correlated metadata must not be logged.

func (MagicLinkAuthentication) Format

func (MagicLinkAuthentication) Format(s fmt.State, _ rune)

Format redacts original command, grant and identifier for every verb.

func (MagicLinkAuthentication) MarshalJSON

func (MagicLinkAuthentication) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit metadata export; trusted stores use Bindings.

func (MagicLinkAuthentication) MarshalText

func (MagicLinkAuthentication) MarshalText() ([]byte, error)

MarshalText rejects implicit export and map-key disclosure.

type MagicLinkAuthenticationSpec

type MagicLinkAuthenticationSpec struct {
	CommandID, RequestCommandID            identity.CommandID
	CapabilityID                           string
	IdentifierID                           identity.IdentifierID
	IdentifierVersion, VerificationVersion uint64
	AuthenticatedAt, ValidUntil            time.Time
}

MagicLinkAuthenticationSpec is historical, secret-free email-possession provenance. CommandID names consumption; RequestCommandID names original issuance. CapabilityID and identifier versions name that exact grant and verified address. AuthenticatedAt and exclusive ValidUntil retain the original consuming admission, not an authoritative validity lease. Complete trusted storage must retain this separately from SessionSpec; no token or proof is present. Construction cannot certify consumption, identity or factor policy.

type OTPAuthentication

type OTPAuthentication struct {
	// contains filtered or unexported fields
}

OTPAuthentication freezes historical OTP metadata. Copies are concurrency-safe. Construction is not authentication, consumption, current authority or permission to issue a session. The native issuer must establish those in one transaction.

func NewOTPAuthentication

func NewOTPAuthentication(p OTPAuthenticationSpec) (OTPAuthentication, error)

NewOTPAuthentication validates and copies a trusted projection without IO. IDs are bounded before parsing; challenge IDs retain up to256 UTF-8 bytes with no control runes. Command and attempt IDs are canonical nonzero random128 IDs. Only email/phone possession is supported; other methods must use their owner.

func (OTPAuthentication) Bindings

Bindings returns a caller-owned historical projection. Zero returns only the redacted ErrInvalidSession. Correlated metadata must never enter logs.

func (OTPAuthentication) Format

func (OTPAuthentication) Format(s fmt.State, _ rune)

Format redacts correlated authentication metadata for every verb.

func (OTPAuthentication) MarshalJSON

func (OTPAuthentication) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit export; trusted stores use explicit Bindings.

func (OTPAuthentication) MarshalText

func (OTPAuthentication) MarshalText() ([]byte, error)

MarshalText denies implicit export and map-key disclosure.

type OTPAuthenticationSpec

type OTPAuthenticationSpec struct {
	CommandID, SendCommandID               identity.CommandID
	ChallengeID, AttemptID                 string
	IdentifierID                           identity.IdentifierID
	IdentifierKind                         identity.IdentifierKind
	IdentifierVersion, VerificationVersion uint64
	AuthenticatedAt, ValidUntil            time.Time
}

OTPAuthenticationSpec is historical, non-secret authentication provenance for trusted storage. CommandID is the consuming signin, SendCommandID its original delivery, and AttemptID the original server-issued random128 attempt. The identifier must be the exact verified email or phone used by that challenge. Versions name those original records, not current eligibility. AuthenticatedAt and ValidUntil retain the original successful check and exclusive continuation expiry; neither is an authoritative validity lease. Persist this together with the complete SessionSpec. It contains no code, bearer, proof or replay grant.

type OptionalAuthorityBinding

type OptionalAuthorityBinding struct {
	Present bool
	Binding AuthorityBinding
}

OptionalAuthorityBinding has exactly two legal forms: absent with zero Binding, or present with a valid positive Binding. Missing factor/passkey authority cannot be represented as a zero version on a present dimension.

type OrganizationSelectionCommand

type OrganizationSelectionCommand struct {
	// contains filtered or unexported fields
}

OrganizationSelectionCommand freezes a neutral record transition. Zero is invalid; copies are concurrency-safe. The sole native organization command must enlist the session-owned CAS, membership/lifecycle admission and required effects in one coordinator transaction. Construction grants no authority.

func NewOrganizationSelectionCommand

func NewOrganizationSelectionCommand(b identity.CommandBinding, source Session, selection ActiveOrganizationSelection) (OrganizationSelectionCommand, error)

NewOrganizationSelectionCommand constructs an exact self-session CAS without IO. Selection must name source's tenant, stable ID and current version; the command's human actor and effective user must match that source. The successor preserves lookup, family, original authentication/provenance, remember policy, activity and expiry. It increments only the session version and replaces or clears the organization dimension. Overflow and malformed/foreign input return ErrInvalidSessionCommand with no partial command. Native owners must separately require original authenticated custody and every current authority.

Version-bound CSRF state is cleared, never copied to a new version. This constructor does not deliver replacement browser state; cookie composition must remain disabled until its own authorized replacement flow is selected.

func (OrganizationSelectionCommand) Bindings

Bindings returns a caller-owned scalar projection. Mutating it cannot change the command. Source/successor remain immutable and are not live admissions.

func (OrganizationSelectionCommand) Format

Format redacts command scope for every formatting verb.

func (OrganizationSelectionCommand) MarshalJSON

func (OrganizationSelectionCommand) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit command disclosure or reconstructed custody.

func (OrganizationSelectionCommand) MarshalText

func (OrganizationSelectionCommand) MarshalText() ([]byte, error)

MarshalText rejects implicit command disclosure, including map-key encoding.

func (OrganizationSelectionCommand) ValidateAt

func (c OrganizationSelectionCommand) ValidateAt(now time.Time) error

ValidateAt checks only the original source's absolute/idle lifetime. It never refreshes activity or authenticates selection. The executor must retain the original positive-evidence deadline and independently fence current owners.

type OrganizationSelectionCommandSpec

type OrganizationSelectionCommandSpec struct {
	Binding           identity.CommandBinding
	Source, Successor Session
	Selection         ActiveOrganizationSelection
}

OrganizationSelectionCommandSpec projects immutable source and successor records for the organization owner's atomic active-set operation. Only the selected organization and exact session version/vector may change. No token, authority lease or transaction is conveyed by this projection.

type PreAuthBinding

type PreAuthBinding struct {
	ID                  identity.PreAuthTransactionID
	Intent              PreAuthIntent
	IssuedAt, ExpiresAt time.Time
}

PreAuthBinding preserves the original flow identity and timeline. ID alone grants no authority. IssuedAt/ExpiresAt are authoritative original UTC times; general configured TTL is 1..10 minutes, with the reference profile exactly five minutes. A continuation may not restart either time or replace intent.

func (PreAuthBinding) Format

func (PreAuthBinding) Format(s fmt.State, _ rune)

Format redacts every correlated flow field.

func (PreAuthBinding) MarshalJSON

func (PreAuthBinding) MarshalJSON() ([]byte, error)

MarshalJSON denies automatic private flow export.

func (PreAuthBinding) MarshalText

func (PreAuthBinding) MarshalText() ([]byte, error)

MarshalText denies automatic private flow export.

type PreAuthIntent

type PreAuthIntent struct {
	TenantID                    identity.TenantID
	Action, Origin, CallbackURL string
	Nonce                       [32]byte
	Remember                    RememberPolicy
	PolicyID                    string
	PolicyVersion               uint64
	// IdentifierBinding is an optional server-derived commitment to the exact
	// canonical identifier, tenant, purpose and comparison profile. Zero retains
	// legacy unbound intent. A selected identifier-bound workflow must require
	// and compare this commitment before credential work; its presence alone is
	// not authentication. Never use plaintext identifiers or client-chosen hashes.
	IdentifierBinding [32]byte
	// Purpose is normally zero. Phone password recovery issues no session;
	// its exact action/identifier binding and absent Remember are mandatory.
	Purpose PreAuthPurpose
}

PreAuthIntent freezes the selected unauthenticated session-issuance/linking intent. IDs/actions/policy IDs are exact 1..128 visible ASCII bytes; versions are positive. Origin is an exact HTTPS origin (HTTP only for explicit local development loopback), without path/query/fragment/userinfo. CallbackURL is empty for explicitly no redirect, or a bounded absolute URL under the same transport rules, without userinfo/fragment. No normalization or allowlisting occurs here: trusted initiation must validate configured origins/redirects before creating intent. Nonce is 32 server-generated bytes, not all zero. Login Remember must already be resolved, never defaulted during continuation. Phone recovery instead selects its exact Purpose and leaves Remember zero. This private projection is not credential verification or policy authority.

func (PreAuthIntent) Format

func (PreAuthIntent) Format(s fmt.State, _ rune)

Format redacts every correlated flow field.

func (PreAuthIntent) MarshalJSON

func (PreAuthIntent) MarshalJSON() ([]byte, error)

MarshalJSON denies automatic private flow export.

func (PreAuthIntent) MarshalText

func (PreAuthIntent) MarshalText() ([]byte, error)

MarshalText denies automatic private flow export.

type PreAuthIssuanceExecutor

type PreAuthIssuanceExecutor interface {
	ExecutePreAuthIssuance(context.Context, PreAuthIssueCommand) (PreAuthIssueExecution, error)
	RecoverPreAuthIssue(context.Context, identity.RecoveryQuery) (identity.CommandResult, error)
}

PreAuthIssuanceExecutor extends owned initiation with explicit replay metadata for commit-gated delivery. It is separate from PreAuthIssueExecutor to preserve existing receipt-only implementations. ExecutePreAuthIssuance returns Replayed for terminal observations and any call that did not acquire execution custody; errors, cancellation and Unknown never authorize delivery. RecoverPreAuthIssue remains outcome-only and never permits credential delivery. Calls must be bounded, cancellation-aware and concurrency-safe.

type PreAuthIssueCommand

type PreAuthIssueCommand struct {
	CommandID     identity.CommandID
	CorrelationID string
	Record        PreAuthTransaction
}

PreAuthIssueCommand freezes a server-prepared original flow with a stable command identity and correlation. Record is structural, not authentication. Server initiation owns nonce, cookie commitment, original time and resolved remember policy; never decode this value directly from HTTP input. The same complete command must be retained across retries; no raw cookie is accepted. Copies preserve immutable Record custody and may be read concurrently. Zero is invalid at execution; this scalar contract performs no IO or validation.

func (PreAuthIssueCommand) Format

func (PreAuthIssueCommand) Format(s fmt.State, _ rune)

Format redacts flow custody and correlation for every formatting verb.

func (PreAuthIssueCommand) MarshalJSON

func (PreAuthIssueCommand) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit original flow or command disclosure.

func (PreAuthIssueCommand) MarshalText

func (PreAuthIssueCommand) MarshalText() ([]byte, error)

MarshalText denies implicit original flow disclosure, including map keys.

type PreAuthIssueExecution

type PreAuthIssueExecution struct {
	Receipt  identity.CommandResult
	Replayed bool
}

PreAuthIssueExecution distinguishes original execution from a historical receipt. Replayed is true unless this call acquired the sole coordinator's execution reservation. A committed receipt alone never permits cookie delivery: an issuer must also require !Replayed, no error and exact original scope and unexpired lifetime. This value contains no credential or current authentication. Public reconstruction is structural, not authority; only the trusted executor establishes the observation. Do not mutate concurrently.

func (PreAuthIssueExecution) Format

func (PreAuthIssueExecution) Format(s fmt.State, _ rune)

Format redacts original scope and retained receipt metadata.

func (PreAuthIssueExecution) MarshalJSON

func (PreAuthIssueExecution) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit receipt or original flow disclosure.

func (PreAuthIssueExecution) MarshalText

func (PreAuthIssueExecution) MarshalText() ([]byte, error)

MarshalText denies implicit receipt disclosure, including map keys.

type PreAuthIssueExecutor

type PreAuthIssueExecutor interface {
	ExecutePreAuthIssue(context.Context, PreAuthIssueCommand) (identity.CommandResult, error)
	RecoverPreAuthIssue(context.Context, identity.RecoveryQuery) (identity.CommandResult, error)
}

PreAuthIssueExecutor is the storage-neutral owned initiation/recovery seam. Implementations authorize configured service scope and atomically stage the exact original flow, required effects and receipt under the sole command owner. Unknown never authorizes issuance under a different command. Exact replay/recovery return historical metadata, no cookie or renewed flow. Recovery must not reserve missing commands or infer rollback from flow absence. Calls must be bounded, cancellation-aware and concurrency-safe. This seam does not create flow entropy, select policy or reveal credentials.

type PreAuthIssueResult

type PreAuthIssueResult struct {
	CommandID     identity.CommandID
	CommitOutcome identity.CommitOutcome
	Flow          PreAuthTransaction
	Token         Token
	Cookie        http.Cookie
	Replayed      bool
	RetryAfter    time.Duration
}

PreAuthIssueResult preserves durable outcome and original structural metadata. Token and credential-free Cookie are populated only on exact new commitment, no error/cancellation and at least one second of original flow lifetime. Flow is historical metadata, not active state or authentication. Recovery and replay return no credential. Token copies share reveal-once custody. HTTP may assign Value only when delivering; never log a populated credential cookie.

func (PreAuthIssueResult) Format

func (PreAuthIssueResult) Format(s fmt.State, _ rune)

Format redacts original outcome scope and transport custody.

func (PreAuthIssueResult) MarshalJSON

func (PreAuthIssueResult) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit credential/result export.

func (PreAuthIssueResult) MarshalText

func (PreAuthIssueResult) MarshalText() ([]byte, error)

MarshalText denies implicit credential/result export.

type PreAuthIssuer

type PreAuthIssuer struct {
	// contains filtered or unexported fields
}

PreAuthIssuer owns original entropy and commit-gated flow-cookie delivery. It authenticates no user and holds no store, journal, lock or goroutine. Compose the owned durable executor; dependencies remain borrowed and must outlive calls. Preparations retain credentials privately across value copies.

func NewPreAuthIssuer

func NewPreAuthIssuer(executor PreAuthIssuanceExecutor, c PreAuthIssuerConfig) (*PreAuthIssuer, error)

NewPreAuthIssuer validates trusted composition without IO or entropy. The durable executor must independently enforce the identical selected profile.

func (PreAuthIssuer) Format

func (PreAuthIssuer) Format(s fmt.State, _ rune)

Format redacts retained policy, dependencies and key composition.

func (*PreAuthIssuer) Issue

Issue attempts one unchanged preparation with an earlier-deadline-preserving execution budget. Copies share one local attempt; after Unknown recover the original command, never prepare a replacement. A known commitment survives delivery failure. Flow cookies expire within original TTL for both remember choices; persistent-session choice never extends unauthenticated flow time.

func (PreAuthIssuer) MarshalJSON

func (PreAuthIssuer) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit runtime composition export.

func (*PreAuthIssuer) Prepare

func (s *PreAuthIssuer) Prepare(input PreAuthPrepareInput) (out PreparedPreAuthIssuance, err error)

Prepare validates all supplied input before generating a canonical random flow ID, 32-byte nonce and opaque cookie. Original time comes from the trusted clock and is never refreshed by retries or final-session remember policy. No durable work, authentication, policy callback or proof consumption occurs.

func (*PreAuthIssuer) Recover

Recover performs current-policy primary outcome lookup for the exact original safe command, even after flow expiry. It neither executes nor renews flow state and never delivers a credential, including on known commitment.

type PreAuthIssuerConfig

type PreAuthIssuerConfig struct {
	ActorID                               identity.ActorID
	Action, Origin, CallbackURL, PolicyID string
	PolicyVersion                         uint64
	Clock                                 IssuerClock
	MaximumDuration, FlowTTL              time.Duration
	LookupKey                             DigestKey
	TokenSize                             int
	Cookie                                CookiePolicy
	// Purpose zero preserves login; phone recovery requires no Remember and
	// an original nonzero identifier binding. It enables no reset workflow.
	Purpose PreAuthPurpose
}

PreAuthIssuerConfig freezes one trusted service/action/origin/callback/policy profile. Empty callback explicitly disables redirection. Never select these values from client input. FlowTTL is 1..10 minutes (reference: five minutes), independent of the resolved final-session remember choice. LookupKey must be a dedicated retained pre-auth key; TokenSize is 32..64 bytes. Cookie must be the validated __Host-identity_flow Lax/Strict policy. MaximumDuration is 1ms..30s. Clock must be concurrency-safe, trusted and nonblocking.

func (PreAuthIssuerConfig) Format

func (PreAuthIssuerConfig) Format(s fmt.State, _ rune)

Format redacts trusted profile and digest-key composition.

func (PreAuthIssuerConfig) MarshalJSON

func (PreAuthIssuerConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit runtime configuration export.

type PreAuthPrepareInput

type PreAuthPrepareInput struct {
	CommandID     identity.CommandID
	TenantID      identity.TenantID
	CorrelationID string
	Remember      RememberPolicy
	// IdentifierBinding is the workflow owner's original canonical-identifier
	// commitment. It is retained unchanged, not computed or authenticated here.
	IdentifierBinding [32]byte
}

PreAuthPrepareInput supplies server-selected command, tenant and correlation identities plus the already-resolved final session choice for login, or zero Remember and a nonzero identifier commitment for phone recovery. It cannot select the flow ID, nonce, cookie, original timeline or trusted profile. Retain the returned preparation unchanged; calling Prepare again is not a retry.

func (PreAuthPrepareInput) Format

func (PreAuthPrepareInput) Format(s fmt.State, _ rune)

Format redacts tenant, command and correlation custody.

func (PreAuthPrepareInput) MarshalJSON

func (PreAuthPrepareInput) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit original preparation-input export.

type PreAuthPurpose

type PreAuthPurpose uint8

PreAuthPurpose distinguishes session-issuing login from recovery that cannot carry a session-lifetime choice. Unknown values deny; zero preserves login.

const (
	// PreAuthSessionIssuance retains the original login/linking framing and
	// requires a resolved RememberPolicy before any continuation is issued.
	PreAuthSessionIssuance PreAuthPurpose = iota
	// PreAuthPhonePasswordRecovery selects only phone password-reset initiation,
	// requires an identifier commitment and forbids every RememberPolicy.
	PreAuthPhonePasswordRecovery
)

type PreAuthTransaction

type PreAuthTransaction struct {
	// contains filtered or unexported fields
}

PreAuthTransaction owns immutable structural continuation state. It is not authentication, an active primary record or one-use proof. Zero is invalid. Copies are safe for concurrent reads; no resource/goroutine is retained.

func NewPreAuthTransaction

func NewPreAuthTransaction(s PreAuthTransactionSpec) (PreAuthTransaction, error)

NewPreAuthTransaction freezes validated private storage without issuing a cookie or persisting a flow. Invalid input returns a zero value and redacted ErrInvalidPreAuthTransaction. Policy allowlists, trusted nonce provenance, active state and atomic one-use reservation/finalization must be independently checked by the owned initiation/continuation and primary adapter.

func (PreAuthTransaction) Bindings

Bindings returns an owned private scalar projection without renewing the timeline or remember choice. Never log it or expose it as a wire credential.

func (PreAuthTransaction) Check

func (p PreAuthTransaction) Check(now time.Time, expected PreAuthBinding, cookie TokenDigest) error

Check compares the complete original expected binding and independently computed flow-cookie digest. Now must be primary authoritative time sampled after locking the current record; equality at expiry denies. The earlier flow state is never refreshed. Success is only structural/temporal agreement: it cannot authenticate a subject, check current primary state or consume a flow. The durable owner must fence its exact version/state and finalize with session issuance/linking in the shared transaction. No IO or callbacks run.

func (PreAuthTransaction) Format

func (PreAuthTransaction) Format(s fmt.State, _ rune)

Format redacts every correlated flow field.

func (PreAuthTransaction) MarshalJSON

func (PreAuthTransaction) MarshalJSON() ([]byte, error)

MarshalJSON denies automatic private flow export.

func (PreAuthTransaction) MarshalText

func (PreAuthTransaction) MarshalText() ([]byte, error)

MarshalText denies automatic private flow export.

type PreAuthTransactionSpec

type PreAuthTransactionSpec struct {
	Binding PreAuthBinding
	Cookie  TokenDigest
	Version uint64
}

PreAuthTransactionSpec is a complete private storage projection. Cookie is the named-key domain-separated flow-cookie digest, never a raw bearer or a session lookup digest. Version is the positive durable record CAS version. Active/reserved/terminal state, exact reservation custody, current policy, one-use consumption and commit recovery remain the durable adapter's owners.

func (PreAuthTransactionSpec) Format

func (PreAuthTransactionSpec) Format(s fmt.State, _ rune)

Format redacts every correlated flow field.

func (PreAuthTransactionSpec) MarshalJSON

func (PreAuthTransactionSpec) MarshalJSON() ([]byte, error)

MarshalJSON denies automatic private flow export.

func (PreAuthTransactionSpec) MarshalText

func (PreAuthTransactionSpec) MarshalText() ([]byte, error)

MarshalText denies automatic private flow export.

type PreparedIssuance

type PreparedIssuance struct {
	// contains filtered or unexported fields
}

PreparedIssuance retains an original bearer privately with its exact command and proof. Zero is invalid. It can be copied concurrently; no public operation reveals its bearer. One atomic attempt is shared across all copies. It is not a durable receipt, a replay store or a replacement for executor idempotency. Retain Request for proof-route recovery; OTP recovery must use separate code-free native correlation; password recovery must be password/cookie-free. Do not Prepare again to retry an unknown command.

func (PreparedIssuance) CSRFToken

func (p PreparedIssuance) CSRFToken() (CSRFToken, error)

CSRFToken returns the original reveal-once token only after this preparation completes an exact new error-free Issue within delivery bounds. Before that, after recovery-only observations, and for tokenless profiles it denies. Copies share the same reveal permission; repeated access does not create a new token. Holding a returned token does not certify current session authority. An earlier successful delivery remains owned even if a later retry is rejected, just as an already returned bearer cannot be retracted from its recipient.

func (PreparedIssuance) Format

func (PreparedIssuance) Format(f fmt.State, _ rune)

Format redacts every scope and credential for all formatting verbs.

func (PreparedIssuance) MarshalJSON

func (PreparedIssuance) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit credential/command serialization.

func (PreparedIssuance) MarshalText

func (PreparedIssuance) MarshalText() ([]byte, error)

MarshalText rejects implicit text or map-key serialization.

func (PreparedIssuance) Request

func (p PreparedIssuance) Request() (IssueRequest, bool)

Request returns the original proof-route command/proof for durable recovery, without bearer bytes. Zero, OTP and password preparations deny: secret-bearing consuming commands must never be advertised as safe recovery input.

func (PreparedIssuance) Session

func (p PreparedIssuance) Session() (Session, bool)

Session returns the original tokenless structural session projection. It cannot authenticate, authorize, reserve or reveal a bearer. In the OTP profile the native adapter must bind this exact projection into the final command before reservation; its original digest and metadata must not be regenerated. Zero returns false. Complete mapping also retains OTPAuthentication/CSRFState.

type PreparedPreAuthIssuance

type PreparedPreAuthIssuance struct {
	// contains filtered or unexported fields
}

PreparedPreAuthIssuance owns an immutable original command and private bearer. Zero is invalid. Copies share one atomic execution attempt, not a durable replay authority. Retain Command for outcome-only recovery; no method exposes credential bytes before successful new committed issuance.

func (PreparedPreAuthIssuance) Command

Command returns the unchanged private original for durable recovery, without exposing bearer bytes or granting execution authority. Zero returns false.

func (PreparedPreAuthIssuance) Format

func (PreparedPreAuthIssuance) Format(s fmt.State, _ rune)

Format redacts all original flow, command and bearer custody.

func (PreparedPreAuthIssuance) MarshalJSON

func (PreparedPreAuthIssuance) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit private preparation disclosure.

func (PreparedPreAuthIssuance) MarshalText

func (PreparedPreAuthIssuance) MarshalText() ([]byte, error)

MarshalText denies implicit private preparation disclosure.

type PreparedRotation

type PreparedRotation struct {
	// contains filtered or unexported fields
}

PreparedRotation privately retains the original successor token, command and opaque source custody. Copies share one atomic attempt; the durable owner, not this in-memory claim, owns idempotency. Retain Request for safe recovery.

func (PreparedRotation) CSRFToken

func (p PreparedRotation) CSRFToken() (CSRFToken, error)

CSRFToken returns original reveal-once cookie-CSRF custody only after an exact new error-free Rotate within original delivery bounds. Zero, precommit, recovery-only, tokenless and bearer paths deny. Copies share reveal permission; an earlier successful delivery is not retracted by a later rejected attempt. This token never proves current primary authority or renews validity.

func (PreparedRotation) Format

func (PreparedRotation) Format(s fmt.State, _ rune)

Format redacts original private token custody.

func (PreparedRotation) MarshalJSON

func (PreparedRotation) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit bearer custody serialization.

func (PreparedRotation) Request

func (p PreparedRotation) Request() (RotationRequest, bool)

Request returns the original safe immutable request, never the raw successor.

type RememberChoice

type RememberChoice uint8

RememberChoice distinguishes omitted input from both explicit choices. Continuations carry RememberPolicy, never this unresolved input.

const (
	// RememberDefault resolves through LifetimeConfig.Default exactly once.
	RememberDefault RememberChoice = iota
	// BrowserSession omits cookie persistence and caps authority at 24 hours.
	// Browser restoration can retain session cookies; server expiry still applies.
	BrowserSession
	// PersistentSession permits a persistent cookie bounded by session expiry.
	PersistentSession
)

type RememberPolicy

type RememberPolicy struct {
	// contains filtered or unexported fields
}

RememberPolicy is an immutable resolved choice and lifetime policy, safe to copy across authentication continuations and concurrent callers. Zero is invalid. It is configuration, not authenticated proof or session authority.

func NewRememberPolicy

func NewRememberPolicy(s RememberPolicySpec) (RememberPolicy, error)

NewRememberPolicy reconstructs a previously resolved policy. Invalid bounds, omitted choices and values requiring browser/lifetime clamping return ErrInvalidPolicy rather than silently changing the stored policy. Call ResolveRememberPolicy only for new choices using deployment configuration. Reconstruction performs no IO and does not renew any timestamp or authority.

func ResolveRememberPolicy

func ResolveRememberPolicy(choice RememberChoice, c LifetimeConfig) (RememberPolicy, error)

ResolveRememberPolicy resolves omitted input once. A browser choice cannot be upgraded by a later continuation: retain the returned value unchanged. Invalid configuration fails even for explicit choices. No callbacks or IO run.

Example
package main

import (
	"fmt"
	"github.com/faustbrian/go-identity/session"
	"net/http"
	"time"
)

func main() {
	policy, err := session.ResolveRememberPolicy(session.BrowserSession, session.LifetimeConfig{
		Default: session.PersistentSession, AbsoluteTTL: 7 * 24 * time.Hour,
		IdleTTL: 24 * time.Hour, RefreshAfter: 12 * time.Hour, FreshFor: 24 * time.Hour,
	})
	if err != nil {
		panic(err)
	}
	// Retain this resolved value unchanged through any MFA continuation.
	cookies, err := session.NewCookiePolicy(session.CookieConfig{Name: "__Host-identity_session", SameSite: http.SameSiteLaxMode})
	if err != nil {
		panic(err)
	}
	now := time.Date(2026, 10, 2, 12, 0, 0, 0, time.UTC)
	lifetime, err := policy.Evaluate(now, now, now, now)
	if err != nil {
		panic(err)
	}
	attributes, err := cookies.Attributes(policy, now, lifetime.AbsoluteExpiresAt)
	if err != nil {
		panic(err)
	}
	// Value is empty: this example issues no credential.
	fmt.Println(policy.AbsoluteTTL(), attributes.MaxAge, attributes.Expires.IsZero())
}
Output:
24h0m0s 0 true

func (RememberPolicy) AbsoluteTTL

func (p RememberPolicy) AbsoluteTTL() time.Duration

AbsoluteTTL returns the immutable lifetime cap; zero returns zero.

func (RememberPolicy) Bindings

func (p RememberPolicy) Bindings() (RememberPolicySpec, error)

Bindings returns an owned complete scalar projection without choosing a new default or extending limits. A zero policy returns ErrInvalidPolicy. The projection is configuration, not proof of a live or authorized session.

func (RememberPolicy) Choice

func (p RememberPolicy) Choice() RememberChoice

Choice returns the resolved explicit choice; zero returns RememberDefault.

func (RememberPolicy) Evaluate

func (p RememberPolicy) Evaluate(now, issuedAt, lastActivity, authenticatedAt time.Time) (Lifetime, error)

Evaluate computes expiry at authoritative now. issuedAt is original family issuance, lastActivity is an authoritative accepted-use timestamp and authenticatedAt is the original completed authentication/reauthentication. It may precede issuance: resetting it to issuance would renew proof freshness. Activity/rotation never resets issuedAt or authenticatedAt. Future, pre-issuance activity, zero and out-of-range times fail closed; equality with expiry is expired and equality with freshness end is not fresh. No skew is silently granted. Evaluate neither reads nor mutates a store.

type RememberPolicySpec

type RememberPolicySpec struct {
	Choice       RememberChoice
	AbsoluteTTL  time.Duration
	IdleTTL      time.Duration
	RefreshAfter time.Duration
	FreshFor     time.Duration
}

RememberPolicySpec is the complete non-secret resolved policy projection for trusted persistence and authentication continuations. Durations retain their exact nanosecond precision. Choice must be explicit; no deployment default belongs in a stored policy. This value supplies no authentication authority.

type RevokeAllInput

type RevokeAllInput struct {
	TenantID               identity.TenantID
	Credential             Credential
	CommandID              identity.CommandID
	CorrelationID          string
	IncludeCurrent         bool
	ExpectedSubjectVersion uint64
}

RevokeAllInput explicitly selects source disposition and the positive current user-authority CAS version. That version must equal the authenticated snapshot; it is not a caller-selected invalidation authority. Native execution rechecks it under the same primary user lock that serializes issuance/revocation.

func (RevokeAllInput) Format

func (RevokeAllInput) Format(s fmt.State, _ rune)

Format redacts correlated credential input.

func (RevokeAllInput) MarshalJSON

func (RevokeAllInput) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit credential export.

type RevokeFamilyCommandSpec

type RevokeFamilyCommandSpec struct {
	Binding         identity.CommandBinding
	ExpectedVersion uint64
}

RevokeFamilyCommandSpec targets exactly Binding.RecordID's family owned by Binding.UserID in Binding.TenantID. ExpectedVersion is a positive current family version with a representable successor. It grants no authorization. Revocation retains historical session snapshots and never issues a bearer.

type RevokeOneCommandSpec

type RevokeOneCommandSpec struct {
	Binding identity.CommandBinding
	Session Session
}

RevokeOneCommandSpec targets one exact session with its original complete authority snapshot and positive version. Binding.RecordID is the session ID, never the family ID. This structural projection grants no caller authority. A durable owner must compare current ownership/version and revoke only this session, leaving sibling records and family authority unchanged.

type RevokeOneExecutor

type RevokeOneExecutor interface {
	ExecuteRevokeOne(context.Context, RevokeOneRequest) (identity.CommandResult, error)
}

RevokeOneExecutor is the storage-neutral execution boundary implemented by the owned durable adapter, not an application domain store. It authenticates original request custody, authorizes current policy before reservation and atomically compares current source/target owners with mutation, audit and lifecycle effects. It must honor ctx, preserve original admission expiry and be concurrency-safe. A zero receipt conveys no authoritative observation; panic, unavailable or malformed responses never prove rollback. Historical recovery belongs to that same durable owner, not a second command journal. Requests carrying CSRFToken require the executor's own trusted named-key selection and exact original-primary CSRF admission in that same transaction; an executor lacking that profile must reject them before reservation.

type RevokeOneRequest

type RevokeOneRequest struct {
	// contains filtered or unexported fields
}

RevokeOneRequest retains an exact target command and the original opaque authenticated caller admission. Zero is invalid. Copies preserve the original exclusive deadline; no constructor accepts caller-built principal fields. This is authentication custody, not policy permission, durable execution or evidence that the target is still active. The owned executor must recheck original caller and target owners, policy and deadline in its sole transaction.

func (RevokeOneRequest) CSRFToken

func (r RevokeOneRequest) CSRFToken() (CSRFToken, bool)

CSRFToken returns optional opaque input custody for trusted native admission, not a validity proof or serialization projection. Zero and legacy direct requests return zero,false. Copies share original reveal custody; admission must never Reveal it. Key selection remains the executor's trusted policy.

func (RevokeOneRequest) Caller

func (r RevokeOneRequest) Caller() Session

Caller returns the original authenticating source record, not the target. Zero returns zero. This is historical metadata only; the executor must use original opaque request admission and recheck this source's active owners.

func (RevokeOneRequest) Command

func (r RevokeOneRequest) Command() (SessionCommand, bool)

Command returns the immutable exact target projection; zero returns false. This loses private caller custody and cannot independently authorize execution.

func (RevokeOneRequest) Format

func (RevokeOneRequest) Format(s fmt.State, _ rune)

Format prevents scope, credential and caller linkage disclosure.

func (RevokeOneRequest) MarshalJSON

func (RevokeOneRequest) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit authentication request persistence/export.

func (RevokeOneRequest) MarshalText

func (RevokeOneRequest) MarshalText() ([]byte, error)

MarshalText rejects text and map-key disclosure of caller custody.

func (RevokeOneRequest) ValidUntil

func (r RevokeOneRequest) ValidUntil() time.Time

ValidUntil returns the preserved original exclusive admission deadline. Zero returns zero. The timestamp alone cannot establish caller provenance.

func (RevokeOneRequest) Validate

func (r RevokeOneRequest) Validate(service *SessionService, now time.Time) error

Validate checks private caller provenance against trusted configured service and time, not request-selected dependencies. The original exclusive deadline, backward-clock and lifetime checks apply. It does not refresh authority or require fresh authentication. The durable owner must call this before reservation and final commit, and atomically compare current source/target owner bindings and policy; a structural Command or Caller cannot replace it.

type RevokeOtherInput

type RevokeOtherInput struct {
	TenantID      identity.TenantID
	Credential    Credential
	CommandID     identity.CommandID
	CorrelationID string
}

RevokeOtherInput selects actual source credentials and a host-generated command/correlation, never user/session targets. Zero credential or malformed binding is invalid. HTTP owns canonical parsing and cookie origin/CSRF policy.

func (RevokeOtherInput) Format

func (RevokeOtherInput) Format(s fmt.State, _ rune)

Format redacts correlated credential input.

func (RevokeOtherInput) MarshalJSON

func (RevokeOtherInput) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit credential export.

type RevokeSetCommandSpec

type RevokeSetCommandSpec struct {
	Binding         identity.CommandBinding
	Caller          Session
	IncludeCurrent  bool
	MaximumSessions uint32
}

RevokeSetCommandSpec freezes user-owned bulk revocation with its exact authenticating source record. Binding.RecordID is that exact source session ID; Binding.UserID fixes the effective owner of the selected set. IncludeCurrent is false for revoke-other and explicit for revoke-all. MaximumSessions is an all-or-nothing active-row bound of 1..100000, not permission to truncate or paginate mutations. The durable owner must lock source/current user authority and serialize with issuance, atomically revoke every selected user session (across audiences), audit and retain command recovery. Preserve complete historical records and never reset lifetime or authentication freshness. When the source survives, only its existing session version advances, with its matching snapshot binding; a user-wide authority bump must not accidentally invalidate that survivor. This structural projection is neither authentication nor an executed workflow.

func (RevokeSetCommandSpec) Format

func (RevokeSetCommandSpec) Format(s fmt.State, _ rune)

Format redacts structural user/source projections.

func (RevokeSetCommandSpec) MarshalJSON

func (RevokeSetCommandSpec) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit structural projection export.

type RevokeSetExecutionResult

type RevokeSetExecutionResult struct {
	Receipt               identity.CommandResult
	RevokedCount          uint32
	SubjectVersion        uint64
	CurrentSessionRevoked bool
}

RevokeSetExecutionResult is the owned durable receipt plus retained metadata. On committed outcomes, RevokedCount is bounded by the command limit, SubjectVersion is the unchanged current user-authority CAS version and CurrentSessionRevoked matches the explicit disposition. Receipt versions describe the source session's successor, never a new user-wide authority. If an error prevents retained metadata retrieval after a known commit, all three metadata fields are zero; the exact committed receipt remains intact. On other outcomes those metadata fields must all be zero. No credentials or refreshed authentication are returned. Treat this as historical metadata only.

func (RevokeSetExecutionResult) Format

func (RevokeSetExecutionResult) Format(s fmt.State, _ rune)

Format redacts correlated native receipt metadata.

func (RevokeSetExecutionResult) MarshalJSON

func (RevokeSetExecutionResult) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit durable result export.

type RevokeSetExecutor

type RevokeSetExecutor interface {
	ExecuteRevokeSet(context.Context, RevokeSetRequest) (RevokeSetExecutionResult, error)
}

RevokeSetExecutor is the owned durable adapter boundary, not an application workflow callback. It authorizes before reservation, checks original opaque caller custody/freshness and current owners, serializes against issuance, and applies the entire bounded set plus source-version transition/audit/lifecycle in the sole transaction. It persists exact counts, source disposition and command recovery; an unknown outcome never authorizes a replacement mutation. Dependencies honor ctx, are concurrency-safe and remain borrowed through calls.

type RevokeSetRequest

type RevokeSetRequest struct {
	// contains filtered or unexported fields
}

RevokeSetRequest binds an immutable bulk command to the original opaque Get admission from one exact configured reader. Zero is invalid. Copies cannot renew authority or authentication freshness. This is not permission: the owned executor must authorize and recheck source/current owner state in the sole transaction before revocation, audit, lifecycle effects and commit.

func (RevokeSetRequest) Caller

func (r RevokeSetRequest) Caller() Session

Caller returns historical source metadata; zero returns zero. The exact service-bound request, not this projection, is required for execution.

func (RevokeSetRequest) Command

func (r RevokeSetRequest) Command() (SessionCommand, bool)

Command returns the immutable structural projection; zero returns false. It does not transfer opaque caller custody or authorize execution.

func (RevokeSetRequest) Format

func (RevokeSetRequest) Format(s fmt.State, _ rune)

Format redacts correlated command and caller custody for every diagnostic verb.

func (RevokeSetRequest) MarshalJSON

func (RevokeSetRequest) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit custody persistence/export.

func (RevokeSetRequest) MarshalText

func (RevokeSetRequest) MarshalText() ([]byte, error)

MarshalText denies implicit text/map-key export.

func (RevokeSetRequest) ValidUntil

func (r RevokeSetRequest) ValidUntil() time.Time

ValidUntil returns the earlier original authority/freshness deadline; zero returns zero. The timestamp itself cannot authenticate a source or renew it.

func (RevokeSetRequest) Validate

func (r RevokeSetRequest) Validate(service *SessionService, now time.Time) error

Validate checks original private provenance and exclusive authority/freshness deadlines at trusted now. The owned executor calls it before reservation and final commit; mapped fields or Caller are never substitutes for this custody. It does not reread authority, renew admission, authorize or mutate a store.

type RevokeSetResult

type RevokeSetResult struct {
	CommandID             identity.CommandID
	CommitOutcome         identity.CommitOutcome
	RetryAfter            time.Duration
	Recovery              identity.RecoveryQuery
	RevokedCount          uint32
	SubjectVersion        uint64
	SessionVersion        uint64
	CurrentSessionRevoked bool
}

RevokeSetResult preserves durable command outcome and scoped recovery. Counts, current disposition, SubjectVersion and source SessionVersion are disclosed only after consistent committed success inside original authority/freshness deadlines. SubjectVersion remains the user's current CAS version, not a new epoch. SessionVersion is the source successor, even when it is tombstoned. A survivor retains its original bearer, expiry and authentication timestamps; HTTP clears only the selected transport when CurrentSessionRevoked is true. Retain recovery scope after Unknown/InProgress; do not issue a replacement.

func (RevokeSetResult) Format

func (RevokeSetResult) Format(s fmt.State, _ rune)

Format redacts correlated durable metadata.

func (RevokeSetResult) MarshalJSON

func (RevokeSetResult) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit output; HTTP owns explicit authorized DTOs.

type RotationCommandSpec

type RotationCommandSpec struct {
	Binding           identity.CommandBinding
	Source, Successor Session
}

RotationCommandSpec fixes an original record and one exact successor. Only lookup digest, synchronizer state, activity and session version may change. Family, owner, authentication, remember policy and all other authority are preserved. These are structural projections, never proof of authentication or commitment.

type RotationConfig

type RotationConfig struct {
	PolicyID        string
	PolicyVersion   uint64
	MaximumDuration time.Duration
	LookupKey       DigestKey
	TokenSize       int
	Cookie          CookiePolicy
}

RotationConfig selects explicit self-service policy, a 1ms..30s call budget, 32..64 token bytes, a lookup key retained by the exact reader, and secure host cookie policy. The original transport is preserved: bearer results contain no cookie. Configuration is frozen; borrowed dependencies must outlive calls.

func (RotationConfig) Format

func (RotationConfig) Format(s fmt.State, _ rune)

Format redacts policy/key configuration.

func (RotationConfig) MarshalJSON

func (RotationConfig) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit configuration serialization.

type RotationExecution

type RotationExecution struct {
	Receipt  identity.CommandResult
	Session  Session
	Replayed bool
}

RotationExecution is a durable receipt and exact historical successor. Session is absent on noncommits. Replayed forbids credential delivery. If a known commit's ancillary result read fails, Session is absent with an error; the exact committed receipt remains valid, without manufactured metadata.

func (RotationExecution) Format

func (RotationExecution) Format(s fmt.State, _ rune)

Format redacts historical receipt and successor.

func (RotationExecution) MarshalJSON

func (RotationExecution) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit historical linkage serialization.

type RotationExecutor

type RotationExecutor interface {
	ExecuteRotation(context.Context, RotationRequest) (RotationExecution, error)
	RecoverRotation(context.Context, RotationRequest) (RotationExecution, error)
}

RotationExecutor is implemented by the owned durable adapter, not an application workflow or second journal. It preserves original same-reader custody and deadlines, authorizes current policy and compares current owners inside atomic digest retirement/successor/audit/lifecycle/command effects. ExecuteRotation returns Replayed for historical results. RecoverRotation authorizes current exact result access and observes the original command; it never executes or reveals. Methods are concurrent-safe and must honor ctx.

type RotationRequest

type RotationRequest struct {
	// contains filtered or unexported fields
}

RotationRequest retains the exact command and original opaque same-reader caller/transport admission. Zero is invalid; copies never renew its deadline. No credential or caller-built principal can substitute this custody.

func (RotationRequest) Command

func (r RotationRequest) Command() (SessionCommand, bool)

Command returns the exact structural intent, never private caller authority.

func (RotationRequest) Format

func (RotationRequest) Format(s fmt.State, _ rune)

Format redacts source, successor and admission linkage.

func (RotationRequest) MarshalJSON

func (RotationRequest) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit request serialization.

func (RotationRequest) MarshalText

func (RotationRequest) MarshalText() ([]byte, error)

MarshalText rejects implicit text/map-key disclosure.

func (RotationRequest) Transport

func (r RotationRequest) Transport() CredentialKind

Transport returns the original admitted credential transport, never a caller override or permission to change cookie/header profile. Zero returns zero.

func (RotationRequest) ValidUntil

func (r RotationRequest) ValidUntil() time.Time

ValidUntil preserves the original exclusive source admission deadline.

func (RotationRequest) Validate

func (r RotationRequest) Validate(s *SessionService, now time.Time) error

Validate checks original private caller custody against the trusted service and current time before reservation and commit. The owner must additionally compare all current primary authorities; this does not renew or replace them.

type RotationResult

type RotationResult struct {
	CommandID     identity.CommandID
	CommitOutcome identity.CommitOutcome
	RetryAfter    time.Duration
	Recovery      identity.RecoveryQuery
	Session       Session
	Replayed      bool
	Transport     CredentialKind
	Token         Token
	Cookie        http.Cookie
}

RotationResult retains exact durable outcome/recovery and historical successor. Token is present only after a new error-free commit within original caller/context/lifetime bounds; its copies share reveal-once custody. Cookie Value is empty, and bearer transport never emits cookie attributes. This result cannot authenticate or renew authority by itself.

func (RotationResult) Format

func (RotationResult) Format(s fmt.State, _ rune)

Format redacts historical scope and successor delivery metadata.

func (RotationResult) MarshalJSON

func (RotationResult) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit delivery serialization.

type ServiceConfig

type ServiceConfig struct {
	Profile                           StorageProfile
	Audience                          string
	Clock                             IssuerClock
	MaximumDuration, ClockUncertainty time.Duration
	LookupKeys                        []DigestKey
}

ServiceConfig selects stateful opaque validation only. Profile must explicitly be StorageStatefulOpaque; other profiles fail rather than emulate revocation. LookupKeys has 1..4 independent retained keys with distinct positive versions. Audience is 1..256 visible ASCII bytes. MaximumDuration is 1ms..5s and ClockUncertainty is 1ms..5s; their sum must fit the shared-issuer 10s budget. Clock is trusted, nonblocking and concurrency-safe. All dependencies remain borrowed and must outlive calls; construction copies key selection without IO.

func (ServiceConfig) Format

func (ServiceConfig) Format(s fmt.State, _ rune)

Format redacts runtime key/dependency configuration.

func (ServiceConfig) MarshalJSON

func (ServiceConfig) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit configuration export.

type Session

type Session struct {
	// contains filtered or unexported fields
}

Session owns immutable structural session state, safe to copy concurrently. Zero is invalid. NewSession reconstructs trusted storage projections; it does not issue a session. An attacker can construct structurally valid projections, so neither this value nor Lifetime authorizes credential acceptance. Primary adapters own active status, exact scope derivation, proof validation and live authority comparisons, including original bounded validity evidence.

func ContinuePasswordSession

func ContinuePasswordSession(source Session, c CredentialContinuationSpec) (Session, error)

ContinuePasswordSession structurally continues an exact password session over one credential successor without renewing authentication, activity, lifetime, assurance, remember policy, lookup, session/family versions or CSRF custody. The credential-authority dimension alone advances; user authority is distinct from the password command's user aggregate version. Both predecessors must match exactly and admit uint64 successors. This mapping performs no IO and grants no authority. The owning transaction must independently deny expired, revoked or otherwise stale rows and preserve every unrelated current owner.

func NewContinuedPasswordSession

func NewContinuedPasswordSession(spec SessionSpec, csrf CSRFState, c CredentialContinuationSpec) (Session, error)

NewContinuedPasswordSession reconstructs a complete trusted continued record. AuthenticationMetadata retains original login provenance, including original credential version and proof times. EffectiveCredentialVersion is its separate current linkage. Persist CredentialContinuation with Bindings and CSRFState; losing it is not equivalent serialization. Only verified password provenance is supported here; OTP/anonymous/provider histories are different profiles. Reconstruction certifies neither commitment nor current primary authority. Zero CSRF means explicitly tokenless; nonzero state must bind this session.

func NewSession

func NewSession(s SessionSpec) (Session, error)

NewSession validates and freezes a complete record without IO or callbacks. Authentication proof expiry is historical metadata here; admission uses the issue command's separate temporal check. It rejects activity outside original absolute lifetime and mismatched record/family versions, returning only the redacted ErrInvalidSession. No token is created, revealed or persisted.

func NewSessionWithCSRF

func NewSessionWithCSRF(spec SessionSpec, state CSRFState) (Session, error)

NewSessionWithCSRF freezes a base record and exact synchronizer state without changing SessionSpec's compatibility shape. The state must bind its exact tenant, session and positive version; zero is invalid. Use NewSession for explicitly tokenless legacy/bearer profiles. This grants no authentication, primary liveness or storage/transaction guarantee. Adapters must persist both Bindings and CSRFState; lossy reconstruction is not an equivalent session.

func NewSessionWithMagicLink(s SessionSpec, p MagicLinkAuthentication) (Session, error)

NewSessionWithMagicLink reconstructs complete magic-link session metadata without a synchronizer. Kind must be AuthenticationMagicLink; legacy proof and credential fields must be zero. Issuance precedes original admission expiry, but later session activity uses Remember and never renews provenance. Unsupported organization/factor/passkey projections fail closed. This is reconstruction only, not authentication or permission to issue a session.

func NewSessionWithMagicLinkAndCSRF

func NewSessionWithMagicLinkAndCSRF(s SessionSpec, p MagicLinkAuthentication, c CSRFState) (Session, error)

NewSessionWithMagicLinkAndCSRF retains both complete trusted projections. CSRF must bind the exact tenant/session/version; neither value proves current authority. No token, transaction, IO or consumption is created here.

func NewSessionWithMagicLinkMFA

func NewSessionWithMagicLinkMFA(s SessionSpec, primary MagicLinkAuthentication, factor MFAAuthentication) (Session, error)

NewSessionWithMagicLinkMFA reconstructs complete primary and factor metadata. Original primary time controls freshness; MFA cannot substitute its admission or upgrade Remember. Factor authority is required and must match this exact generation. Organization/passkey variants are not supported by this profile. This structural constructor grants no authentication or storage authority.

func NewSessionWithMagicLinkMFAAndCSRF

func NewSessionWithMagicLinkMFAAndCSRF(s SessionSpec, primary MagicLinkAuthentication, factor MFAAuthentication, csrf CSRFState) (Session, error)

NewSessionWithMagicLinkMFAAndCSRF preserves all three trusted projections. Synchronizer state must bind the exact tenant/session/version. No token, transaction, factor verification or authority refresh occurs here.

func NewSessionWithOTP

func NewSessionWithOTP(spec SessionSpec, metadata OTPAuthentication) (Session, error)

NewSessionWithOTP reconstructs an OTP record with no synchronizer state. Authentication.Kind must be AuthenticationOTP and all legacy proof/credential fields zero. Issuance must precede original continuation expiry; later session activity is governed by Remember, never by renewing authentication. Factor, passkey and organization profiles currently fail closed, not silently omitted. This structural constructor grants no issuance or current acceptance authority.

func NewSessionWithOTPAndCSRF

func NewSessionWithOTPAndCSRF(spec SessionSpec, metadata OTPAuthentication, state CSRFState) (Session, error)

NewSessionWithOTPAndCSRF retains both explicit storage projections. The CSRF state must bind the exact tenant/session/version. Neither projection alone proves current authority; no code, token or transaction is created here.

func NewSessionWithPasskeyMFA

func NewSessionWithPasskeyMFA(s SessionSpec, factor MFAAuthentication) (Session, error)

NewSessionWithPasskeyMFA reconstructs trusted historical UV-passkey and independently completed factor metadata. It preserves the original credential, primary time/expiry, passkey/factor epochs and resolved remember policy. The non-final primary purpose must be PasskeyMFAPrimaryPurpose. No proof, factor verification, current authority, token or persistence is created here. The native completion must authenticate both original owners in its sole Work.

func NewSessionWithPasskeyMFAAndCSRF

func NewSessionWithPasskeyMFAAndCSRF(s SessionSpec, factor MFAAuthentication, csrf CSRFState) (Session, error)

NewSessionWithPasskeyMFAAndCSRF also retains the exact synchronizer state bound to this tenant/session/version. Reconstruction creates no credential.

func NewSessionWithPasswordMFA

func NewSessionWithPasswordMFA(s SessionSpec, factor MFAAuthentication) (Session, error)

NewSessionWithPasswordMFA reconstructs original password credential metadata and its completed second factor. The primary projection remains single-factor historical evidence: this constructor neither upgrades it nor authenticates it. Its purpose must be PasswordMFAPrimaryPurpose rather than session-issue. Its ID must name the factor's original PrimaryCommandID, its credential ID/version must be retained, and its original time and expiry bound the factor. Factor authority and the unchanged resolved remember policy are required. Native issuance must independently validate the committed password primary, current credential, browser, child and factor in the protected transaction. Organization and passkey variants fail closed. No IO or issuance occurs.

func NewSessionWithPasswordMFAAndCSRF

func NewSessionWithPasswordMFAAndCSRF(s SessionSpec, factor MFAAuthentication, csrf CSRFState) (Session, error)

NewSessionWithPasswordMFAAndCSRF also retains the exact synchronizer digest bound to this tenant/session/version. It creates no token or authority lease.

func (Session) Bindings

func (s Session) Bindings() (SessionSpec, error)

Bindings returns the original owned base projection for trusted adapters. Complete serialization/equality must also retain CSRFState and OTPAuthentication, MagicLinkAuthentication and MFAAuthentication. Bindings alone cannot reconstruct those records and deliberately produces a tokenless record for other supported variants. Scope and lookup values correlate people/activity; never log them. Returned Remember and Authority values retain immutable state, not renewed freshness.

func (Session) CSRFState

func (s Session) CSRFState() CSRFState

CSRFState returns immutable digest-only synchronizer state. Zero session and explicitly tokenless records return zero state, which denies every check. This is a structural projection, never current primary authority; do not authorize a mutation from cached or historical state. Complete storage must retain this together with Bindings, never raw CSRF or bearer credentials.

func (Session) CredentialContinuation

func (s Session) CredentialContinuation() (CredentialContinuationSpec, bool)

CredentialContinuation returns an independent scalar trusted-storage projection. False means none, including zero session. It grants no current authority and must never be used alone to accept a credential.

func (Session) EffectiveCredentialVersion

func (s Session) EffectiveCredentialVersion() uint64

EffectiveCredentialVersion is the current credential-reference linkage while AuthenticationMetadata retains original login provenance. Zero/anonymous/OTP returns zero. This structural version is not current authority evidence.

func (Session) Format

func (s Session) Format(f fmt.State, _ rune)

Format redacts identifiers, metadata and correlated lookup values.

func (Session) Lifetime

func (s Session) Lifetime(now time.Time) (Lifetime, error)

Lifetime evaluates only recorded timestamps and immutable lifetime policy. It does not check active status, proof authority, revocation, versions or a store; positive output must never be used alone to authenticate a credential.

func (Session) MFAAuthentication

func (s Session) MFAAuthentication() MFAAuthentication

MFAAuthentication returns historical factor metadata, never current proof. Complete stores, cache, equality, update and rotation must retain it together with the original primary provenance. Zero and single-factor sessions deny.

func (Session) MagicLinkAuthentication

func (s Session) MagicLinkAuthentication() MagicLinkAuthentication

MagicLinkAuthentication returns historical metadata only for magic-link sessions. Zero/other methods return zero. Store/equality/rotation must retain it with Bindings and CSRFState; it is not a reusable authentication proof.

func (Session) MarshalJSON

func (s Session) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit encoding; use explicit trusted Bindings instead.

func (Session) MarshalText

func (s Session) MarshalText() ([]byte, error)

MarshalText denies implicit encoding and map-key disclosure.

func (Session) OTPAuthentication

func (s Session) OTPAuthentication() OTPAuthentication

OTPAuthentication returns historical provenance; non-OTP and zero sessions return zero. Complete storage/equality must retain it together with Bindings and CSRFState. It is never a reusable proof or authority refresh.

type SessionCommand

type SessionCommand struct {
	// contains filtered or unexported fields
}

SessionCommand is a closed immutable native transition. Issue, rotation, one-session, family and user-owned set revocation and metadata update are distinct variants. Zero is invalid, copies are concurrency safe, and formatting/serialization cannot expose scope. Construction grants no issuance or execution authority.

func NewIssueCommand

func NewIssueCommand(b identity.CommandBinding, s Session) (SessionCommand, error)

NewIssueCommand binds one new version1 record to its exact command scope and resolved policy. Existing family version is retained, never reset. The final proof metadata must have exact session-issue purpose and be unexpired at original issuance; anonymous records remain an explicit unprivileged variant. OTP metadata cannot enter this credential-proof/anonymous issuance route; consuming OTP issuance requires its own atomically checked effect contract. This is structural/temporal preparation only. SessionIssuer must independently validate the expected authority-issued authentication/anonymous proof, current activity/vector and operation policy before any durable reservation or effect. The adapter owns atomic consumption, safe recovery and reveal-once delivery.

func NewRevokeAllCommand

func NewRevokeAllCommand(b identity.CommandBinding, caller Session, includeCurrent bool, maximum uint32) (SessionCommand, error)

NewRevokeAllCommand freezes exact self-owned inputs and explicit current disposition without IO or authority. It cannot select another user's sessions. The durable owner must retain per-session tombstones and protect a survivor's lifetime while invalidating older source-version projections. Zero is invalid.

func NewRevokeFamilyCommand

func NewRevokeFamilyCommand(b identity.CommandBinding, expected uint64) (SessionCommand, error)

NewRevokeFamilyCommand prepares an immutable exact-scope revocation. Zero and MaxUint64 versions fail rather than wrapping authority. A durable owner must authorize the operation and atomically compare current ownership/version, retain the tombstone, and commit the required audit/lifecycle/receipt. An absent, stale or already-revoked target does not permit a new transition; exact command replay belongs to the sole durable coordinator.

func NewRevokeOneCommand

func NewRevokeOneCommand(b identity.CommandBinding, s Session) (SessionCommand, error)

NewRevokeOneCommand binds an immutable original target record to the exact tenant, effective user and session. Its version must have a representable successor. Structural records, including expired records, are not admission: the owning service must independently authenticate the caller and authorize the target, then recheck all applicable current authorities atomically with revocation, audit, lifecycle and retained command recovery. No fresh-login requirement is added here. Public logout idempotency belongs to the service; neither a missing nor an already-revoked row permits a second transition.

func NewRevokeOtherCommand

func NewRevokeOtherCommand(b identity.CommandBinding, caller Session, maximum uint32) (SessionCommand, error)

NewRevokeOtherCommand freezes exact self-owned inputs without IO or authority. Current custody/freshness, authorization, bounded atomic execution and recovery belong to the configured service and durable owner. Zero values are invalid.

func NewRotateCommand

func NewRotateCommand(b identity.CommandBinding, source, successor Session) (SessionCommand, error)

NewRotateCommand freezes an exact self-owned single-version transition. The source must be live and refresh-due at the successor's accepted-activity time; a representable version successor and a different nonzero digest are required. It grants no authority. The owned executor must preserve original opaque admission, compare all current owners, atomically retire the old digest without a reuse window, persist the successor/audit/lifecycle/receipt, and handle retired-token reuse through the same family/command owner.

func NewUpdateCommand

func NewUpdateCommand(b identity.CommandBinding, source Session, label string) (SessionCommand, error)

NewUpdateCommand prepares the exact self-owned source-version transition. Binding.RecordID must be the source session, with the effective user also the actor. A checked version successor invalidates old session projections; lookup, activity, authentication, remember policy and all unrelated authority remain unchanged. It performs no IO and cannot authenticate a caller. The separately bound synchronizer state is cleared, never carried into the new version or replaced without original credential-delivery ownership. Protected cookie work must deny until an owned authorized flow issues replacement state. source's version is the expected CAS; overflow, malformed labels, foreign scope and zero fail with ErrInvalidSessionCommand before copying input.

func (SessionCommand) Format

func (c SessionCommand) Format(f fmt.State, _ rune)

Format redacts all command scope and metadata.

func (SessionCommand) Issue

func (c SessionCommand) Issue() (IssueCommandSpec, bool)

Issue returns a caller-owned scalar projection, not an admitted transaction. False means zero/unsupported; no partially prepared command escapes.

func (SessionCommand) MarshalJSON

func (c SessionCommand) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit command serialization.

func (SessionCommand) MarshalText

func (c SessionCommand) MarshalText() ([]byte, error)

MarshalText denies implicit command serialization and map-key disclosure.

func (SessionCommand) RevokeFamily

func (c SessionCommand) RevokeFamily() (RevokeFamilyCommandSpec, bool)

RevokeFamily returns an owned scalar native projection. False means another command variant or zero. This projection is preparation, never proof that revocation committed or that a caller can inspect or manage another account.

func (SessionCommand) RevokeOne

func (c SessionCommand) RevokeOne() (RevokeOneCommandSpec, bool)

RevokeOne returns a caller-owned scalar projection preserving the original immutable session. False means zero or another command variant. It is never evidence that revocation committed or that the caller owns the target.

func (SessionCommand) RevokeSet

func (c SessionCommand) RevokeSet() (RevokeSetCommandSpec, bool)

RevokeSet returns a scalar caller-owned projection; copies cannot change the original command. False means zero or another closed variant. The projection loses private caller admission and never grants permission or proves a commit.

func (SessionCommand) Rotation

func (c SessionCommand) Rotation() (RotationCommandSpec, bool)

Rotation returns the exact immutable structural projection. False means a zero or different variant; this value loses private authenticated custody.

func (SessionCommand) Update

func (c SessionCommand) Update() (UpdateCommandSpec, bool)

Update returns a scalar caller-owned projection; changing it cannot mutate the command. Zero or another variant returns false. Source and Successor remain immutable records, not evidence of active state or caller admission.

func (SessionCommand) ValidateIssueAt

func (c SessionCommand) ValidateIssueAt(now time.Time) error

ValidateIssueAt rechecks only immutable temporal metadata at authoritative now, including exact proof purpose/audience, exclusive proof/session expiry and original authentication freshness. It authenticates NOTHING: private proof ownership, activity, policy and every applicable current authority must be established separately at reservation/apply under the sole coordinator. Anonymous metadata is never upgraded to verified assurance. No IO runs.

func (SessionCommand) ValidateRotationAt

func (c SessionCommand) ValidateRotationAt(now time.Time) error

ValidateRotationAt rechecks original exclusive lifetime and rejects a future prepared activity time. It performs no IO and neither authenticates a source nor refreshes current authority; the original admission deadline also applies.

func (SessionCommand) ValidateUpdateAt

func (c SessionCommand) ValidateUpdateAt(now time.Time) error

ValidateUpdateAt checks only original session lifetime at trusted now. Ordinary display metadata does not require fresh login and never refreshes accepted activity. Current authorization and every authority comparison must still be established by the executor, with original private caller custody.

type SessionEnricher

type SessionEnricher interface {
	Enrich(context.Context, Session, EnrichmentSchema) (Enrichment, error)
}

SessionEnricher supplies a bounded deployment callback, not a domain store. Enrich must honor ctx and return promptly when cancelled. Implementations must be concurrency-safe and keep returned values stable until return. Session is structural source data, not proof; do not use it to grant access. Callbacks run without session/store locks and cannot replace session state.

type SessionIssuer

type SessionIssuer struct {
	// contains filtered or unexported fields
}

SessionIssuer owns original-token preparation and commit-gated delivery. It holds no durable store, command cache, locks, goroutines or transaction handle. Dependencies remain borrowed and must outlive calls. Copies of preparations share one execution claim; unrelated preparations can execute concurrently.

func NewAnonymousSessionIssuer

func NewAnonymousSessionIssuer(executor IssueExecutor, config IssuerConfig) (*SessionIssuer, error)

NewAnonymousSessionIssuer selects explicitly unprivileged issuance. Authority must be nil; other bounds match NewSessionIssuer. The native anonymous owner must admit original action-specific risk and create the actual anonymous identity/lifecycle with session, audit and outbox in one protected transaction. Preparation is not authentication, persistence or permission to create a user. Dependencies are borrowed, bounded and concurrent-safe; no resource is opened.

func NewAnonymousSessionIssuerWithCSRF

func NewAnonymousSessionIssuerWithCSRF(executor IssueExecutor, config IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewAnonymousSessionIssuerWithCSRF also prepares original synchronizer custody. The native effect must retain the entire session record; CSRF and bearer delivery remain gated by the same exact new committed result.

func NewAnonymousUpgradeSessionIssuer

func NewAnonymousUpgradeSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewAnonymousUpgradeSessionIssuer selects prospective verified-session replacement in the native anonymous upgrade transaction. Authority must be nil: original target authentication and current action-bound password proof are checked by the real native executor, not a caller-authored projection. It must atomically consume the transition, revoke guest sessions and persist exactly this permanent session with merge, audit and outbox. This constructor provides no authentication, store, transaction or background resource.

func NewAnonymousUpgradeSessionIssuerWithCSRF

func NewAnonymousUpgradeSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewAnonymousUpgradeSessionIssuerWithCSRF also prepares a synchronizer token with the existing exact known-new-commit delivery gate. The native session owner must persist its separate state alongside the complete session.

func NewEmailVerificationSessionIssuer

func NewEmailVerificationSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewEmailVerificationSessionIssuer selects signin after a separately committed registration verification. It reuses the email-grant authentication record (AuthenticationMagicLink), not a password proof or ordinary magic-link command. The native executor must authenticate original signup/browser custody, require that exact committed verification, and fence current account, identifier, authorization, risk and factor policy while committing the session and audit. It must never issue from scanner inspection, replay or unknown verification. Configuration/resource bounds match NewMagicLinkSessionIssuer; Authority must be nil. The issuer owns no transaction, durable retry state or goroutine.

func NewEmailVerificationSessionIssuerWithCSRF

func NewEmailVerificationSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewEmailVerificationSessionIssuerWithCSRF also retains the fresh synchronizer with the exact new session. Neither token is available before a new error-free committed issuance; metadata-only recovery cannot generate or redeliver them.

func NewMFAMagicLinkSessionIssuer

func NewMFAMagicLinkSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewMFAMagicLinkSessionIssuer selects native TOTP or recovery-code completion of an original magic-link primary. Authority must be nil; projected metadata is not a new credential-issued proof. The native executor must verify original child, primary, browser and factor authority and commit factor replay, continuation, child use, session and audit/lifecycle in the same authoritative transaction. This constructor performs no IO or factor authentication.

func NewMFAMagicLinkSessionIssuerWithCSRF

func NewMFAMagicLinkSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewMFAMagicLinkSessionIssuerWithCSRF retains synchronizer custody in the exact completion transaction. Only a new exact committed Issue can disclose either token; replay, denial and ambiguous outcomes disclose neither.

func NewMFAPasskeySessionIssuer

func NewMFAPasskeySessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewMFAPasskeySessionIssuer selects completion of an original committed UV passkey primary with an independent enrolled factor. Authority must be nil. The native executor must authenticate the original assertion, credential, browser, child and actual factor, committing replay/continuation/session effects together. Construction and structural preparation grant no authority.

func NewMFAPasskeySessionIssuerWithCSRF

func NewMFAPasskeySessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewMFAPasskeySessionIssuerWithCSRF retains the original synchronizer until an exact fresh acknowledged commit. Replay, recovery, ambiguity and failure disclose neither it nor the prepared bearer.

func NewMFAPasswordSessionIssuer

func NewMFAPasswordSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewMFAPasswordSessionIssuer selects completion of an original committed password primary, not a magic-link grant or newly authenticated opaque proof. Authority must be nil. The native executor must fence the original signed password evidence and current credential, browser, child and factor, committing child use, factor replay, continuation completion, session and audit/lifecycle atomically. This constructor performs no IO or authentication.

func NewMFAPasswordSessionIssuerWithCSRF

func NewMFAPasswordSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewMFAPasswordSessionIssuerWithCSRF prepares original synchronizer custody together with password-primary completion. Only a fresh exact known committed Issue may reveal tokens; replay, unknown outcomes and recovery reveal none.

func NewMFAVerificationSessionIssuer

func NewMFAVerificationSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewMFAVerificationSessionIssuer selects TOTP completion of a separately committed registration-verification primary. This is not magic-link consume or password comparison. The native executor must authenticate the original confirmation, signup/browser, child and actual factor under the sole Work. Email-possession metadata retains its shared storage shape and original time. No IO, proof creation or factor authentication occurs during construction.

func NewMFAVerificationSessionIssuerWithCSRF

func NewMFAVerificationSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewMFAVerificationSessionIssuerWithCSRF retains synchronizer custody until one fresh exact committed issue. Replay, denial, recovery and unknown outcomes disclose neither credential. Verification primary does not enable other origins.

func NewMagicLinkSessionIssuer

func NewMagicLinkSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewMagicLinkSessionIssuer selects native consuming email-grant issuance. Authority must be nil: a prospective session is not a credential-issued proof. The owned native executor must verify the original opaque grant and browser custody, current recipient/factor/risk policy, and atomically consume both grant and flow with this exact session and required audit/lifecycle. All standard issuer resource, timeout, cookie and reveal-once bounds apply.

func NewMagicLinkSessionIssuerWithCSRF

func NewMagicLinkSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewMagicLinkSessionIssuerWithCSRF retains synchronizer custody in the same consuming session. CSRFToken remains unavailable until an exact new committed Issue; replay, failure and ambiguous outcomes cannot repeat disclosure.

func NewOTPSessionIssuer

func NewOTPSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewOTPSessionIssuer selects consuming OTP issuance, without fabricating an authority-issued credential proof. Authority must be nil; other configuration bounds are identical to NewSessionIssuer. The owned executor must authenticate the original pre-auth possession and consume OTP atomically with this exact session, current authority, audit/outbox and receipt. Structural preparation alone authenticates nothing. This profile does not enable credential Prepare.

func NewOTPSessionIssuerWithCSRF

func NewOTPSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewOTPSessionIssuerWithCSRF also generates the original synchronizer custody. The executor must persist its complete state in the same consuming commit. CSRF delivery remains gated by the existing PreparedIssuance.CSRFToken rules.

func NewPasskeySessionIssuer

func NewPasskeySessionIssuer(executor IssueExecutor, config IssuerConfig) (*SessionIssuer, error)

NewPasskeySessionIssuer selects prospective identified UV-passkey issuance. Authority must be nil: the owned native executor must verify the genuine opaque WebAuthn transition and current identity/passkey/factor/risk authority, then commit ceremony consumption, counters and session effects in one Work. Structural preparation is not authentication. Dependencies retain IssuerConfig lifetime and concurrency semantics; construction performs no IO.

func NewPasskeySessionIssuerWithCSRF

func NewPasskeySessionIssuerWithCSRF(executor IssueExecutor, config IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewPasskeySessionIssuerWithCSRF retains synchronizer custody until the exact new committed assertion/session result. Replay, recovery and unknown outcomes disclose neither token; native storage must preserve the complete CSRF state.

func NewPasskeySignupSessionIssuer

func NewPasskeySignupSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewPasskeySignupSessionIssuer explicitly selects prospective passkey-only signup, not existing-account assertion issuance. Authority must be nil. The owned native executor must verify real WebAuthn, admit original pre-auth/risk, and commit account/credential/known-empty factor/policy/session effects and required lifecycles in the original transaction. Preparation grants none of those permissions. Borrowed dependencies retain IssuerConfig's bounded, concurrency-safe lifetime; construction performs no IO or background work.

func NewPasskeySignupSessionIssuerWithCSRF

func NewPasskeySignupSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewPasskeySignupSessionIssuerWithCSRF retains the original synchronizer token until acknowledged new commit. Replay/unknown/recovery cannot reveal either credential; the native executor must persist the full original CSRF state.

func NewPasswordBearerSessionIssuer

func NewPasswordBearerSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewPasswordBearerSessionIssuer selects prospective native password issuance without cookie attributes or synchronizer state. Cookie must be zero and Authority nil; other bounds and exact commit-gated delivery match NewPasswordSessionIssuer. The owned password executor still proves comparison, current authority and all atomic effects. This is not a cookie-to-bearer conversion: existing sessions and browser issuance are unchanged.

func NewPasswordSessionIssuer

func NewPasswordSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewPasswordSessionIssuer selects prospective native password issuance. Authority must be nil: a committed-original proof cannot admit the same transaction that creates that original. Other bounds match NewSessionIssuer. The owned password executor must perform actual comparison and current policy fences, then persist signed original authentication, required risk/pre-auth consumption, any upgrade, session and audit/outbox in one coordinator Work. Preparation is not authentication and does not enable proof or OTP issuance.

func NewPasswordSessionIssuerWithCSRF

func NewPasswordSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewPasswordSessionIssuerWithCSRF also prepares original synchronizer custody, which must be persisted in the same login commit and delivered only through PreparedIssuance.CSRFToken after a fresh known success.

func NewPasswordSignupSessionIssuer

func NewPasswordSignupSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewPasswordSignupSessionIssuer selects prospective native registration issuance without synchronizer custody. Authority must be nil; configuration bounds match NewPasswordSessionIssuer. Native registration owns policy-complete authentication and the atomic effects described by PrepareSignup. This profile enables neither proof issuance nor password signin. It owns no goroutines, stores or transactions, and borrows the concurrency-safe bounded executor.

func NewPasswordSignupSessionIssuerWithCSRF

func NewPasswordSignupSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewPasswordSignupSessionIssuerWithCSRF selects prospective native registration issuance with original synchronizer custody. Authority must be nil; configuration bounds match NewPasswordSessionIssuerWithCSRF. Preparation is not authentication. The password owner must establish that verification and MFA policy are complete, reserve original pre-auth/risk custody and commit registration, password material, session and required audit/outbox in the same coordinator transaction. This issuer cannot grant that policy admission or persist those effects itself.

func NewSessionIssuer

func NewSessionIssuer(executor IssueExecutor, c IssuerConfig) (*SessionIssuer, error)

NewSessionIssuer validates and freezes trusted composition without IO. Use the owned PostgreSQL execution service, not a consumer-written domain store.

func NewSessionIssuerWithCSRF

func NewSessionIssuerWithCSRF(executor IssueExecutor, c IssuerConfig, key CSRFKey) (*SessionIssuer, error)

NewSessionIssuerWithCSRF selects the synchronizer profile with a dedicated current issuance key. All original configuration/receipt/lifetime rules still apply. The owned executor MUST persist the complete Session, including its separate CSRFState, in the issuance transaction; legacy lossy adapters cannot be composed with this profile. Retain named verification keys for overlap. Original CSRF delivery is retrieved from PreparedIssuance.CSRFToken only after successful new Issue. No public configuration/result struct shape changes.

func (*SessionIssuer) BindAnonymous

func (s *SessionIssuer) BindAnonymous(prepared PreparedIssuance, command identity.Command) (PreparedIssuance, error)

BindAnonymous retains the exact original native command under one shared bind claim. Invalid inputs do not claim the preparation. The native executor must compare every prepared session field and actual kernel creation in its original Work; this structural bind grants neither risk nor user authority. Verified credentials, pre-auth cookies and submitted codes cannot be silently reinterpreted as an anonymous request. No IO or token generation occurs.

func (*SessionIssuer) BindAnonymousUpgrade

func (s *SessionIssuer) BindAnonymousUpgrade(p PreparedIssuance, command identity.Command) (PreparedIssuance, error)

BindAnonymousUpgrade freezes the exact target-bearer command and guest version under the preparation's shared one-bind claim. It proves neither bearer possession nor signed reauthentication. The native executor must validate all target/guest/merge/risk/capability and prospective-session inputs in sole Work. Other profiles, substituted versions and scalar bearer reconstructions deny.

func (*SessionIssuer) BindEmailVerification

func (s *SessionIssuer) BindEmailVerification(p PreparedIssuance, command identity.Command) (PreparedIssuance, error)

BindEmailVerification lends the exact prepared session and original signup browser cookie only to its selected native executor. Copies share one bind and one attempt. Cookie presence is structural, not possession authentication; the native owner must validate the original digest and committed email grant. Ordinary magic-link, password, OTP and proof routes remain disjoint. Do not persist this borrowed input or use it as a restart/recovery credential.

func (*SessionIssuer) BindMFA

BindMFA retains the exact original method-specific opaque code/pre-auth command. Scalar projections cannot replace it. Copies share one atomic bind claim; invalid input does not spend it. Native execution must independently verify the code and original child and compare the exhaustive Session mapping. This binding grants no authentication, transaction, reservation or session permission.

BindMagicLink freezes the exact consuming command and original pre-auth custody. Copies share one atomic bind claim. Invalid inputs do not claim it. The native executor must independently authenticate the original proof and exhaustively compare the prepared Session mapping before protected mutation; this binding establishes neither possession nor permission. Request and legacy proof routes remain unavailable for this ephemeral consuming profile.

func (*SessionIssuer) BindOTP

BindOTP freezes the exact native consuming command before the authoritative adapter fingerprints or reserves it. It requires original opaque code and pre-auth custody, the exact prepared binding and the closed signin descriptor. Native parsing must exhaustively bind all session/OTP/CSRF fields and original recipient/remember policy inside the protected transaction. This operation grants no authentication or execution authority and regenerates no credential. Copies share one atomic bind claim: invalid inputs do not claim it; after a successful bind every further bind returns ErrIssuanceAlreadyBound. Keep the returned preparation for one Issue, not code-bearing restart recovery.

func (*SessionIssuer) BindPasskey

func (s *SessionIssuer) BindPasskey(prepared PreparedIssuance, command identity.Command) (PreparedIssuance, error)

BindPasskey freezes the native owner's exact original command under a shared once-only bind claim. Binding grants no authentication: the owned executor must match the whole prepared Session and opaque assertion before committing. Other secret-bearing method commands cannot be reinterpreted as assertions. Recovery uses separate native metadata correlation, not this preparation.

func (*SessionIssuer) BindPasskeySignup

func (s *SessionIssuer) BindPasskeySignup(p PreparedIssuance, c identity.Command) (PreparedIssuance, error)

BindPasskeySignup seals the exact original signup command under the shared one-bind claim. Native execution must compare the entire prepared session and actual opaque registration, not trust structural intent as authentication. Other issuance profiles deny. Recovery uses separate native metadata custody; this preparation never grants a right to execute again or reveal again.

func (*SessionIssuer) BindPassword

func (s *SessionIssuer) BindPassword(p PreparedIssuance, command identity.Command) (PreparedIssuance, error)

BindPassword retains the exact native password/pre-auth command under a shared once-only claim. Invalid inputs do not claim it. Native mapping must bind every prepared session/authority/remember/CSRF field and original pre-auth intent; this structural operation verifies no password or flow possession. Copies retain the caller-owned Secret lifetime. Keep the returned preparation for one Issue; recovery must use separate password/cookie-free native correlation.

func (*SessionIssuer) BindSignup

BindSignup retains the exact paired prepared-verifier/pre-auth command under one shared bind claim. Invalid input does not claim the preparation. The native owner must bind all prepared session fields into keyed intent and admit their provenance in its protected transaction; this structural check grants neither hash-policy approval nor cookie possession. Copies share one issuance attempt. Keep verifier/cookie custody ephemeral; recovery uses separate safe correlation.

func (*SessionIssuer) Issue

func (s *SessionIssuer) Issue(ctx context.Context, p PreparedIssuance) (out IssueResult, err error)

Issue makes one bounded durable attempt using the original preparation. Before executor entry a failure observes no outcome. After entry, panic or malformed receipt is Unknown, never inferred rollback. Valid exact receipts retain their outcome even alongside cancellation/error; those paths disclose no bearer. No dependency error text escapes. The executor, not this in-memory claim, owns durable idempotency and atomic proof/session/audit finalization.

func (*SessionIssuer) Prepare

Prepare validates the resolved policy, complete original authentication and vector before generating a token. spec.Lookup must be zero: only this issuer sets the exact tenant/key-bound digest. All other input, including command ID, family lifetime, proof/credential versions and RememberPolicy, is retained. It performs no durable IO or proof consumption and grants no authority. A successful preparation must be retained unchanged through Issue/recovery.

func (*SessionIssuer) PrepareAnonymous

func (s *SessionIssuer) PrepareAnonymous(binding identity.CommandBinding, spec SessionSpec) (out PreparedIssuance, err error)

PrepareAnonymous freezes a prospective new anonymous session before complete native command fingerprinting. Lookup must be zero; session/family versions are one, accepted activity and AnonymousAt equal original issuance. Selected organization/factor/passkey authority is forbidden. Original remember policy is unchanged. Native expiry/current authority remain protected-owner checks. Map the full tokenless Session projection into intent, then BindAnonymous; do not regenerate a preparation to retry an unknown result.

func (*SessionIssuer) PrepareAnonymousUpgrade

func (s *SessionIssuer) PrepareAnonymousUpgrade(b identity.CommandBinding, spec SessionSpec, before uint64, until time.Time) (out PreparedIssuance, err error)

PrepareAnonymousUpgrade retains prospective target-session custody, exact guest lifecycle version and the earliest original exclusive admission deadline. until must be within 20s of original issuance and may never be renewed by preparation, retries or delivery. The native owner must supply the earlier bound from every contributing authoritative read, proof and source lifetime.

Only a single-factor password target without optional authority/continuation is supported. Preserve its historical authentication metadata rather than manufacturing a new signin proof or resetting authentication age. The native executor must authenticate that original target, consume fresh action-bound reauthentication and preserve the guest's resolved remember choice. Lookup must be zero, new session/family versions one and activity equal issuance. Retain this preparation, map its complete record into native intent and bind once; an unknown result must use credential-free native recovery instead.

func (*SessionIssuer) PrepareEmailVerification

func (s *SessionIssuer) PrepareEmailVerification(b identity.CommandBinding, spec SessionSpec, metadata MagicLinkAuthentication) (PreparedIssuance, error)

PrepareEmailVerification freezes original post-confirmation email-possession provenance before generating fresh token custody. The command is the closed identity.email.verification-signin v1 schema, with explicit user and the committed confirmation command as RecordID. This binds the parent transition independently of the newly allocated session ID. Remember must be recovered from the original signup intent, not resolved again. Lookup must be zero, versions initial and activity equal to issuance. This pure preparation proves no verification or current authority. The native owner must bind every session field before BindEmailVerification.

func (s *SessionIssuer) PrepareMFAMagicLink(b identity.CommandBinding, spec SessionSpec, primary MagicLinkAuthentication, metadata MFAAuthentication) (out PreparedIssuance, err error)

PrepareMFAMagicLink freezes the prospective completed session before token allocation. It does not certify factor completion: metadata is trusted intent to be checked by the native owner against original durable scope. Lookup must be zero, Version one and activity equal issuance. Primary time, factor version, original remember policy and continuation expiry are never renewed. BindMFA must freeze the same final opaque command before any reservation/execution.

func (*SessionIssuer) PrepareMFAPasskey

func (s *SessionIssuer) PrepareMFAPasskey(b identity.CommandBinding, spec SessionSpec, metadata MFAAuthentication) (PreparedIssuance, error)

PrepareMFAPasskey freezes original UV-primary and independent TOTP provenance before token allocation. Only the explicit passkey-MFA issuer admits it; no ordinary passkey/password/magic-link route is enabled. Native execution must prove the retained primary and actual factor; this is only prospective intent.

func (*SessionIssuer) PrepareMFAPassword

func (s *SessionIssuer) PrepareMFAPassword(b identity.CommandBinding, spec SessionSpec, metadata MFAAuthentication) (out PreparedIssuance, err error)

PrepareMFAPassword freezes original password and factor provenance before allocation. It is available only on the explicit password-MFA issuer; the single-factor password and magic-link issuers cannot enter this profile. Lookup must be zero, Version one and activity equal issuance. The original password time/expiry and resolved remember policy cannot be renewed. BindMFA must retain the final opaque code/browser command before protected execution.

func (*SessionIssuer) PrepareMFAVerification

func (s *SessionIssuer) PrepareMFAVerification(b identity.CommandBinding, spec SessionSpec, primary MagicLinkAuthentication, metadata MFAAuthentication) (PreparedIssuance, error)

PrepareMFAVerification freezes original email-possession and TOTP provenance only on the explicit verification-MFA issuer. Native execution must prove the separate verification parent; structural metadata is never authentication. Freshness, Remember and absolute primary/continuation deadlines cannot renew.

func (s *SessionIssuer) PrepareMagicLink(b identity.CommandBinding, spec SessionSpec, metadata MagicLinkAuthentication) (out PreparedIssuance, err error)

PrepareMagicLink allocates original token custody only after freezing the complete prospective session and historical grant provenance. It performs no IO, proof verification, consumption or current-policy admission. Lookup must be zero, Version1, activity equal issuance, and anonymous command scope exact. The native owner must map Session into its final command and BindMagicLink once before reservation. Original grant expiry and remember policy are never refreshed. Unsupported organization/factor/passkey profiles deny.

func (*SessionIssuer) PrepareOTP

func (s *SessionIssuer) PrepareOTP(b identity.CommandBinding, spec SessionSpec, metadata OTPAuthentication) (out PreparedIssuance, err error)

PrepareOTP freezes original token/session custody before the native adapter binds its complete consuming intent. Lookup must be zero; Version must be1 and accepted activity must equal original issuance. Metadata is prospective, not proof that a code was checked. The operation is the closed record-free v1 identity/otp signin schema or the separately owned identity.phone.signin schema with phone-only metadata; user scope must match the final user, or anonymous scope must remain explicitly anonymous. The native effect must independently bind that anonymous flow to its original eligible recipient, not caller input. Actor is separate from the final user. Remember and authority are never reset. No IO or reservation occurs. Issue rejects this unbound preparation; use its Session projection to map the complete native intent, then BindOTP once.

func (*SessionIssuer) PreparePasskey

func (s *SessionIssuer) PreparePasskey(binding identity.CommandBinding, spec SessionSpec) (out PreparedIssuance, err error)

PreparePasskey freezes original session/digest/remember/CSRF custody for the exact self-scoped identified assertion. Lookup must be zero; session/family versions are one and activity equals issuance. The original proof projection must retain phishing-resistant passkey provenance and original passkey and factor epochs. The native owner must prove that factor epoch is known-empty; its presence is a lifecycle fence, not a claim of completed secondary MFA. Organization and completed-MFA profiles deny rather than dropping dimensions. No cryptographic verification, reservation or authority read occurs here. Map the entire Session into the native command, then BindPasskey once.

func (*SessionIssuer) PreparePasskeySignup

func (s *SessionIssuer) PreparePasskeySignup(b identity.CommandBinding, spec SessionSpec) (PreparedIssuance, error)

PreparePasskeySignup freezes an initial prospective session and private token for the original anonymous signup command. RecordID names its new credential, not the separately allocated session. No durable user, authentication or authority is inferred. Initial account/credential/policy/factor/passkey epochs are one; original observed deployment epochs, remember and proof expiry stay unchanged. Map the complete session into native intent before binding once.

func (*SessionIssuer) PreparePassword

func (s *SessionIssuer) PreparePassword(b identity.CommandBinding, spec SessionSpec) (out PreparedIssuance, err error)

PreparePassword freezes original bearer/session custody before native intent mapping. Lookup must be zero, Version one and activity equal issuance. The AuthenticationVerified projection must name a password/single-factor original for session-issue, not a checked opaque proof. Current authentication time, exclusive proof expiry, complete authority and resolved Remember are retained. Organization/factor/passkey profiles fail closed here; native policy must not issue a full session when MFA/verification remains required. No IO occurs. Issue rejects unbound preparations. Map the exact Session projection into the password-owned native command, then BindPassword once before reservation. The closed username-signin profile retains its original operation and uses the same password custody; preparation does not prove username ownership.

func (*SessionIssuer) PrepareSignup

PrepareSignup freezes prospective single-factor password-session custody for the original signup command. Version, activity, authority and remember rules match PreparePassword, but this profile is disjoint from signin. The new user must be retained separately from anonymous command scope. No IO, authentication or flow consumption occurs; never prepare again to recover an unknown result. Map the complete Session/CSRF projection into native intent before BindSignup.

func (*SessionIssuer) Recover

func (s *SessionIssuer) Recover(ctx context.Context, r IssueRequest) (out IssueResult, err error)

Recover performs only an authorized, bounded primary outcome lookup for the original request. Proof expiry does not prohibit historical recovery; current result-access policy belongs to the executor. It never executes, regenerates, reveals or redelivers a credential, even when recovery proves Committed. This is proof-profile recovery only. OTP and password requests are rejected; consuming native composition must provide separate code-free correlation.

type SessionListEntry

type SessionListEntry struct {
	Session                Session
	Revoked, FamilyRevoked bool
	Label                  string
}

SessionListEntry retains an immutable structural record and primary session and family tombstones. Label is at most128 UTF-8 bytes without control runes; it is user-controlled display metadata, never device trust or authentication. Returned entries and labels are caller-owned and must not be changed after return. The public service strips authority, digests and proof linkage.

func (SessionListEntry) Format

func (SessionListEntry) Format(s fmt.State, _ rune)

Format redacts structural records, tombstones and user-controlled labels.

func (SessionListEntry) MarshalJSON

func (SessionListEntry) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit structural record and label export.

type SessionLookup

type SessionLookup struct {
	TenantID identity.TenantID
	Digests  []TokenDigest
}

SessionLookup is one bounded, caller-owned observation request. Digests has 1..4 server-selected distinct positive key versions. No raw bearer is sent to storage. The reader must bind every returned row to this exact tenant/digest, reject multiple matches, and never authenticate on a prefix. Do not log it.

func (SessionLookup) Format

func (SessionLookup) Format(s fmt.State, _ rune)

Format redacts correlated lookup inputs.

func (SessionLookup) MarshalJSON

func (SessionLookup) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit lookup export.

type SessionObservation

type SessionObservation struct {
	Session                   Session
	Current                   AuthoritySnapshot
	Active                    bool
	ReadStartedAt, ValidUntil time.Time
}

SessionObservation is a trusted owned-reader projection, not public proof. Active asserts that the record, family, credential and every applicable authority are active on the primary, with exact owner-derived scope keys. Current is the one complete vector, not partial enrichment. The reader must compare the authenticating credential ID/version as well as aggregate versions. ReadStartedAt is the earliest contributing authoritative read start; ValidUntil is exclusive, no later than 20 seconds after that start. Copies/projections must preserve both timestamps. Missing/inactive returns Active false; incomplete infrastructure returns an error, not an active structural record.

func (SessionObservation) Format

func (SessionObservation) Format(s fmt.State, _ rune)

Format redacts authoritative observation metadata.

func (SessionObservation) MarshalJSON

func (SessionObservation) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit observation export.

type SessionPage

type SessionPage struct {
	Entries []SessionListEntry
	HasMore bool
}

SessionPage contains one bounded raw ordered scan. HasMore requires exactly the requested Limit entries and an additional matching record observed by the same primary query. A reader must not silently truncate, omit corrupt rows or filter inactive records: the core owns exact recorded-lifetime projection.

func (SessionPage) Format

func (SessionPage) Format(s fmt.State, _ rune)

Format redacts all returned storage projections.

func (SessionPage) MarshalJSON

func (SessionPage) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit stored page export.

type SessionPageQuery

type SessionPageQuery struct {
	TenantID       identity.TenantID
	UserID         identity.UserID
	Audience       string
	AfterSessionID string
	Limit          uint16
}

SessionPageQuery is an owned primary metadata scan, not authentication. Scope is derived from the authenticated caller. Limit is 1..100 raw records; AfterSessionID is empty or a canonical exclusive bytewise keyset marker. Readers must use exact tenant/user/audience predicates and ascending session IDs, return at most Limit records, and bound IO by ctx. Do not mutate during calls or use this structural query as an access grant.

func (SessionPageQuery) Format

func (SessionPageQuery) Format(s fmt.State, _ rune)

Format redacts trusted storage lookup scope.

func (SessionPageQuery) MarshalJSON

func (SessionPageQuery) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit trusted storage scope export.

type SessionPageReader

type SessionPageReader interface {
	ReadSessionPage(context.Context, SessionPageQuery) (SessionPage, error)
}

SessionPageReader is implemented by the owned primary adapter. It borrows dependencies, starts no unowned goroutines and returns owned snapshots after releasing store locks. Authentication and current policy are separate; no application-written store is required by native composition.

type SessionReader

type SessionReader interface {
	ObserveSession(context.Context, SessionLookup) (SessionObservation, error)
}

SessionReader is implemented by the owned session adapter, not an application domain store. ObserveSession must honor ctx, be concurrency-safe, use primary authority and perform no network policy callback while holding store locks. It does not issue/rotate a token, update activity or consume proof. A returned projection is trusted only through the immutable configured composition.

type SessionRotator

type SessionRotator struct {
	// contains filtered or unexported fields
}

SessionRotator owns exact successor preparation and commit-gated reveal-once delivery, but no store, transaction, journal, goroutine or retained key cache. Durable execution is provided only by the separately owned native adapter.

func NewSessionRotator

func NewSessionRotator(sessions *SessionService, executor RotationExecutor, c RotationConfig) (*SessionRotator, error)

NewSessionRotator freezes validated composition without IO. The issuance key must be retained by the reader with identical bytes/version so delivered successors are readable. No profile fallback or independent clock is added.

func NewSessionRotatorWithCSRF

func NewSessionRotatorWithCSRF(sessions *SessionService, executor RotationExecutor, c RotationConfig, key CSRFKey) (*SessionRotator, error)

NewSessionRotatorWithCSRF selects fresh synchronizer state for cookie successors with a dedicated current issuance key. Bearer rotation explicitly clears synchronizer state and delivers no CSRF credential or cookie. The executor must atomically persist complete source/successor state. Do not use legacy lossy adapters. Original credential delivery retains all native gates; retrieve CSRF custody from PreparedRotation.CSRFToken after successful Rotate.

func (SessionRotator) Format

func (SessionRotator) Format(s fmt.State, _ rune)

Format redacts configuration and borrowed runtime dependencies.

func (SessionRotator) MarshalJSON

func (SessionRotator) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit runtime serialization.

func (*SessionRotator) Prepare

func (s *SessionRotator) Prepare(caller GetResult, command identity.CommandID, correlation string) (out PreparedRotation, err error)

Prepare validates original authenticated custody and refresh eligibility before generating a token. It preserves absolute issuance, authentication, family, policy and non-session authority; accepted activity and session CAS advance exactly once in the frozen candidate. Bounded CSPRNG token generation runs, but no durable IO, command reservation or state transition occurs.

func (*SessionRotator) Recover

func (s *SessionRotator) Recover(ctx context.Context, r RotationRequest) (out RotationResult, err error)

Recover makes a bounded historical lookup under the native owner's current exact result-access policy. Source expiry does not erase commitment. It never executes, regenerates or redelivers a credential, including after restart.

func (*SessionRotator) Rotate

func (s *SessionRotator) Rotate(ctx context.Context, p PreparedRotation) (out RotationResult, err error)

Rotate makes one bounded attempt against the original immutable preparation. Panic/malformed response after executor entry is Unknown, never rollback. Known receipts preserve their outcome alongside errors, without credentials. A repeated preparation attempt requires original scoped recovery, not rerun.

type SessionService

type SessionService struct {
	// contains filtered or unexported fields
}

SessionService owns bounded credential lookup, exact current-vector comparison and original-validity/lifetime admission. It holds no store locks, cache, goroutines, transactions or authorization engine. Get is authentication only; callers must separately authorize each protected action with current policy.

func NewMethodSessionService

func NewMethodSessionService(reader SessionReader, config ServiceConfig, method AuthenticationKind) (*SessionService, error)

NewMethodSessionService freezes one explicit authentication method for primary and cached admission. Only verified-credential, OTP and magic-link methods are supported. This is an additional restriction on the trusted reader, not proof of issuance or an alternative to current authority. Other methods fail closed. Existing NewSessionService retains its reader-selected method composition.

func NewOrganizationBearerProfileSessionService

func NewOrganizationBearerProfileSessionService(reader SessionReader, config ServiceConfig, methods []AuthenticationKind, cacheProfile string) (*SessionService, error)

NewOrganizationBearerProfileSessionService selects the same explicit method set as NewSelectedProfileSessionService, with organization-bearing records restricted to bearer transport and no cookie-bound CSRF state. Unselected records retain existing cookie/bearer behavior. The owned reader still checks every applicable current authority; this restriction grants no membership or permission and does not enable selection, issuance or browser replacement.

The restriction is immutable and authenticated in encrypted-cache context. A permissive profile's cache cannot bypass it, and promotion cannot renew original freshness. Existing constructors remain unchanged. Construction performs no IO; dependencies remain borrowed with the usual concurrency rules.

func NewProfileSessionService

func NewProfileSessionService(reader SessionReader, config ServiceConfig, method AuthenticationKind, cacheProfile string) (*SessionService, error)

NewProfileSessionService additionally binds encrypted-cache admission to a stable, trusted reader profile identifier (1..256 visible ASCII bytes). The owner must distinguish all selected authority/store/method configuration that can change admission. The identifier is not authority itself; primary reads still enforce current owners. Changing it invalidates cached positives and refreshes from primary. Constructor inputs are copied without IO.

func NewSelectedProfileSessionService

func NewSelectedProfileSessionService(reader SessionReader, config ServiceConfig, methods []AuthenticationKind, cacheProfile string) (*SessionService, error)

NewSelectedProfileSessionService freezes an explicit nonempty subset of verified-credential, OTP and magic-link admission. The owned reader must dispatch on the stored record's kind and enforce that kind's complete current authority, never try readers until one accepts. cacheProfile binds all native owner/store configuration; the selected set is additionally authenticated in encrypted cache context. Selection is copied, order-independent, and grants no authority. Existing single-method constructors keep their closed semantics.

func NewSessionService

func NewSessionService(reader SessionReader, config ServiceConfig) (*SessionService, error)

NewSessionService freezes validation composition without IO. Use the owned primary adapter; structural Repository.Get/Lookup alone is not a SessionReader.

func (*SessionService) CacheAdmission

func (s *SessionService) CacheAdmission(result GetResult, maximumAge time.Duration) (out CachedAdmission, err error)

CacheAdmission prepares optional same-service reuse of an authentic Get result. maximumAge is 1ms..5m, clipped to the original conservative validity and lifetime. The configured trusted clock owns the observation; callers cannot select time. Fabricated, modified, foreign-service or expired results deny. Promotion/copying never renews freshness or a prior shortened deadline.

func (*SessionService) Configured

func (s *SessionService) Configured() bool

Configured reports immutable constructor validity without IO, clock calls or authentication. Nil/zero owners are false. This is not dependency health, readiness, authority or a lease; Get must still admit each credential. Valid immutable services may be inspected concurrently with Get.

func (SessionService) Format

func (SessionService) Format(s fmt.State, _ rune)

Format redacts runtime composition and keys.

func (*SessionService) Get

func (s *SessionService) Get(ctx context.Context, request GetRequest) (out GetResult, err error)

Get validates one credential without modifying session state. It sends only tenant-bound digests to the configured reader, requires active exact current authority and checks original lifetime, audience and source-read timestamps. Absent/denied/expired returns zero,nil without enumeration. Invalid input, missing authority infrastructure, clock/dependency panic and operational failure are redacted. Cancellation/deadline preserve identity classifications. No stale fallback, principal elevation, token reveal or refresh occurs.

func (*SessionService) GetCached

func (s *SessionService) GetCached(ctx context.Context, request GetRequest, cached CachedAdmission) (out GetResult, err error)

GetCached reuses only an exact same-service tenant, credential digest and transport until its original exclusive deadline. It never manufactures a new lease. Zero, stale, foreign or substituted cache entries invoke bounded authoritative Get with the original request; a failed refresh never falls back to stale positive evidence. Lost invalidation events cannot extend the source read's at-most-20s evidence window. Explicit current invalidation may discard the handle sooner. Caller cancellation and backward clocks deny. This is opt-in same-process admission reuse, not serialized cookie caching.

func (SessionService) MarshalJSON

func (SessionService) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit runtime export.

func (*SessionService) PrepareRevokeOne

func (s *SessionService) PrepareRevokeOne(caller GetResult, command SessionCommand) (out RevokeOneRequest, err error)

PrepareRevokeOne freezes a target command with a positive Get result from this exact configured service. It performs no IO, reservation or mutation and never renews admission. The target must share the caller's tenant, effective user and audience; the command actor must be that user. A same-ID target must retain the entire original caller record, not just its version. Independent sibling targets remain distinct from the authenticating source session. Ordinary logout does not require fresh login. Policy authorization, current owner locks and idempotent absent/revoked handling remain executor obligations. Clock failures are redacted. Dependencies must remain alive through execution.

func (*SessionService) PrepareRevokeOneWithCSRF

func (s *SessionService) PrepareRevokeOneWithCSRF(caller GetResult, command SessionCommand, token CSRFToken, key CSRFKey) (RevokeOneRequest, error)

PrepareRevokeOneWithCSRF additionally retains synchronizer-token custody for the original cookie-authenticated caller. The key must be the exact eligible state-named key from trusted deployment policy. This structural check performs no IO and does not replace primary admission. The owned executor must select its own trusted key, recheck the token against this frozen original on its original protected transaction after acquiring mutation fences, and abort on error. No raw token/key may enter command intents, audit or recovery records. Existing PrepareRevokeOne remains the trusted direct/bearer profile.

func (*SessionService) PrepareRevokeSet

func (s *SessionService) PrepareRevokeSet(caller GetResult, command SessionCommand) (out RevokeSetRequest, err error)

PrepareRevokeSet requires positive, currently fresh caller admission from this exact service and the entire unchanged authenticating record in the command. It performs no IO/mutation and never accepts caller-built principal metadata. Its effective exclusive deadline is the earlier original admission expiry or authentication freshness boundary. Clock failures are redacted.

func (*SessionService) PrepareRotation

func (s *SessionService) PrepareRotation(caller GetResult, command SessionCommand) (out RotationRequest, err error)

PrepareRotation binds only the authenticating session's exact original record to its structurally valid successor. Original lifetime and admission must be live; ordinary rotation does not require a fresh login or unexpired historical sign-in proof. Current policy/owner comparison and atomic effects remain owned executor obligations. No IO, consumption, durable command or reveal occurs.

func (*SessionService) PrepareUpdate

func (s *SessionService) PrepareUpdate(caller GetResult, command SessionCommand) (out UpdateCommandRequest, err error)

PrepareUpdate admits only the exact currently authenticating source record, not another same-user device. It does no IO, mutation or authorization. A forged, modified, foreign-service or expired caller fails closed. Freshness for safe display metadata is not renewed or required. Clock panics redact.

type SessionSpec

type SessionSpec struct {
	SessionID, FamilyID      string
	TenantID                 identity.TenantID
	UserID                   identity.UserID
	Audience                 string
	Version, FamilyVersion   uint64
	Remember                 RememberPolicy
	Authority                AuthoritySnapshot
	Lookup                   TokenDigest
	Authentication           AuthenticationMetadata
	IssuedAt, LastActivityAt time.Time
}

SessionSpec is the original bounded base projection with no raw token. Synchronizer and OTP metadata are separately projected by Session.CSRFState and Session.OTPAuthentication to preserve this public struct's shape. Magic-link primary and MFA provenance likewise use their separate structural projections. Complete storage must persist every applicable projection. Remember must already be resolved; Authority is the sole complete vector. Session/family versions must equal that vector's corresponding versions. IDs are canonical 1..128 visible ASCII bytes, Audience at most256. Constructors do not normalize IDs or derive authority scope keys. The owner must derive those keys from these exact IDs and verify them against primary records. Times preserve original issuance, accepted activity and authentication. A completed proof may precede issuance; issuance must not renew its freshness. Reconstruction is not authentication, an active-state check or durable proof.

type SessionUpdater

type SessionUpdater struct {
	// contains filtered or unexported fields
}

SessionUpdater owns source-bound label preparation, bounded native execution, receipt validation and safe outcome recovery. It creates no store, journal, transaction, token, goroutine or competing authority vector. Borrowed reader and executor must outlive calls and satisfy their concurrency/budget contracts.

func NewSessionUpdater

func NewSessionUpdater(sessions *SessionService, executor UpdateExecutor, c UpdateConfig) (*SessionUpdater, error)

NewSessionUpdater freezes explicit composition without IO. Use the owned primary reader and native executor for the exact reader; installing core alone does not implement PostgreSQL mutation or permit consumer-written stores.

func (*SessionUpdater) Format

func (*SessionUpdater) Format(s fmt.State, _ rune)

Format redacts borrowed runtime composition.

func (*SessionUpdater) MarshalJSON

func (*SessionUpdater) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit runtime export.

func (*SessionUpdater) Prepare

func (s *SessionUpdater) Prepare(caller GetResult, input UpdatePreparation) (out UpdateCommandRequest, err error)

Prepare requires unchanged same-reader original Get custody and an exact self-session ID/version before constructing a label-only transition. A stale expected version returns identity.ConflictError without reserving anything. It runs no IO, authorization or mutation; ordinary safe metadata needs no fresh login. Retain the returned immutable request for exact scoped recovery.

func (*SessionUpdater) Recover

func (s *SessionUpdater) Recover(ctx context.Context, r UpdateCommandRequest) (out UpdateResult, err error)

Recover observes the original exact scoped command under the executor's current result-access policy. It does not require an expired original source to become valid again, execute a mutation or return session/display metadata. Copies preserve original custody and expiry; no recovery grants admission.

func (*SessionUpdater) Update

Update makes one bounded exact-intent attempt. The durable coordinator owns idempotency across retries and processes. Panic or malformed response after executor entry is Unknown, never assumed rollback. A known committed receipt survives cancellation, expiry or ancillary read errors without apparent metadata success. Recover an ambiguous outcome before changing command intent.

type SessionVersion

type SessionVersion uint64

SessionVersion is an exact positive session CAS version. Zero is invalid; observing a newer version does not renew an older admission or credential.

type SetRevocationConfig

type SetRevocationConfig struct {
	PolicyID        string
	PolicyVersion   uint64
	MaximumSessions uint32
	MaximumDuration time.Duration
}

SetRevocationConfig selects explicit policy identity/version, all-or-nothing active-row bound 1..100000 and a 1ms..30s whole-call budget. Earlier caller, original authority and freshness deadlines win. Zero is invalid; configuration and borrowed dependencies must remain immutable during concurrent calls.

func (SetRevocationConfig) Format

func (SetRevocationConfig) Format(s fmt.State, _ rune)

Format redacts policy configuration.

func (SetRevocationConfig) MarshalJSON

func (SetRevocationConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit configuration export.

type SetRevocationService

type SetRevocationService struct {
	// contains filtered or unexported fields
}

SetRevocationService owns authenticated, fresh self-service revoke-other/all composition. It creates no stores, transactions, goroutines, policy engine or journal. Native atomic execution/recovery is a separate owned-adapter step; installing this service alone is not a complete persisted revocation workflow.

func NewSetRevocationService

func NewSetRevocationService(sessions *SessionService, executor RevokeSetExecutor, c SetRevocationConfig) (*SetRevocationService, error)

NewSetRevocationService freezes explicit dependencies without IO. Use the owned primary reader and executor configured for that exact reader; caller-selected user IDs, structural records or consumer stores cannot replace credentials.

func (*SetRevocationService) Format

func (*SetRevocationService) Format(s fmt.State, _ rune)

Format redacts borrowed dependencies and configuration.

func (*SetRevocationService) RevokeAll

RevokeAll freshly authenticates the source and explicitly preserves or revokes it while targeting all user-owned sessions in the tenant, across audiences. ExpectedSubjectVersion is positive and exact; mismatch denies before execution.

func (*SetRevocationService) RevokeOther

RevokeOther freshly authenticates and prepares exact self-owned revocation excluding the source, then delegates current policy and atomic persistence to the owned executor. No partial count or apparent success is returned for denial, outage, malformed receipts, cancellation or an ambiguous outcome.

type SignOutConfig

type SignOutConfig struct {
	Cookie          CookiePolicy
	PolicyID        string
	PolicyVersion   uint64
	MaximumDuration time.Duration
}

SignOutConfig selects trusted self-service policy and exact host-cookie deletion attributes. MaximumDuration is 1ms..30s for the whole operation; earlier caller/primary validity deadlines still win. PolicyID and positive PolicyVersion must match the owned executor's deployment configuration. Cookie must be valid even when bearer transport is selected. Zero is invalid.

func (SignOutConfig) Format

func (SignOutConfig) Format(s fmt.State, _ rune)

Format redacts configured policy and cookie metadata.

func (SignOutConfig) MarshalJSON

func (SignOutConfig) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit deployment configuration export.

type SignOutRequest

type SignOutRequest struct {
	TenantID      identity.TenantID
	CommandID     identity.CommandID
	CorrelationID string
	Transport     CredentialKind
	Credential    Credential
}

SignOutRequest selects one tenant and transport, with optional credential. CommandID is caller-generated and retained for ambiguous-outcome recovery; CorrelationID is bounded safe correlation, not authority. A zero Credential means absent. A present credential must exactly match Transport; HTTP owns canonical parsing, mixed-source rejection and cookie origin/CSRF protection. The request cannot select a user, target session or policy. Do not mutate it concurrently with a call. Zero is invalid.

func (SignOutRequest) Format

func (SignOutRequest) Format(s fmt.State, _ rune)

Format redacts correlated transport and command metadata.

func (SignOutRequest) MarshalJSON

func (SignOutRequest) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit credential persistence.

func (SignOutRequest) MarshalText

func (SignOutRequest) MarshalText() ([]byte, error)

MarshalText rejects implicit credential disclosure.

type SignOutResult

type SignOutResult struct {
	SignedOut, ClearCookie, ClearBearer bool
	CommandID                           identity.CommandID
	CommitOutcome                       identity.CommitOutcome
	RetryAfter                          time.Duration
	Cookie                              http.Cookie
	Recovery                            identity.RecoveryQuery
}

SignOutResult distinguishes successful transport removal from a durable command observation. SignedOut is true only after absent/primary-denied credentials or exact committed execution with no delivery error. Invalid CommitOutcome means no authoritative command outcome was observed, including already-absent idempotent success; it is not a fabricated NotCommitted result. Cookie is empty-valued secure deletion metadata only when ClearCookie is true; bearer signout sets ClearBearer and never clears a cookie. CommitOutcome and Recovery retain exact metadata even on cancellation or unknown outcome. Recovery is a scope locator, not lookup permission or authentication. The owned executor's historical query requires current result-access policy.

func (SignOutResult) Format

func (SignOutResult) Format(s fmt.State, _ rune)

Format redacts historical command/transport scope.

func (SignOutResult) MarshalJSON

func (SignOutResult) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit command or transport export.

func (SignOutResult) MarshalText

func (SignOutResult) MarshalText() ([]byte, error)

MarshalText rejects implicit scope disclosure.

type SignOutService

type SignOutService struct {
	// contains filtered or unexported fields
}

SignOutService owns bounded self-signout composition through the exact trusted reader and durable executor. It starts no goroutines and owns no store, locks, command journal or transaction. Dependencies are borrowed, must outlive calls and be concurrency-safe. Ordinary signout requires no fresh login. Other sessions, family authority and client transports remain unchanged.

func NewSignOutService

func NewSignOutService(sessions *SessionService, executor RevokeOneExecutor, c SignOutConfig) (*SignOutService, error)

NewSignOutService validates immutable composition without IO. Use the owned primary SessionService and native executor configured for that exact reader; structural records or consumer-written repositories are not authentication.

func (*SignOutService) Configured

func (s *SignOutService) Configured() bool

Configured reports immutable owner composition without calling dependencies or reading state. Nil/zero owners are false; true is not health, permission, current session validity or a future execution guarantee. Safe concurrently.

func (SignOutService) Format

func (SignOutService) Format(s fmt.State, _ rune)

Format redacts borrowed runtime dependencies.

func (SignOutService) MarshalJSON

func (SignOutService) MarshalJSON() ([]byte, error)

MarshalJSON rejects implicit runtime composition export.

func (*SignOutService) SignOut

func (s *SignOutService) SignOut(ctx context.Context, r SignOutRequest) (out SignOutResult, err error)

SignOut authenticates the presented credential on the primary, prepares an exact self-target command and invokes the sole durable owner. Absent, inactive and already-revoked credentials succeed without another mutation. Reader outages, ambiguity, policy denial and cancellation do not become successful logout or cookie deletion. Retries must not mint replacements for an unknown command: query its retained Recovery scope first. The adapter preserves original caller validity through commit; this service never renews it. No raw credential is revealed or stored. All dependency errors are redacted.

type StorageProfile

type StorageProfile uint8

StorageProfile declares a deployment capability, not an automatic fallback.

const (
	// StorageStatefulOpaque uses digest-indexed durable primary authority.
	StorageStatefulOpaque StorageProfile = iota + 1
	// StorageSecondary requires a separately implemented bounded projection.
	StorageSecondary
	// StorageCookieCache requires a separately implemented authenticated cache.
	StorageCookieCache
	// StorageStateless requires a separately implemented codec/invalidation policy.
	StorageStateless
)

type Token

type Token struct {
	// contains filtered or unexported fields
}

Token owns an opaque 32..64-byte bearer encoded as canonical unpadded base64url. Zero is invalid. No raw secret is exposed by formatting or automatic serialization. Copies share one atomic Reveal permission; Digest is read-only and concurrency-safe before and after Reveal. Token owns no external resource. It cannot prove authentication, authority, persistence or session expiry.

Example
package main

import (
	"crypto/rand"
	"errors"
	"fmt"

	"github.com/faustbrian/go-identity/session"
)

func main() {
	// This is a standalone custody example, not authoritative session issuance.
	material := make([]byte, 32)
	rand.Read(material)
	key, err := session.NewDigestKey(1, material)
	if err != nil {
		panic(err)
	}
	clear(material)
	token, err := session.NewToken(32)
	if err != nil {
		panic(err)
	}
	digest, err := token.Digest(key, "tenant-example")
	if err != nil {
		panic(err)
	}
	fmt.Println(digest.KeyVersion)
	copy := token
	// In real issuance this disclosure must follow authoritative commitment.
	wire, err := token.Reveal()
	if err != nil {
		panic(err)
	}
	fmt.Println(len(wire)) // Never print the bearer itself.
	_, err = copy.Reveal()
	fmt.Println(errors.Is(err, session.ErrTokenAlreadyRevealed))
}
Output:
1
43
true

func NewToken

func NewToken(size int) (Token, error)

NewToken creates a cryptographically random token of exactly size bytes, bounded to 32..64 before allocation. Go's crypto/rand owns secure OS entropy; fatal entropy failure follows its standard fail-stop behavior. This allocates a credential only, not a session, command, receipt or database row. Reveal only after the authoritative issuance transaction commits; unknown outcomes must reveal nothing. Durable recovery must recover the original issuance result, never call NewToken to retry an ambiguous command.

func ParseToken

func ParseToken(wire string) (Token, error)

ParseToken copies a bounded canonical bearer from an explicit credential transport. Padding, whitespace, non-URL alphabet, trailing bits and decoded lengths outside 32..64 deny. Parsing creates one new delivery permission: callers already possessing wire bytes can parse again, so Reveal is custody control, not a replay store or cryptographic limit on bearer reuse.

func (Token) Digest

func (t Token) Digest(k DigestKey, tenant string) (TokenDigest, error)

Digest computes HMAC-SHA-256 over the exact framing: "golib-session-lookup-v1\x00", big-endian uint32 key version, big-endian uint16 tenant-byte length, tenant bytes, uint8 decoded-token length, decoded bytes. Tenant is an already canonical 1..128-byte visible ASCII ID, never a user-input normalizer. Scope/domain/version separation is mandatory. No raw token or key is retained in the returned value. Rotating keys requires explicit lookups with each required retained key; this method does not silently change versions.

func (Token) Format

func (t Token) Format(s fmt.State, _ rune)

Format redacts for every fmt verb, including quoted and Go-syntax output.

func (Token) MarshalJSON

func (t Token) MarshalJSON() ([]byte, error)

MarshalJSON denies accidental bearer serialization. Explicit Reveal is the sole transport disclosure operation.

func (Token) MarshalText

func (t Token) MarshalText() ([]byte, error)

MarshalText denies text and map-key serialization of bearer custody.

func (Token) PreAuthDigest

func (t Token) PreAuthDigest(k DigestKey, b PreAuthBinding) (TokenDigest, error)

PreAuthDigest derives HMAC-SHA-256 cookie lookup under the exact named key and complete original binding. Use a dedicated pre-auth key, not the session lookup/signing/envelope key. The framing starts with golib-preauth-cookie-v1 NUL and the uint32 key version. Next come ID, tenant, action, origin, callback and policy strings, each with a uint16 byte length, then nonce, uint64 policy version, UTC RFC3339Nano issued/expiry strings, resolved uint8 remember choice and four uint64 nanosecond durations, then uint8 decoded token size and token bytes, all integers big-endian. With nonzero IdentifierBinding, the domain is instead golib-preauth-cookie-identifier-v1 NUL and its exact 32 bytes follow the four durations, before token size/bytes. Zero retains every legacy framing byte. Phone recovery instead uses golib-preauth-cookie-phone-recovery-v1 NUL, omits the remember choice/durations and requires the identifier commitment. No key fallback, raw-cookie storage, automatic disclosure, time sample or validity renewal occurs. Compute only from authenticated original intent; possession of the result is not an alternate credential or one-use proof.

func (Token) Reveal

func (t Token) Reveal() (string, error)

Reveal returns the credential exactly once across copies. The atomic claim occurs before return; lost delivery does not restore it. The transport must never log, persist raw, snapshot or encode the returned value outside the explicitly authorized credential response/cookie/header. This does not erase process memory or prevent a recipient from retaining the credential.

type TokenDigest

type TokenDigest struct {
	KeyVersion uint32
	Sum        [32]byte
}

TokenDigest is the non-bearer lookup projection. KeyVersion and all 32 digest bytes must be persisted together with tenant scope. It is not authentication proof and must not be exposed as an alternate client credential. Avoid logging stable lookup digests because they correlate session activity.

type UpdateCommandRequest

type UpdateCommandRequest struct {
	// contains filtered or unexported fields
}

UpdateCommandRequest binds an immutable native update to original opaque admission from one exact SessionService. Zero is invalid; copies preserve the exclusive source deadline. No raw credential or caller-built principal can replace this custody. Durable policy/owner validation remains required.

func (UpdateCommandRequest) Command

func (r UpdateCommandRequest) Command() (SessionCommand, bool)

Command returns structural intent without transferring caller custody. Zero returns false. Restoring a command cannot reconstruct this request.

func (UpdateCommandRequest) Format

func (UpdateCommandRequest) Format(s fmt.State, _ rune)

Format redacts correlated mutation and caller custody.

func (UpdateCommandRequest) MarshalJSON

func (UpdateCommandRequest) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit request persistence and custody export.

func (UpdateCommandRequest) MarshalText

func (UpdateCommandRequest) MarshalText() ([]byte, error)

MarshalText denies implicit text and map-key custody disclosure.

func (UpdateCommandRequest) Transport

func (r UpdateCommandRequest) Transport() CredentialKind

Transport returns the admitted cookie/bearer transport, never a caller override. Zero returns zero. Updating metadata cannot change transport.

func (UpdateCommandRequest) ValidUntil

func (r UpdateCommandRequest) ValidUntil() time.Time

ValidUntil returns the original exclusive admission deadline; zero returns zero. Reading, copying or retrying this request cannot move that deadline.

func (UpdateCommandRequest) Validate

func (r UpdateCommandRequest) Validate(s *SessionService, now time.Time) error

Validate checks original custody and exclusive deadline at trusted now; the owned executor must call it before reservation and final commit and independently compare current primary state and operation policy. It does not extend freshness, authenticate structural fields or mutate any store.

type UpdateCommandSpec

type UpdateCommandSpec struct {
	Binding           identity.CommandBinding
	Source, Successor Session
	DeviceLabel       string
}

UpdateCommandSpec freezes a self-session metadata CAS. DeviceLabel is untrusted display text, at most128 UTF-8 bytes without control runes; empty clears it. Successor changes only the session version and its exact authority binding. Labels are not authentication, device trust or authorization facts. The projection grants no custody, permission or commitment.

func (UpdateCommandSpec) Format

func (UpdateCommandSpec) Format(s fmt.State, _ rune)

Format redacts labels, source records, scope and authority for all verbs.

func (UpdateCommandSpec) MarshalJSON

func (UpdateCommandSpec) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit label and structural record disclosure.

func (UpdateCommandSpec) MarshalText

func (UpdateCommandSpec) MarshalText() ([]byte, error)

MarshalText denies implicit label and structural record disclosure.

type UpdateConfig

type UpdateConfig struct {
	PolicyID        string
	PolicyVersion   uint64
	MaximumDuration time.Duration
}

UpdateConfig requires explicit selected self-policy identity/version and a 1ms..30s whole-call budget. Original admission expiry always wins. Zero is invalid; the frozen configuration adds no clock, token key or store.

func (UpdateConfig) Format

func (UpdateConfig) Format(s fmt.State, _ rune)

Format redacts policy configuration.

func (UpdateConfig) MarshalJSON

func (UpdateConfig) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit configuration export.

type UpdateExecution

type UpdateExecution struct {
	Receipt     identity.CommandResult
	Session     Session
	DeviceLabel string
	Replayed    bool
}

UpdateExecution carries an exact durable receipt and historical successor label. Session and DeviceLabel are absent on noncommits. A known commit's ancillary read failure may return zero Session/label alongside an error; the exact committed receipt remains intact. Replayed describes historical observation, not a replacement command or current authority.

func (UpdateExecution) Format

func (UpdateExecution) Format(s fmt.State, _ rune)

Format redacts historical native receipt and label.

func (UpdateExecution) MarshalJSON

func (UpdateExecution) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit native receipt/label export.

type UpdateExecutor

type UpdateExecutor interface {
	ExecuteUpdate(context.Context, UpdateCommandRequest) (UpdateExecution, error)
	RecoverUpdate(context.Context, UpdateCommandRequest) (identity.CommandResult, error)
}

UpdateExecutor is implemented by the owned durable adapter, not application workflow callbacks or another command journal. ExecuteUpdate authorizes the exact current policy, validates original same-reader custody and current primary owners, and commits label/session CAS/audit/lifecycle/receipt under the sole coordinator. Exact intent replay must not reapply the mutation. RecoverUpdate authorizes current exact result access and observes the original command only; source expiry must not erase commitment. Neither method returns credentials or renewed admission. Methods are concurrent-safe and honor ctx. A zero receipt with ForbiddenError, ErrUnauthenticated or ErrInvalidInput and absent result metadata/replay is reserved for rejection before reservation and effects (Execute) or outcome observation (Recover); it does not classify a historical command as rolled back.

type UpdatePreparation

type UpdatePreparation struct {
	CommandID       identity.CommandID
	CorrelationID   string
	SessionID       string
	ExpectedVersion uint64
	DeviceLabel     string
}

UpdatePreparation identifies the authenticating session and exact expected positive session version. CommandID is the stable host-validated identity, not a per-attempt random key. DeviceLabel is bounded untrusted display text; empty clears it. No owner override, security-field patch or clock is accepted. Copies are safe only while caller-owned fields remain immutable.

func (UpdatePreparation) Format

func (UpdatePreparation) Format(s fmt.State, _ rune)

Format redacts labels and correlated command input.

func (UpdatePreparation) MarshalJSON

func (UpdatePreparation) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit label/command input export.

func (UpdatePreparation) MarshalText

func (UpdatePreparation) MarshalText() ([]byte, error)

MarshalText denies text and map-key input export.

type UpdateResult

type UpdateResult struct {
	CommandID     identity.CommandID
	CommitOutcome identity.CommitOutcome
	RetryAfter    time.Duration
	Recovery      identity.RecoveryQuery
	Session       Session
	Device        Device
	Replayed      bool
}

UpdateResult retains exact durable outcome and recovery scope. Session and Device appear only after consistent committed success inside the original admission/context deadlines. They are historical display data, not new Get custody or permission. Recovery returns no Session/Device and never claims that a historical command's target remains the current active session. Invalid means no authoritative outcome was observed, including cancellation before executor entry; it must not be interpreted as original command rollback.

func (UpdateResult) Format

func (UpdateResult) Format(s fmt.State, _ rune)

Format redacts historical scope and safe display metadata.

func (UpdateResult) MarshalJSON

func (UpdateResult) MarshalJSON() ([]byte, error)

MarshalJSON denies implicit display export; HTTP owns explicit authorized DTOs.

func (UpdateResult) MarshalText

func (UpdateResult) MarshalText() ([]byte, error)

MarshalText denies implicit result/map-key export.

Directories

Path Synopsis
postgres module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL