Protect a DaloyJS API with Auth0
Auth0 is a developer-friendly IdP that handles universal login, MFA, social login, and a rich rule/action engine. For backend protection, Auth0's official quickstart uses express-oauth2-jwt-bearer, which is Express-only. DaloyJS isn't Express, so we use the same primitive, JWT verification against Auth0's JWKS, through jose. That keeps the same security guarantees while running on every runtime DaloyJS targets, including the edge.
- 01requestClient appAuth0 tenantUniversal Login (authorization-code + PKCE)Auth0 owns login, MFA, social
- 02responseAuth0 tenantClient appAccess token (RS256 JWT, aud = your API)
- 03requestClient appDaloyJS APIRequest with Authorization: Bearer <token>
- 04asyncDaloyJS APIAuth0 JWKSFetch signing keys (cached by jose)GET /.well-known/jwks.json
- 05responseDaloyJS APIClient appjwtVerify checks iss (trailing slash), aud, RS256, then scopes401 on a bad token, 403 on a missing scope
1. Configure an Auth0 API
- In the Auth0 dashboard, go to Applications → APIs → Create API. Pick an identifier (e.g.
https://api.acme.example.com), this becomes theaudclaim on issued tokens. - Define permissions (e.g.
read:items,write:items) and enable RBAC + Add Permissions in the Access Token if you want them inpermissions. - Note your tenant's domain (e.g.
dev-abc123.us.auth0.com). Your issuer ishttps://{domain}/(trailing slash).
2. Install
3. Environment variables
4. Plugin
5. Guard a route
Permissions (RBAC)
If you enabled Add Permissions in the Access Token, the JWT carries a permissions array. Tighten the overview's requireAuth to check principal.permissions when you want to enforce role assignments rather than OAuth 2.0 scopes:
Auth0 Actions & custom claims
Add custom claims through an Action on the Login flow. Namespace them (e.g. https://acme.example.com/tenant) per Auth0's rules, that prevents collisions with standard claims and is required for non-reserved claims to be included.
Runtimes
jose uses Web Crypto, so this setup runs on Node 18+, Bun, Deno, Cloudflare Workers, Vercel, and AWS Lambda. No need to swap libraries between environments.
Notes
- The
issclaim Auth0 issues includes a trailing slash. Mismatching it (with or without the slash) is a common cause of validation failures. - Set a non-empty audience on the API, without it Auth0 returns an opaque token that you can't verify locally.
- For sensitive operations, also check Auth0's
azp(authorized party) claim against your allowed client IDs.
See also Okta, Clerk, and the auth integrations overview.