The security helper surface: hardening primitives, the SSRF and open-redirect guards, cookie helpers, JWT/JWK verification, temporal claim assertions, security-scheme builders, sessions, and password hashing. Unless noted, these are exported from the root @daloyjs/core barrel (sessions and hashing also ship as their own subpaths). See the API reference overview for the module map.
Inbound primitives sanitize what arrives, egress guards constrain where your app can send users and requests, and the credential helpers verify who is calling.
✓Service-to-service tokens between backends you own and deploy together.
✓Short-lived signed URLs for a download, an upload, or a one-time confirmation link.
✓Signing a webhook payload so the receiver can verify the sender.
✓Test fixtures and local development, where you need a valid token without reaching a provider.
You are building an identity provider
✗Minting an access or refresh token after checking a password you stored yourself.
✗Adding refresh-token rotation, reuse detection, and a revocation list on top of it.
✗Serving the public half of your signing key as a JWKS for other services to trust.
✗Adding sessions per device, step-up authentication, or sign-out everywhere.
The moment the right-hand column starts appearing in your backlog, you are maintaining an identity provider as a side project. Hand the issuing role to a real one and keep createJwtVerifier() on the receiving end. See Auth architecture.
passwordHash(password: string): Promise<string>; // scrypt with random salt + per-hash params; returns a self-describing PHC string. // Throws TypeError on empty input or passwords over 4096 UTF-8 bytes // (the cap blocks scrypt CPU-amplification abuse).passwordVerify(password: string, hash: string): Promise<boolean>; // timing-safe comparison; refuses to verify when scrypt parameters are below // the secure floor (forces a rehash via your application logic). // Returns false (never throws) for empty or over-4096-byte passwords.