Password policy

mandatory

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.

Status: v0.1.0 — Draft. Promoted from the GOV.UK parity scan (metadocsstack #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 upperlowerdigit/

    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).
  • Sessiontoken lifetime (`specsauth/oauth-flow.kmd`).
  • Machine-user / service-account credentials (non-password).