Skip to content

@lastshotlabs/slingshot-auth

npm install @lastshotlabs/slingshot-auth

Adds a single tenant-scoped role to a user within a tenant.

Delegates to adapter.addTenantRole, then emits a security.admin.role.changed event with scope: "tenant" and action: "add".

async function addTenantRole(userId: string, tenantId: string, role: string, changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Adds a single app-level role to a user.

Delegates to adapter.addRole (which should be idempotent — duplicate adds are silently ignored by well-behaved adapters), then emits a security.admin.role.changed event with action: "add".

async function addUserRole(userId: string, role: string, changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Zod schema for the full AuthPluginConfig object.

Used internally by createAuthPlugin to validate the raw config at startup. Exported for consumers who want to pre-validate config before passing it to the plugin (e.g., in tests or server-config loaders).

FieldDescription
authCore authentication feature configuration. Omit to use the plugin defaults.

Source: packages/slingshot-auth/src/types/config.ts

Creates the slingshot-auth plugin instance for use with createApp(), createServer(), or as a standalone Hono plugin via plugin.setup().

The plugin bootstraps all auth subsystems (session store, adapters, rate limiting, credential stuffing detection, OAuth providers, MFA, SAML, SCIM, etc.) and mounts the corresponding route handlers on the Hono app.

Remarks: - In standalone mode (no SlingshotFrameworkConfig), config.runtime.password is required. - Production boot requires an explicit security.signing.sessionBinding choice. Without it a stolen JWT+session pair is usable from any IP or browser. Set security.signing.sessionBinding to either a real binding policy or false to acknowledge the risk explicitly. - OAuth routes are provided by @lastshotlabs/slingshot-oauth and mounted by that plugin.

function createAuthPlugin(rawConfig: AuthPluginConfig): StandalonePlugin

Source: packages/slingshot-auth/src/plugin.ts

Builds a resolved auth config by merging partial overrides onto DEFAULT_AUTH_CONFIG. The returned object is deep-frozen — mutations throw in strict mode.

Called by bootstrapAuth to produce the singleton config attached to AuthRuntimeContext. Exposed publicly so consumers and tests can construct a resolved config without going through the full plugin bootstrap.

function createAuthResolvedConfig(overrides: Partial<AuthResolvedConfig>,): AuthResolvedConfig

Source: packages/slingshot-auth/src/config/authConfig.ts

Creates (or retrieves a cached) Mongoose AuthUser model on the given connection.

Checks conn.models['AuthUser'] before defining a new schema to avoid the “Cannot overwrite model once compiled” error in environments where modules are re-evaluated (e.g. hot reload, test runners that re-import modules between tests). When absent, defines the schema and registers the model on the connection.

Remarks: Model caching is per-connection: two different Connection instances each get their own independent model registration. This is intentional — each createApp() call in a multi-tenant setup receives its own Mongo connection and therefore its own model reference with zero cross-app state pollution.

Remarks: The schema uses { timestamps: true } so Mongoose automatically manages createdAt and updatedAt. The providerIds array carries a sparse unique multikey index so each external OAuth identity can belong to only one local user, while email and identifier use sparse unique indexes so null values do not collide.

function createAuthUserModel(conn: Connection, mongooseInstance: Mongoose,): Model<AuthUserDocument>

Source: packages/slingshot-auth/src/models/AuthUser.ts

Creates a fully in-memory AuthAdapter plus synchronous session accessor methods (MemoryAuthStores) for test introspection.

All state is closure-owned — each call returns an independent instance with its own user, session, role, group, and M2M client stores. No module-level mutable state.

Suitable for:

  • Unit and integration tests (create a fresh instance per suite)
  • Development with ephemeral data
  • Benchmarks that need zero I/O overhead
function createMemoryAuthAdapter(getConfig?: () => AuthResolvedConfig, passwordRuntime?: RuntimePassword,): AuthAdapter & MemoryAuthStores

Source: packages/slingshot-auth/src/adapters/memoryAuth.ts

Create an isolated in-memory provider-connection store for development and tests.

function createMemoryProviderConnectionStore(): ProviderConnectionStore

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Creates a MongoDB-backed AuthAdapter using Mongoose.

Manages users, roles, groups, group memberships, M2M clients, and tenant roles in separate collections on the provided connection. All models are registered on conn only — the global mongoose.models registry is not touched.

Remarks: Requires mongoose peer dependency (>=9.0). Not supported in the Bun SQLite-only bundle.

function createMongoAuthAdapter(conn: import('mongoose').Connection, mg: typeof import('mongoose'), passwordRuntime?: RuntimePassword,): AuthAdapter

Source: packages/slingshot-auth/src/adapters/mongoAuth.ts

Creates a MongoDB-backed session repository using Mongoose.

Registers (or reuses) the Session model on the provided connection. Uses MongoDB transactions for atomic session creation when a maxSessions limit is enforced. A TTL index on expiresAt (expireAfterSeconds: 0) handles natural expiration unless persistSessionMetadata is enabled, in which case the TTL index is omitted and expired tokens are nulled out instead of deleted.

Remarks: Requires mongoose 9+. The Session model is registered on the provided connection only — it does not pollute the global mongoose.models registry.

function createMongoSessionRepository(conn: import('mongoose').Connection, mg: typeof import('mongoose'),): SessionRepository

Source: packages/slingshot-auth/src/lib/session/mongoStore.ts

Creates a Redis-backed session repository.

Sessions are stored as JSON strings keyed by session:{appName}:{sessionId}. User-to-session indexes use a sorted set keyed by score = createdAt (epoch ms), enabling O(log N) oldest-session eviction. Refresh token lookup uses a separate key per token hash.

Atomic session creation and TTL management use Lua scripts to ensure consistency under concurrent requests.

Remarks: Requires ioredis 5+. The appName must be stable across deployments — changing it invalidates all existing session keys.

function createRedisSessionRepository(getRedis: () => RedisLike, appName: string,): SessionRepository

Source: packages/slingshot-auth/src/lib/session/redisStore.ts

Stores a new session for a user. No capacity enforcement — use atomicCreateSession (via createSessionForUser) when you want oldest-session eviction.

async function createSession(repo: SessionRepository, userId: string, token: string, sessionId: string, metadata?: SessionMetadata, config?: AuthResolvedConfig,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Creates the slingshot-auth access provider for the built-in admin API.

Implements AdminAccessProvider by resolving the authenticated user’s roles from the auth adapter and building an AdminPrincipal from their profile. Returns null when the request has no authenticated user, causing the admin API to return 401.

Passed to createServer({ admin: { accessProvider: createSlingshotAuthAccessProvider() } }) to gate the built-in admin panel with standard session-based auth + role checks.

Remarks: getUser and getRoles on the adapter are called via optional chaining — adapters that omit these methods will return null (access denied) rather than throwing.

function createSlingshotAuthAccessProvider(): AdminAccessProvider

Source: packages/slingshot-auth/src/admin/slingshotAccess.ts

Creates a ManagedUserProvider that exposes slingshot-auth’s user store through the framework’s admin user management interface.

Provides list, get, update, suspend/unsuspend, delete, session management, and role management operations backed by the configured AuthAdapter and SessionRepository.

Registered automatically by bootstrapAuth when the admin API is enabled. Exposed publicly so advanced consumers can register it manually or substitute a custom provider.

Remarks: User listing is cursor-based (base64-encoded offset). The search parameter is passed as an email prefix filter when supported by the adapter’s listUsers implementation. The built-in slingshot-auth adapter does not partition users or sessions by tenant, so tenant-scoped admin requests fail closed: list/get/session/role operations return empty results and mutating operations no-op rather than leaking global auth state.

function createSlingshotManagedUserProvider(adapter: AuthAdapter, config: AuthResolvedConfig, sessionRepo: SessionRepository,): ManagedUserProvider

Source: packages/slingshot-auth/src/admin/slingshotUsers.ts

Creates a SQLite-backed AuthAdapter plus session helper methods for the bootstrap layer.

Runs schema migrations (runMigrations) at construction time and sets PRAGMA journal_mode = WAL and PRAGMA foreign_keys = ON for reliability. The adapter starts a periodic cleanup interval when startCleanup is called (done automatically during plugin bootstrap).

Remarks: Requires the bun:sqlite module or a compatible RuntimeSqliteDatabase implementation. Not supported in environments without SQLite support.

function createSqliteAuthAdapter(db: RuntimeSqliteDatabase, passwordRuntime?: RuntimePassword,): SqliteAuthResult

Source: packages/slingshot-auth/src/adapters/sqliteAuth.ts

Creates a SQLite-backed cache adapter.

Stores entries in an auth_cache table (created lazily on the first operation). TTL is tracked as a Unix-millisecond timestamp in the expiresAt column; expired rows are filtered at query time, not swept proactively.

Suitable for single-server deployments that already use SQLite for persistence and want durable caching across process restarts.

function createSqliteCacheAdapter(db: RuntimeSqliteDatabase): ICacheAdapter

Source: packages/slingshot-auth/src/lib/cache.ts

Create a durable provider-connection store backed by a runtime SQLite database.

function createSqliteProviderConnectionStore(db: RuntimeSqliteDatabase,): ProviderConnectionStore

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Creates a SQLite-backed session repository.

Creates the sessions table (and supporting indexes) if they do not already exist. Uses a WAL-compatible schema shared with createSqliteAuthAdapter — the table is safe to have created by either party.

Remarks: Initialization is lazy — the table is created on the first operation, not at construction time. This avoids issues when the database file is opened before migrations have run.

function createSqliteSessionRepository(db: RuntimeSqliteDatabase): SessionRepository

Source: packages/slingshot-auth/src/lib/session/sqliteStore.ts

Deletes (or tombstones) a single session.

When config.persistSessionMetadata is true, the session token and refresh tokens are nulled out but the metadata row is retained for auditing. Otherwise the row is deleted entirely.

async function deleteSession(repo: SessionRepository, sessionId: string, config?: AuthResolvedConfig,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Deletes the oldest active session for a user.

Used internally by the session capacity enforcement path when the per-user session limit (maxSessions) would be exceeded by a new login.

async function evictOldestSession(repo: SessionRepository, userId: string, config?: AuthResolvedConfig,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Returns the number of currently active sessions for a user.

async function getActiveSessionCount(repo: SessionRepository, userId: string, config?: AuthResolvedConfig,): Promise<number>

Source: packages/slingshot-auth/src/lib/session/index.ts

Returns the current request’s actor when it is an authenticated user (kind 'user' with a non-null id), otherwise null.

function getAuthenticatedUserActor(c: Parameters<typeof getActor>[0],): AuthenticatedUserActor | null

Source: packages/slingshot-auth/src/middleware/userAuth.ts

Retrieves the AuthRuntimeContext from plugin state.

Use this inside framework-level code that has access to the per-app pluginState map directly (e.g., setupPost hooks, admin providers, or server-side utilities).

function getAuthRuntimeContext(input: PluginStateMap | PluginStateCarrier | object | null | undefined,): AuthRuntimeContext

Source: packages/slingshot-auth/src/runtime.ts

Retrieves the AuthRuntimeContext from plugin state when auth has published it.

Returns null instead of throwing so optional-auth bootstrap paths can fail closed without digging through raw pluginState entries.

function getAuthRuntimeContextOrNull(input: PluginStateMap | PluginStateCarrier | object | null | undefined,): AuthRuntimeContext | null

Source: packages/slingshot-auth/src/runtime.ts

Resolves the request’s AuthRuntimeContext, throwing if the auth plugin has not been initialised.

function getAuthRuntimeFromRequest(c: { get(key: string): unknown }): AuthRuntimeContext

Source: packages/slingshot-auth/src/runtime.ts

Retrieves the AuthRuntimeContext from a Hono request context.

Use this inside Hono route handlers and middleware. This resolves the current request’s app pluginState and returns the auth runtime published into it.

function getAuthRuntimeFromRequestOrNull(c: { get(key: string): unknown; }): AuthRuntimeContext | null

Source: packages/slingshot-auth/src/runtime.ts

Returns the Unix epoch timestamp (seconds) when MFA was last verified for a session, or null if MFA has not been completed in this session.

async function getMfaVerifiedAt(repo: SessionRepository, sessionId: string,): Promise<number | null>

Source: packages/slingshot-auth/src/lib/session/index.ts

Retrieves the JWT token for an active, non-expired session.

Returns null if the session does not exist, has expired, or has exceeded the configured idle timeout. The idle check is enforced inline — an expired-by-idle session is deleted and null is returned.

async function getSession(repo: SessionRepository, sessionId: string, config?: AuthResolvedConfig,): Promise<string | null>

Source: packages/slingshot-auth/src/lib/session/index.ts

Looks up a session by its refresh token, supporting a short grace window after rotation.

Returns null if the token is unknown, expired, or has been superseded by more than the configured grace period (config.refreshToken.rotationGraceSeconds).

If the token matches the previous (rotated-away) token and is still within the grace window, fromGrace: true is set on the result — the caller should re-issue the current token rather than rotating again.

async function getSessionByRefreshToken(repo: SessionRepository, refreshToken: string, config?: AuthResolvedConfig,): Promise<RefreshResult | null>

Source: packages/slingshot-auth/src/lib/session/index.ts

Retrieves the stored session fingerprint, or null if none is set.

The fingerprint is a SHA-256 hash of the client’s binding fields (IP address, user-agent, etc.) configured via signing.sessionBinding. It is set at session creation time and re-verified on every authenticated request.

async function getSessionFingerprint(repo: SessionRepository, sessionId: string,): Promise<string | null>

Source: packages/slingshot-auth/src/lib/session/index.ts

Returns the tenant-scoped roles for a user in a specific tenant.

Delegates to adapter.getTenantRoles. The returned array may be empty when the user has no tenant-specific roles.

async function getTenantRoles(userId: string, tenantId: string, adapter?: AuthAdapter,): Promise<string[]>

Source: packages/slingshot-auth/src/lib/roles.ts

Lists sessions for a user, filtered by the active/inactive policy in config.

Active sessions have a non-null token and have not expired. Inactive sessions are included only when config.includeInactiveSessions is true and config.persistSessionMetadata is true.

async function getUserSessions(repo: SessionRepository, userId: string, config?: AuthResolvedConfig,): Promise<SessionInfo[]>

Source: packages/slingshot-auth/src/lib/session/index.ts

Store factories for provider connections. Durable long-lived secrets fit sqlite (and memory for dev/tests); redis/mongo/postgres backends are not implemented yet and throw with a clear message at resolve time — which only happens when an app on one of those backends actually configures connections.

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Auth-specific publish helper. Many auth delivery.* events fire from non-HTTP code paths (background workers, retry queues) where no request tenant exists, so this wrapper defaults requestTenantId to null and accepts a partial context. HTTP-route callers should always pass { requestTenantId: getRequestTenantId(c), ... } so request-scoped tenant flows through the envelope.

function publishAuthEvent<K extends AuthManagedEventKey>(events: SlingshotEvents, key: K, payload: SlingshotEventMap[K], ctx?: Partial<EventPublishContext>,): void

Source: packages/slingshot-auth/src/eventGovernance.ts

Registers the auth package’s managed event definitions on the given event publisher, skipping any already registered.

function registerAuthEventDefinitions(events: SlingshotEvents): void

Source: packages/slingshot-auth/src/eventGovernance.ts

Removes a single tenant-scoped role from a user within a tenant.

Delegates to adapter.removeTenantRole, then emits a security.admin.role.changed event with scope: "tenant" and action: "remove".

async function removeTenantRole(userId: string, tenantId: string, role: string, changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Removes a single app-level role from a user.

Delegates to adapter.removeRole, then emits a security.admin.role.changed event with action: "remove".

async function removeUserRole(userId: string, role: string, changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Renders an EmailTemplate by substituting {{variableName}} placeholders with the provided variable values. Placeholders with no corresponding key are left unchanged.

HTML body values are HTML-escaped to prevent XSS injection. The subject and text fields are plain text and are substituted without escaping.

function renderTemplate(template: EmailTemplate, vars: TemplateVariables): EmailTemplate

Source: packages/slingshot-auth/src/lib/emailTemplates.ts

Middleware factory that enforces role-based access control (RBAC).

Must be used after userAuth (requires an authenticated actor). Resolves the user’s effective role set for the authenticated user actor and returns 403 Forbidden when none of the required roles are present.

Effective roles are written to the actor via c.set('actor', ...) for downstream handlers.

When a tenant context is active (actor has a tenantId), role resolution is scoped to that tenant. Use requireRole.global() to bypass tenant scoping and enforce app-wide roles only.

Source: packages/slingshot-auth/src/middleware/requireRole.ts

Atomically rotates a refresh token: issues a new token, archives the old one into a short grace window, and updates the access token stored in the session.

Implements a concurrent-request guard: if oldRefreshToken is provided, the rotation only succeeds when the session’s current token still matches — preventing double-rotation race conditions. Pass undefined for oldRefreshToken when re-rotating from within the grace window (the guard is skipped).

On success, also updates lastActiveAt on the session.

async function rotateRefreshToken(repo: SessionRepository, sessionId: string, oldRefreshToken: string | undefined, newRefreshToken: string, newAccessToken: string, config?: AuthResolvedConfig,): Promise<boolean>

Source: packages/slingshot-auth/src/lib/session/index.ts

RepoFactories dispatch map for SessionRepository.

Passed to resolveRepo(sessionFactories, storeType, infra) in the bootstrap layer to instantiate the correct backend based on the configured db.sessions store type.

Supported store types: 'memory' | 'sqlite' | 'redis' | 'mongo' | 'postgres'.

Source: packages/slingshot-auth/src/lib/session/factories.ts

Marks the current time as the MFA verification timestamp for a session.

Used by step-up auth and MFA flows to record when the user last completed a second-factor challenge. The timestamp (Unix epoch seconds) is compared against config.stepUp.maxAge on protected routes.

async function setMfaVerifiedAt(repo: SessionRepository, sessionId: string,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Associates a refresh token with an existing session.

The token is stored hashed (SHA-256). The plain value is never persisted after this point — the caller must return it to the client immediately.

async function setRefreshToken(repo: SessionRepository, sessionId: string, refreshToken: string, config?: AuthResolvedConfig,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Stores a session fingerprint for subsequent binding verification.

Called at session creation time (with fields derivable from session metadata) and on the first authenticated request when runtime fields like Accept-Language are needed.

async function setSessionFingerprint(repo: SessionRepository, sessionId: string, fingerprint: string,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Replaces the full set of tenant-scoped roles for a user within a tenant.

Delegates to adapter.setTenantRoles, then emits a security.admin.role.changed event with scope: "tenant" and action: "set".

async function setTenantRoles(userId: string, tenantId: string, roles: string[], changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Replaces the full set of app-level roles for a user.

Delegates to adapter.setRoles, then emits a security.admin.role.changed event with action: "set" so the role change is auditable.

async function setUserRoles(userId: string, roles: string[], changedBy?: string, adapter?: AuthAdapter, eventBus?: SlingshotEventBus,): Promise<void>

Source: packages/slingshot-auth/src/lib/roles.ts

Signs a JWT with the configured algorithm and expiry.

Every token includes iat (issued at), nbf (not before, set to iat), exp (expiry), and jti (unique token ID for replay detection). Supports HMAC algorithms (HS256/HS384/HS512) and RS256 (OIDC). For RS256, an OIDC key must be loaded via loadJwksKey() before calling this function.

Remarks: RS256 key selection: when config.jwt.algorithm is "RS256", the signing parameter is ignored entirely. The private key is read from the OIDC key store loaded by loadJwksKey(). All entries in signing.secret (including rotated secrets) are irrelevant for RS256 — only the RSA private key matters. The signed token uses the configured OIDC signing-key kid in the protected header for JWKS resolution by relying parties.

Remarks: For HMAC algorithms (HS256, HS384, HS512), signing.secret[0] is used as the signing secret. Rotated secrets (indices 1+) are only used for verification, never for signing — all new tokens are always signed with the first secret.

async function signToken(claims: TokenClaims, expirySeconds: number | undefined, config: AuthResolvedConfig, signing?: SigningConfig | null,): Promise<string>

Source: packages/slingshot-auth/src/lib/jwt.ts

Updates the lastActiveAt timestamp for a session.

Called on every authenticated request when config.trackLastActive is enabled, and automatically by rotateRefreshToken. Required for idle-timeout enforcement (config.sessionPolicy.idleTimeout).

async function updateSessionLastActive(repo: SessionRepository, sessionId: string, config?: AuthResolvedConfig,): Promise<void>

Source: packages/slingshot-auth/src/lib/session/index.ts

Hono middleware that enforces authentication on a route.

Checks that the current actor is an interactive user (actor.kind === 'user') with a non-null ID as resolved by the identify middleware. Machine-to-machine service accounts and static API-key actors are intentionally rejected; use M2M scope guards or bearer auth for those routes instead.

Remarks: This middleware does not verify the JWT itself — that is done by identify during the setupMiddleware phase. userAuth is a lightweight gate that checks whether identification succeeded as a user actor.

Source: packages/slingshot-auth/src/middleware/userAuth.ts

Validates that the configured AuthAdapter implements all methods required by the enabled feature set. Collects every missing-method error before throwing so developers see the complete list in a single startup failure.

Called automatically by bootstrapAuth and not normally called directly by consumers.

function validateAdapterCapabilities(adapter: AuthAdapter, cfg: AdapterValidationConfig,): void

Source: packages/slingshot-auth/src/lib/validateAdapter.ts

Verifies a JWT and returns its decoded payload.

Validates the signature, expiry, issuer, and audience (when configured). For RS256, all loaded public keys are tried in order — supports key rotation with zero downtime.

Remarks: Clock tolerance: verification allows a configurable clock skew window (config.jwt.clockTolerance, default 60 seconds) so that minor clock drift between services does not reject valid tokens. Set to 0 to disable.

Remarks: RS256 key rotation: when config.jwt.algorithm is "RS256", this function iterates over all public keys loaded by loadJwksKey() in order and tries each one. The first key that produces a valid signature wins. Keys that fail are silently skipped (continue). This allows zero-downtime key rotation: add the new key to the JWKS endpoint, wait for tokens signed with the old key to expire naturally, then remove the old key. Tokens signed with either key will verify successfully during the overlap window.

Remarks: If no loaded key validates the token, the function throws "JWT verification failed with all available keys".

Remarks: HMAC key rotation: when signing.secret is an array, all secrets are tried in order during verification. signing.secret[0] is the active signing key; indices 1+ are previous keys kept for verification during rotation windows. Deploy a new secret at index 0 and move the old secret to index 1 — existing tokens will continue to verify until they expire naturally.

async function verifyToken(token: string, config: AuthResolvedConfig, signing?: SigningConfig | null,): Promise<JWTPayload>

Source: packages/slingshot-auth/src/lib/jwt.ts

Canonical error response schema shared across all standard auth routes.

Exported for use in OpenAPI/Zod-based API documentation and custom route handlers that want to return errors in the same shape as the built-in auth endpoints.

M2M routes use RFC 6749 error shapes and SCIM routes use RFC 7644 shapes — neither uses this schema.

FieldDescription
errorHuman-readable error message.

Source: packages/slingshot-auth/src/schemas/error.ts

Built-in auth email templates keyed by name.

Available templates and their required variables:

  • emailVerification{{appName}}, {{verificationLink}}, {{expiryMinutes}}
  • passwordReset{{appName}}, {{resetLink}}, {{expiryMinutes}}
  • magicLink{{appName}}, {{magicLink}}, {{expiryMinutes}}
  • emailOtp{{appName}}, {{code}}, {{expiryMinutes}}
  • welcomeEmail{{appName}}, {{identifier}}
  • accountDeletion{{appName}}, {{cancelLink}}, {{gracePeriodHours}}
  • orgInvitation{{appName}}, {{orgName}}, {{invitationLink}}, {{expiryDays}}

All templates use inline CSS only — no external CDN dependencies. Override individual templates via AuthPluginConfig.emailTemplates.

Source: packages/slingshot-auth/src/lib/emailTemplates.ts

Account deletion policy configuration.

Controls whether DELETE /auth/me is available and how deletion is executed. Supports immediate deletion, queued deletion (with a grace period and cancel link), and lifecycle hooks for pre/post deletion logic.

Source: packages/slingshot-auth/src/config/authConfig.ts

Feature-flag snapshot used to drive validateAdapterCapabilities.

Each boolean corresponds to one or more enabled features that require specific methods on the AuthAdapter. This snapshot is computed once during bootstrap from the resolved AuthPluginConfig and passed to validateAdapterCapabilities at startup.

Remarks: Exposed publicly so consumers who build custom bootstrap flows (outside createAuthPlugin) can construct and pass this config directly to validateAdapterCapabilities.

Source: packages/slingshot-auth/src/lib/validateAdapter.ts

Core authentication feature configuration.

Top-level container for all behavioral auth settings: roles, OAuth, email verification, password policy, MFA, JWT, session policy, rate limiting, magic links, SAML, SCIM, OIDC, M2M, step-up auth, and lifecycle hooks.

Remarks: Most fields are optional and have sensible defaults. Set enabled: false to mount the plugin without registering any auth routes (useful when you only want middleware such as userAuth and requireRole).

Source: packages/slingshot-auth/src/types/config.ts

Cookie attributes for the HttpOnly session authentication cookie.

httpOnly is always true and cannot be overridden — the auth cookie must never be accessible to JavaScript. All other attributes can be tuned per-deployment. Set via AuthConfig.cookieConfig.

Remarks: In production, secure is always required (HTTPS-only), including when TLS terminates at a load balancer. SameSite=None also requires secure: true.

Source: packages/slingshot-auth/src/config/authConfig.ts

Database/store connection configuration for slingshot-auth.

Controls which persistence backends are used for sessions, OAuth state, and the user auth adapter. Each field is optional — defaults are chosen by the bootstrap layer based on what is available (Redis → SQLite → memory).

Remarks: When running under the full framework (createApp / createServer), connection objects are provided automatically via SlingshotFrameworkConfig. These fields are only relevant in standalone mode or when explicitly overriding framework-provided connections.

Source: packages/slingshot-auth/src/types/config.ts

Per-endpoint rate limiting configuration for auth routes.

Each key corresponds to an auth route family. When omitted, a sensible built-in default is used. Set store: 'redis' for multi-instance deployments so counters are shared across all server processes.

Source: packages/slingshot-auth/src/config/authConfig.ts

Read-only, deep-frozen snapshot of all resolved auth configuration values.

Built once during plugin bootstrap by createAuthResolvedConfig, then attached to AuthRuntimeContext as runtime.config. Every field has a concrete default — no optional properties. Consumers should read from runtime.config rather than keeping their own copies of plugin config.

Remarks: The object is deep-frozen at creation time. Any attempt to mutate it in strict mode throws a TypeError. Internal defaults are provided by DEFAULT_AUTH_CONFIG.

Source: packages/slingshot-auth/src/config/authConfig.ts

Per-app auth runtime state, created by bootstrapAuth and stored in pluginState under the AUTH_RUNTIME_KEY symbol.

Access it via getAuthRuntimeContext(ctx.pluginState) from plugin setup code, getAuthRuntimeContext(ctx) from any object that carries pluginState, or getAuthRuntimeFromRequest(c) from a Hono request context inside an auth route.

All properties are readonly. The config object is deep-frozen. The repos map contains the resolved storage adapters for all auth sub-systems.

Remarks: This interface is intentionally wide — it is the single source of truth for all auth runtime state. Plugin-layer code should prefer this over storing state in module-level variables. Every createAuthPlugin() call produces an independent AuthRuntimeContext instance (Rule 3 — no cross-app state pollution).

Source: packages/slingshot-auth/src/runtime.ts

Security configuration for slingshot-auth.

Controls JWT signing, CSRF protection, bearer token auth, captcha integration, trust-proxy behavior, and CORS origins used for CSRF origin checking.

Source: packages/slingshot-auth/src/types/config.ts

Session lifecycle and capacity policy configuration.

Controls session limits, metadata persistence, idle/absolute timeouts, and what happens to sessions on password change. Set via AuthConfig.sessionPolicy.

Remarks: Setting idleTimeout automatically enables trackLastActive. The onPasswordChange policy defaults to 'revoke_others' — always revoke at minimum after a password change to prevent session hijacking via old credentials.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for breached password detection via the HaveIBeenPwned API.

When set on AuthConfig.breachedPasswordCheck, registration and password-reset attempts are checked against the HIBP k-Anonymity API. Matching passwords can be blocked or allowed based on block and onApiFailure policy.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for concealing registration conflicts from potential attackers.

When set, a registration attempt for an already-existing identifier returns a success response (same shape as a new registration) instead of a conflict error. This prevents user enumeration via the registration endpoint.

Source: packages/slingshot-auth/src/config/authConfig.ts

Cookie attributes for the CSRF double-submit cookie.

httpOnly is always false — JavaScript must be able to read this cookie to set the x-csrf-token request header. Set via AuthConfig.csrfCookieConfig.

Remarks: The CSRF cookie is signed with HMAC-SHA256 (server secret) so tampering is detectable. The client must echo it back in the x-csrf-token header on every state-changing request.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for the email verification flow.

When enabled, a verification token is emailed to the user after registration. Set required: true to block login until the user verifies their email address.

Source: packages/slingshot-auth/src/config/authConfig.ts

Request-scoped context passed to auth lifecycle hooks.

Allows hooks to record security events with the originating IP, user-agent, and request ID for audit trails. All fields are optional — hooks must handle absence gracefully.

Source: packages/slingshot-auth/src/config/authConfig.ts

JWT signing configuration.

Controls the algorithm, issuer, and audience claims added to all signed tokens. When algorithm is 'RS256', the OIDC key pair is used for signing (requires auth.oidc to be configured). Set via AuthConfig.jwt.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for passwordless magic-link sign-in.

When set, the POST /auth/magic-link/send and POST /auth/magic-link/verify routes are mounted. A single-use link containing a time-limited token is emailed to the user.

Source: packages/slingshot-auth/src/config/authConfig.ts

Synchronous, direct-access methods that bypass the SessionRepository interface.

Exposed alongside the AuthAdapter by createMemoryAuthAdapter for use in tests that need precise control over session state — for example, pre-seeding a session without going through the async createSession path, or reading raw session records to assert on fingerprint or MFA state.

Remarks: These methods operate directly on the adapter’s closure-owned Maps. They do not apply any config-driven TTL or eviction logic — use them only in tests.

Source: packages/slingshot-auth/src/adapters/memoryAuth.ts

Multi-factor authentication configuration.

When set on AuthConfig.mfa, the MFA routes are mounted (/auth/mfa/...). TOTP is always available. Add emailOtp or webauthn for additional factor options. Set required: true to enforce MFA setup before users can access non-auth endpoints.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for email-based OTP as a second MFA factor.

When set on MfaConfig.emailOtp, users can choose email OTP as their second factor in addition to TOTP. The OTP code is emailed via the configured mail provider.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for WebAuthn (FIDO2) as a second MFA factor.

When set on MfaConfig.webauthn, the plugin mounts WebAuthn registration and authentication routes. Requires the @simplewebauthn/server peer dependency. Set allowPasswordlessLogin: true to additionally mount passkey first-factor routes.

Source: packages/slingshot-auth/src/config/authConfig.ts

OAuth provider configuration for slingshot-auth.

Enables one or more social login providers (Google, GitHub, Apple, etc.) via the optional @lastshotlabs/slingshot-oauth package. Requires slingshot-oauth to be installed — startup throws if providers are configured but the package is missing.

Source: packages/slingshot-auth/src/types/config.ts

OpenID Connect provider configuration.

When enabled, slingshot-auth exposes a standards-compliant OIDC discovery document at /.well-known/openid-configuration and signs JWTs with RS256. Requires auth.jwt.algorithm to be set to "RS256".

If no signingKey is provided outside production, an RSA key pair is auto-generated at startup for local development. Production requires a stable signing key so tokens and JWKS remain valid across restarts and instances.

Source: packages/slingshot-auth/src/config/authConfig.ts

Configuration for the password reset flow.

When set on AuthConfig.passwordReset, the POST /auth/forgot-password and POST /auth/reset-password routes are mounted. Requires primaryField === 'email'.

Source: packages/slingshot-auth/src/config/authConfig.ts

A user’s stored connection to a third-party provider.

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Storage contract for provider connections.

One row per (userId, provider); upsert replaces tokens on re-consent. Tokens are secrets — implementations must never log them, and read paths that serve HTTP responses must go through the sanitized projections in slingshot-oauth (which strip token fields).

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Configuration for the sliding refresh token rotation flow.

When set on AuthConfig.refreshTokens, the plugin issues a short-lived JWT access token alongside a long-lived refresh token. Clients exchange expired access tokens for new ones at POST /auth/refresh. Rotation is atomic — the old refresh token is archived in a short grace window before invalidation.

Source: packages/slingshot-auth/src/config/authConfig.ts

SAML 2.0 Service Provider configuration.

When set on AuthConfig.saml, the plugin mounts SAML SP routes (/auth/saml/...). The IdP metadata is required — provide either an XML string or a URL from which it will be fetched at startup.

Remarks: The SP signing key (signingKey/signingCert) is optional but strongly recommended for production: without it, AuthnRequests are unsigned and assertions are not verified beyond XML schema validation.

Source: packages/slingshot-auth/src/config/authConfig.ts

SCIM 2.0 provisioning endpoint configuration.

When enabled, the plugin mounts a SCIM 2.0-compliant user provisioning endpoint (/scim/v2/Users). SCIM allows identity providers (Okta, Azure AD, etc.) to automatically create, update, and deprovision user accounts.

Remarks: Requires the adapter to implement getUser for RFC 7644 §3.6 DELETE compliance. The bearerTokens field is required — SCIM endpoints must be authenticated.

Source: packages/slingshot-auth/src/config/authConfig.ts

A security event payload delivered to SecurityEventsConfig.onEvent.

eventType is one of the known SecurityEventKey values (e.g. 'security.auth.login.failure'). severity is derived from a fixed mapping per event type. All other fields are optional and populated from the request context when available.

Additional properties (e.g. identifier, reason) may be present in the meta field for certain event types. The index signature allows forward-compatible access.

Source: packages/slingshot-auth/src/lib/securityEventWiring.ts

Configuration for the security event tap.

When provided via AuthPluginConfig.securityEvents, every security event emitted by the auth plugin is forwarded to onEvent after being enriched with severity, timestamp, and contextual fields. Use this to ship events to a SIEM, audit log, or alerting system.

Source: packages/slingshot-auth/src/lib/securityEventWiring.ts

Configuration for step-up authentication.

When set on AuthConfig.stepUp, the POST /auth/step-up route is mounted. Routes protected by step-up verification require the user to complete MFA within the last maxAge seconds before proceeding.

Source: packages/slingshot-auth/src/config/authConfig.ts

Variable substitution map passed to renderTemplate. Keys correspond to {{variableName}} placeholders; values are coerced to strings.

Source: packages/slingshot-auth/src/lib/emailTemplates.ts

Full plugin configuration object for createAuthPlugin.

Combines the Zod-validated base config with the runtime field (standalone-only dependencies injected outside of Zod validation).

Source: packages/slingshot-auth/src/types/config.ts

A static email template (subject/html/text) registered by a plugin and consumed by the mail plugin.

Source: packages/slingshot-core/src/emailTemplates.ts

The primary identifier field for user accounts.

Controls which field is used as the login identifier — email address, username, or phone number. Defaults to 'email'. Set via AuthConfig.primaryField.

Source: packages/slingshot-auth/src/config/authConfig.ts

Input for upsert — timestamps are store-managed.

Source: packages/slingshot-auth/src/lib/providerConnections.ts

Generates a cryptographically random PKCE code verifier.

Required for OAuth providers that support PKCE (e.g. Google, GitHub). Store the verifier alongside the state in OAuthStateStore.store() before the redirect, then pass it to the token exchange call on callback. Re-exported from the arctic library.

Source: packages/slingshot-auth/src/lib/oauth.ts

Generates a cryptographically random OAuth state parameter for CSRF protection.

The state string should be stored in OAuthStateStore.store() before redirecting the user to the provider’s authorization URL. On callback, verify it with OAuthStateStore.consume(). Re-exported from the arctic library.

Source: packages/slingshot-auth/src/lib/oauth.ts