Server sign-in verification requires nonce-domain binding by default. Issue nonces with the expected app domain and verify only messages with the same domain.
await auth.issueNonce({
domain: "example.com",
chainType: "evm",
address,
walletName
});If a nonce is issued without a domain, verifySignIn rejects it with
Nonce domain is required. This protects against phishing flows where a message
from one origin is replayed against another.
Nonces are random, expiring, and single-use.
InMemoryNonceStoreis for local development and tests.RedisNonceStoreadapts Redis-like clients for deployed apps.- Production Redis deployments should use atomic consume semantics. If your client cannot guarantee atomic get-and-delete behavior, wrap consume in a Lua script or equivalent transaction.
createServerAuth rejects short or obvious JWT secrets in production. Use at
least 32 high-entropy characters, rotate secrets through your deployment secret
manager, and avoid committing secrets.
createServerAuth({
jwtSecret: process.env.DOLPHIN_JWT_SECRET ?? "",
runtimeEnvironment: process.env.NODE_ENV
});allowWeakJwtSecret exists only for reviewed exceptions and local test harnesses.
Use createSessionCookieOptions for cookie-backed sessions and rotating refresh
tokens.
const cookie = createSessionCookieOptions({
runtimeEnvironment: process.env.NODE_ENV,
expires: session.expiresAt
});Defaults:
HttpOnly: trueSecure: truein productionSameSite: "lax"Path: "/"
If you set SameSite=None, the cookie must also be Secure. Cookie-backed apps
should still protect unsafe methods with CSRF tokens, same-site request checks,
or framework-native CSRF middleware.
createServerAuth issues a refresh token alongside each successful sign-in.
Refresh tokens have a configurable refreshTokenTtlSeconds window and rotate on
each successful refreshSession call.
const refreshed = await auth.refreshSession({ refreshToken });The previous refresh token is marked rotated and cannot be reused. Reuse, revocation, expiration, and unknown-token cases are rejected.
Use invalidateSessions(subject) for server-side forced logout. It increments a
per-subject session version and revokes outstanding refresh tokens, so existing
access tokens fail verifySession and existing refresh tokens fail
refreshSession.
Production origins must use HTTPS. assertProductionSafeUrl rejects HTTP unless
allowInsecureHttp is explicitly set for a reviewed exception.
createServerAuth({
jwtSecret,
runtimeEnvironment: "production",
publicOrigin: "https://example.com"
});Hosted projects must use exact normalized allow-list entries such as
example.com or example.com:443. URL strings, wildcard domains, paths,
credentials, empty allow-lists, and invalid ports are rejected.
createHostedAuthService should receive runtimeEnvironment: "production" and
a high-entropy jwtSecret in deployed environments. Without a strong secret,
the hosted service refuses to construct the default server auth core in
production.
Hosted sessions are scoped to the project that verified the login. A session token produced for one hosted project cannot be read through another project's API key, even when both projects use the same underlying auth core.
Failure paths for authenticated hosted projects are audit-logged for nonce issue, verification, and session reads. Audit events intentionally do not store raw API keys, refresh tokens, or session tokens.
See v1.0 security audit summary for the release audit scope, remediated findings, accepted risks, and public release notes.