oc · docs
docs / documentation

@orangecheck/auth-core


@orangecheck/auth-core / SessionPayload

Interface: SessionPayload

Defined in: index.ts:56

Extends

  • unknown

Properties

PropertyTypeDescriptionDefined in
<a id="property-did_oc"></a> did_ocstringOpaque public-facing identifier · did:oc:<32-hex>. The sole canonical user identifier post auth-refactor. Stable across linking events. Per AUTH-REFACTOR-PLAN.md §2.1.index.ts:63
<a id="property-display_identity"></a> display_identity?DisplayIdentity | nullThe identity the user has chosen to show in their account badge — the collapsed label every family site (and any integrator) renders instead of the raw did:oc. Baked into the JWT so the choice is consistent across every .ochk.io subdomain with no round-trip, the same posture as name / npub. Re-resolved by the auth host on every mint: an explicit user promotion wins; absent that, it defaults to the account's sign-in identity (BIP-322 accounts → their Bitcoin address, federation accounts → their email). Absent / null on tokens minted before this field shipped — consumers fall back to the did_oc. Read it safely with resolveDisplayIdentity().index.ts:168
<a id="property-home_federation"></a> home_federation?string | nullSlug of the federation this user is bound to (their "home" federation). Multi-federation routing reads this; v1 has one live federation so it's set on first signin and rarely changes. Absent on tokens minted before this field shipped, and on accounts that have never bound to a federation. Consumers fall back to the directory default at /api/federations when absent.index.ts:82
<a id="property-is_owner"></a> is_owner?booleanOptional best-effort owner flag · set by the auth host at signin time when the new did_oc matches OWNER_OC_ADDRESSES. Surfaced through to clients via useOcSession().account.isOwner so the family-switcher and other low-stakes UX can render owner-only affordances (e.g. an analytics.ochk.io entry). NOT A SECURITY BOUNDARY. Sensitive surfaces still re-check the live OWNER_OC_ADDRESSES env against session.did_oc on every request (analytics.ochk.io's requireOwner does this). If an owner is removed from the env, their JWT may still carry is_owner: true for up to 30 days — the UX hint goes stale, but every gated action they attempt re-fails server-side. Treat absence as false. Set only on first signin or re-issue; never mutated mid-session.index.ts:153
<a id="property-jti"></a> jtistring-index.ts:64
<a id="property-merged_from"></a> merged_from?string[]Historical did_ocs consolidated INTO this account via the /api/auth/link/btc transfer-under-dual-proof flow. Consumers that aggregate per-user data should union queries across [did_oc, ...merged_from]. Absent / empty means "no absorbed accounts." Order is not significant.index.ts:112
<a id="property-name"></a> name?string | nullOptional display name set by the user via the auth host's profile surface. When present, consumer subdomains can render it in their header chip without a network round-trip. Re-minted on signin and whenever the user updates their profile.index.ts:71
<a id="property-npub"></a> npub?string | nullOptional Nostr npub set by the user. Same lifecycle as name.index.ts:73
<a id="property-signing_method"></a> signing_method?"fedimint_threshold" | "fedimint_client" | "bip322" | nullDiscriminator recording where this user is on the custody-state graph. Three legitimate states: - 'fedimint_threshold' — federation custody via the OC-introduced federation (default for email-OTP signups; OC's threshold guardians hold key shares). - 'fedimint_client' — user moved their balance to a Fedimint federation they picked themselves (still federation custody, but on a federation OC didn't introduce). - 'bip322' — full self-custody. The user signs with their own Bitcoin key. OC has zero authority over their funds. Graduation is the product thesis. This field is the structural primitive that records progress along the custody-state graph; transitions are recorded as anchored "rebind" envelopes. Absent on tokens minted before the field shipped — consumers should treat undefined as 'fedimint_threshold' for email-OTP identities and 'bip322' for BIP-322 identities (the default-by-construction mapping).index.ts:104
<a id="property-step_up_at"></a> step_up_at?numberUnix seconds when the user last successfully completed a WebAuthn step-up assertion on the auth host. Consumer subdomains gate sensitive actions on (now - step_up_at) < their_window — typically 5 minutes. Absent on JWTs minted before WebAuthn shipped, or on tokens minted by ordinary signin (only set by /api/auth/webauthn/assertion/verify on success). Use verifyStepUpClaim() to read it safely.index.ts:122
<a id="property-sub"></a> substring-index.ts:57
<a id="property-sudo_at"></a> sudo_at?numberUnix seconds when the user last successfully completed an inline sudo-mode re-authentication on the auth host (email-OTP for email-primary identities, BIP-322 challenge for btc-primary identities). Gates auth-graph-mutating operations — register an additional WebAuthn credential, revoke one, link a new identity, change recovery method — without forcing a full sign-out/sign-in. Same shape and freshness window posture as step_up_at; the two are independent claims (sudo proves "you typed your password again," step-up proves "you tapped your hardware key"). Read it with verifySudoClaim().index.ts:135