@lssm/integration.authos-better-auth
v2.1.1
Published
Better Auth bridge that maps AuthOS contracts to provider configuration, plugins, and redacted events.
Maintainers
Readme
@lssm/integration.authos-better-auth
Better Auth bridge for AuthOS Broad V0.
The web bridge preserves legacy signIn.oauth2({ providerId }) and
oauth2.link({ providerId }) callers through Better Auth 1.7's supported
signIn.social/linkSocial endpoints. It no longer imports the removed
genericOAuthClient. Provider callback registration/schema migration remains
a separate host rollout requirement.
This package turns AuthOS contracts into Better Auth configuration and maps Better Auth-like user/session/events back to AuthOS contracts. Canonical models stay in @lssm/lib.authos-spec; pure projections and security gates stay in @lssm/lib.authos-runtime.
advanced.cookiePrefix passes the host-selected namespace to Better Auth. Preview
hosts can combine a distinct prefix with secure cookies and disabled cross-subdomain
cookies. This separates cookie names and host scope; data/secret isolation must still
be provisioned and verified independently.
Maturity
- Core email/password, magic link, email OTP, organization/team, admin, OAuth/OIDC client, MFA, WebAuthn passkeys, phone, and one-tap are runtime-backed through Better Auth.
- Built-in social login is typed for Google, Microsoft, LinkedIn, TikTok, Facebook, and GitHub. Hosts may retain
genericOAuthfor additional providers. - Generic OIDC hosts can opt into
profileNameFallback: "email"for legacy identities without a display name. The bridge reuses the provider email verbatim and never infers a human name. - Invite-only hosts set
disableSignUp; verified-email providers may resolve an existing verified identity, while TikTok and missing-email LinkedIn/Facebook identities require an explicit authenticated account link. - Passkeys use the matching
@better-auth/passkeyserver and browser plugins. Hosts must apply the provider'spasskeytable migration before enabling enrollment. - SSO and SCIM remain declared external plugin capabilities until their production package wiring is separately reviewed.
- LSSM-as-IdP uses the supported
@better-auth/oauth-providerOAuth 2.1/OIDC runtime, with dynamic registration disabled, PKCE/S256 provider defaults, pairwise subject derivation, asymmetric JWT/JWKS support, explicit login/consent routes, and resource audiences. It remains contract-only unlesssecurityReviewRefand a server-only pairwise secret are present and production enablement is explicitly gated. - IdP hosts may supply a product-access policy. Without one, post-login always redirects to the configured access boundary. Reviewed hosts can publish explicit product scopes, bind consent to an entitlement reference, and emit only coarse application/tier/entitlement claims after the host confirms active access.
- Product membership handoffs expose a bounded, bearer-authenticated internal handler. It accepts only an RP-specific pairwise subject and idempotent provisioning scope; canonical identity IDs, local role authority, and secret material are excluded from its contracts and replay evidence.
./relying-party-reconciliationprepares the exact catalog-owned Better Auth OAuth client record for an operator-controlled host reconciliation. It hashes the confidential client secret with the provider's SHA-256/base64url format, keeps dynamic registration disabled, and exposes only a secret-free configuration digest and evidence reference.
Referral and affiliate handoff
attribution configuration composes with an existing Better Auth
databaseHooks.user.create.after hook. When a host resolves a valid signed
acquisition token, the bridge calls onIdentityCreated after email/password or
OAuth identity creation. The callback receives the opaque token and classified
flow; the bridge does not persist, decode, or emit the token.
Native bearer sessions
./native-session-client exposes a storage-port-driven Better Auth client for
Expo, Tauri, and other trusted native shells. Email/password and TOTP flows
capture set-auth-token and the bounded set-mfa-authority projection, while
the host-supplied vault keeps both values device-only. Credentials are sent only
in JSON request bodies to the configured AuthOS origin and never enter URLs,
logs, events, or replay evidence.
Verification
bun run lint:check
bun run typecheck
bun run test
bun run buildPure bridge-plan inspection
Use @lssm/integration.authos-better-auth/bridge-plan for browser/native inspection of provider plugin plans. It retains buildBetterAuthBridgePlan behavior without importing Better Auth server initialization, database adapters or Next.js cookie integration. The existing root/config exports remain compatible for server consumers. Native preview imports must use this pure entry point; a build-boundary test guards against server code re-entering the graph.
Better Auth 1.7 client compatibility
The shared bridge no longer imports the removed genericOAuthClient plugin.
Existing signIn.oauth2({ providerId, ...options }) and
oauth2.link({ providerId, ...options }) bridge calls are retained as adapters to
Better Auth's supported signIn.social and linkSocial methods. They translate
providerId to provider, preserve request options and return provider errors.
Other dynamic client methods retain their original behavior.
This client repair does not migrate provider registrations, callback forwarding routes, native clients built directly on Better Auth, or account identity data. Review those separately using the Better Auth 1.7 upgrade guide before qualifying live OAuth. No production identity records were changed.
Server-side bearer session reads
createBetterAuthBearerSessionReader resolves a bearer through the configured
AuthOS /api/auth/get-session?disableCookieCache=true endpoint and maps it to the
canonical AuthOsSession. It requires HTTPS except loopback development, forbids
redirects, bounds time/body size, and rejects expired, banned or mismatched user
sessions. Tokens, email and role strings are not returned. This is authentication
only: callers must separately resolve current tenant-scoped permissions and must
not infer fleet-management access from the identity or provider role.
