Concepts & glossary
WIPThe vocabulary - AAL, AMR, transport, provider, channel, facet, freshness, step-up - all defined in one place.
The vocabulary
Authentication has more jargon than most domains. This page is the glossary - every term used elsewhere in the docs, with a one-paragraph definition and a pointer to the deep-dive.
Core terms
AuthEngine
The single runtime entry point. You construct it once at boot with all config (transport, stores, providers, channels, presets) and pass it to every framework adapter, server handler, and client mount.
See Core overview ->.
Facet
A typed sub-object on AuthEngine exposing a single concern (sessions,
identities, passwords, providers, MFA, flows, API keys, M2M, orgs,
plugins, operations, idempotency, hijack, anomaly). All 14 facets are
described in Core overview.
Identity
A long-lived "who" record. Identified by an email or provider-sub.
Carries a typed Profile (your domain's per-user data) plus metadata
(emailVerified, tenantId, createdAt, deletedAt). Identities
outlive sessions.
See Identities ->.
Session
A short-lived "this caller, right now" record. Created by sign-in,
rotated on privilege change, revoked on sign-out. Carries aal,
amr, lastReauthAt, expiresAt. Sessions ride on a Transport.
See Sessions ->.
Credential
The hashed material that proves a sign-in factor - a password hash, a
passkey public key, a magic-link token hash, an API-key hash, a TOTP
secret. Stored in the credentials store, keyed by identityId plus
a typed kind.
Provider
An object that knows how to sign someone in. Implements a two-step
begin/complete interface. duck-auth ships password, magic-link,
six OAuth providers, passkeys, API keys, and SAML.
See Providers ->.
Channel
An outbound message transport - SMTP, Resend, SES, Twilio, WebPush, or Console. Channels deliver magic links, password resets, verification emails, and MFA codes.
See Channels ->.
Transport
The bridge between in-memory Session and the wire. Cookie, Bearer,
JWT, or Composite. Optionally bound to a client public key via DPoP.
See Transports ->.
Adapter
A bundle of storage backends - AuthIdentity.IStore, AuthSession.IStore,
AuthCredential.IStore, optionally AuthOrg.IStore. duck-auth ships
AuthMemoryAdapter, the Redis bundle, and a SQL bridge with Drizzle
references.
See Adapters ->.
Assurance terms
AAL (Authentication Assurance Level)
NIST 800-63B vocabulary. duck-auth uses three levels:
| AAL | Meaning |
|---|---|
aal1 | One factor (password, magic-link, OAuth without MFA enforcement). |
aal2 | Two factors, with at least one "something you have" (passkey, TOTP, FIDO key). |
aal3 | Two factors, both hardware-backed. Currently equivalent to aal2 in duck-auth. |
Use aal2 as the gate for sensitive actions (account deletion, payment
config, admin operations).
AMR (Authentication Methods References)
RFC 8176. An array of method tags carried on every session, recording
which factors were verified to mint it: ['pwd'], ['pwd', 'totp'],
['passkey'], ['oauth_google']. Useful for audit and for policies
that gate on specific factor sequences.
Freshness
The time since the session's most recent factor verify. Sensitive
actions require a fresh session - duck-auth raises
AUTH/STEP_UP_REQUIRED when Date.now() - session.lastReauthAt > config.session.freshnessMs. Default freshness window is 5 minutes.
Step-up
The action of asking the user to re-prove one or more factors mid-session.
A step-up does not sign the user out - it bumps lastReauthAt
(possibly aal) and lets them continue.
See Adding MFA ->.
Hijack policy
A policy that reacts to IP/UA drift on an existing session. Options:
ignore (do nothing), rotate (rotate the session id), mfa (force
step-up), revoke (kill the session). The hijack event fires when
the policy triggers.
Anomaly signal
A score from a detector indicating "something unusual is happening."
Detectors include impossible-travel and device-fingerprint. The
aggregator sums signals into a decision of allow / step-up /
deny.
See Anomaly detection ->.
Token / wire terms
PKCE (Proof Key for Code Exchange)
RFC 7636. An OAuth defence against authorization-code interception. The
client picks a code_verifier, sends code_challenge (S256 hash of
the verifier) on /authorize, and the original verifier on /token.
Even if an attacker intercepts the code, they can't redeem it.
duck-auth uses PKCE-S256 on every OAuth flow, regardless of client type.
state
The OAuth CSRF defence. A short-lived token round-tripped through the
IdP. duck-auth signs state with HMAC-SHA256, embeds the PKCE verifier
- a nonce + an expiry, and verifies on callback. Tampered or stale
states raise
AUTH/OAUTH_STATE_MISMATCH.
nonce
OIDC's replay defence. A random value attached to the authorize URL
and verified in the returned id_token. Re-use raises
AUTH/OAUTH_NONCE_REPLAY.
Refresh-token family
OAuth refresh tokens form a chain - each refresh issues a new refresh + access pair, linked to the prior root. duck-auth tracks the family-id; presenting the same refresh token twice (legitimate client plus an attacker) revokes the entire family. RFC 6749 section 10.4.
DPoP
RFC 9449. A DPoP header carrying a signed proof that the client holds
a private key. The access token's cnf.jkt claim names the public-key
thumbprint. A stolen token is useless without the matching private
key.
See DPoP ->.
JWKS
JSON Web Key Set. A document at /.well-known/jwks.json listing the
public verify keys for a JWT issuer. Downstream services use it to
verify your JWTs locally.
See OIDC discovery ->.
Compliance terms
GDPR / SOC2 / HIPAA / FIPS
duck-auth ships compliance presets for each. The presets wire opinionated overrides (hasher choice, dataAtRest policy, audit log delivery, anomaly thresholds, MFA enforcement).
dataAtRest
Field-level encryption for sensitive credentials and profile data.
duck-auth ships AuthAesGcmDataAtRest (local key) and
AuthKmsEnvelopeDataAtRest (AWS KMS or your own KMS).
strict()
The boot-time validator. Called as auth.strict({ env: 'production' }),
it rejects insecure configuration (IamMemoryAdapter in production,
AuthNoopLimiter, secure: false cookies, etc.) before the first
request.
Multi-tenant terms
Tenant
A logical isolation boundary - typically an organisation in a B2B
SaaS, but can be a region, a deployment, or a customer environment.
Every store method takes a tenantId. Cross-tenant reads return
null.
Org
A multi-tenant membership grouping inside a tenant. Backed by the
orgs facet (optional). Useful when one identity is a member of
multiple orgs with different roles in each. Pairs with
duck-iam scoped roles ->.
Error terms
AuthError
The typed error class. Carries code (closed set of AUTH/*
strings), status (HTTP), and meta (denylist-redacted on
toJSON()).
See Errors ->.
AUTH/STEP_UP_REQUIRED
A 403 returned by sensitive routes when the session needs a freshness re-auth or an AAL upgrade. The client catches this and shows the MFA prompt; on success, retries the original call.
Pluralism reminders
Throughout the docs:
- Provider != Channel. A provider takes input from the user (password, OAuth code, passkey assertion). A channel pushes a message out (email, SMS, WebPush).
- Identity != Session. An identity outlives many sessions. Killing a session does not delete the identity.
- Transport != Adapter. A transport carries one session on the wire. An adapter stores many sessions in a database.
- AAL != AMR. AAL is a level (1, 2, 3). AMR is an array of method tags.