Skip to content

Password policy

identity specs/identity/password-policy.kmd

The NCSC/NIST-aligned password rules for Koder ID — the ONLY surface in the Stack that accepts a user password, since Koder ID is the sole identity provider (auth/oauth-flow.kmd R1). Modern guidance: length over complexity, no forced expiry, no composition rules, no security questions, breached-password screening, and password-manager-friendly input. Applies to account creation, password change, and reset.

When this pattern applies

Primary triggers

All triggers

Specification body

Spec — Password policy

Status: v0.1.0 — Draft. Promoted from the GOV.UK parity scan (meta/docs/stack #096); aligns with NCSC password guidance + NIST SP 800-63B. Scope is Koder ID only — no other Koder component has a password field (specs/auth/oauth-flow.kmd R1: Koder ID is the sole identity provider; products receive tokens, never credentials). Sources: https://www.ncsc.gov.uk/collection/passwords · https://pages.nist.gov/800-63-3/sp800-63b.html

R1 — Length, not composition

  • Minimum 8 characters. (12+ encouraged via the strength meter, R6, but never hard-required beyond 8.)
  • No upper length cap below 64; accept passphrases up to at least 256 characters. Never silently truncate.
  • No composition rules — do NOT require a mix of upper/lower/digit/ symbol. Any printable Unicode character (including spaces and emoji) is allowed.

R2 — No forced expiry

  • Passwords do not expire on a schedule. Do not prompt periodic changes.
  • Force a reset only on evidence of compromise (breach screening R3, detected credential stuffing, or user request).

R3 — Breached-password screening

  • On set/change, screen the candidate against a known-compromised password corpus using a k-anonymity range query (only a hash prefix leaves the server; the full password/hash is never sent externally).
  • A match is rejected with a clear, non-shaming message (specs/errors/user-facing-messages.kmd): "This password has appeared in a data breach. Choose a different one."
  • Screening is the ONLY content denylist; do not also ban dictionary words or enforce arbitrary blocklists.

R4 — No knowledge-based recovery

  • No security questions and no password hints — both are weaker than the password and are prohibited.
  • Account recovery goes through verified email/second-factor flows (separate spec), never "mother's maiden name".

R5 — Input UX (password-manager friendly)

  • Allow paste into the password field (do not block it).
  • Provide a show/hide toggle (eye icon) that reveals the entered value; default hidden; the toggle is a real <button> with an accessible label that reflects state ("Show password"/"Hide password").
  • Use autocomplete="new-password" on create/change and autocomplete="current-password" on sign-in so managers work.
  • Never disable autofill.

R6 — Strength feedback, not gatekeeping

  • Show a strength meter (entropy/zxcvbn-style estimate) that guides toward longer/passphrase choices.
  • The meter is advisory: anything meeting R1 (≥8, not breached) is accepted. The meter never blocks submission on its own.

R7 — Storage & rate limiting (contract, not implementation)

  • Store only a salted, memory-hard hash (argon2id or equivalent), per-user salt; never plaintext or reversible encryption.
  • Defend online guessing with throttling (progressive delay) in preference to hard lockout (which enables denial-of-service); lockout, if used, is time-boxed and self-clearing.
  • Authentication telemetry follows policies/identity-data-retention.kmd (no plaintext credentials in logs, ever).

R8 — Accessibility & i18n

  • The field has a real <label>; requirements are stated up front (not only revealed on error), associated via aria-describedby.
  • Errors (too short, breached) are specific and actionable (specs/errors/user-facing-messages.kmd), announced to assistive tech.
  • All strings (label, hint, strength levels, errors, toggle) are translatable per specs/i18n/contract.kmd; length is counted in Unicode code points, locale-independent.

Não-escopo

  • 2FA / passkey / WebAuthn enrolment (separate auth specs).
  • The account-recovery flow itself (email verification, second factor).
  • Session/token lifetime (specs/auth/oauth-flow.kmd).
  • Machine-user / service-account credentials (non-password).

References