Skip to main content

Compliance presets

WIP

The gdpr, hipaa, soc2 and fips presets, what each one raises, and how strict() holds a deployment to them

A preset is a floor. createAuth({ compliance }) shortens the session lifetimes to it, and strict() refuses to run until the deployment shows it meets the rest. It certifies nothing; it catches configuration that contradicts the regime you named.

const auth = createAuth({
  // ...
  compliance: 'hipaa', // or a list, such as ['gdpr', 'soc2']
  providers: [passwords({ compliance: 'hipaa' }), mfaProvider({ compliance: 'hipaa' })],
  strict: false, // checked below, once the listeners exist
})

auth.events.on('lockout', alertOnLockout)
auth.strict({
  env: 'production',
  compliance: { auditLogRetained7y: true, baaCompliantChannel: true, dataAtRest: true, mailerChannel: true },
})
  • A list composes by taking the stricter value of every field.
  • The checks run in every env, not only production, and one error lists every gap.
  • strict: false defers them: createAuth runs strict() as it returns, before you have subscribed anything, and it has no way to take your attestations.

What each preset sets

gdprhipaasoc2fips
Sliding session7 days1 hour7 days4 hours
Absolute session30 days8 hours30 days12 hours
Password minimum812814
API key bytes32323248
Needs mfaProvider()noyesnoyes
ChecksdataAtRest, mailerChannel, exportAvailable, softDeleteEnableddataAtRest, mailerChannel, baaCompliantChannel, auditLogRetained7ylockoutListener, limiterRequired, auditLogRetained7ydataAtRest, mailerChannel, fipsValidatedHasher, webauthnAttestationDirect

The session lifetimes only ever shorten what you set. The password, backup-code and API key floors belong to the providers, so pass the same preset to passwords({ compliance }), mfaProvider({ compliance }) and apiKeyProvider({ compliance }); createAuth cannot reach providers that are already built.

hipaa and fips refuse an engine with no mfa provider. Sign-in still answers AAL 1; demanding the second factor is your checkStepUp, as in step-up.

The checks

CheckAnswered by
limiterRequiredThe engine: a limiter you supplied that is neither the noop nor an in-process one.
lockoutListenerThe engine: a lockout listener is subscribed when strict() runs.
webauthnAttestationDirectThe engine, when a passkey provider is registered. Otherwise you.
fipsValidatedHasherThe engine, from a shipped password hasher. A hasher of your own: you.
dataAtRest, mailerChannel, baaCompliantChannel, auditLogRetained7y, exportAvailable, softDeleteEnabledYou, in strict({ compliance }).

What the engine sees overrides what you attest, so limiterRequired: true over a MemoryLimiter still fails. A check nobody answers fails.