contracts.rules_password_extra

Page actions AI-ready formats and sharing
Open LLM text
Share with AI
Ask Claude Ask ChatGPT Ask Gemini Ask Copilot

Password-hashing deploy-posture check — argon2 in production (#220).

A single env-aware ADVISORY rule: when an app exposes a login / mutating surface butargon2-cffiis notimportable, the password-hashing path silently falls…

Password-hashing deploy-posture check — argon2 in production (#220).

A single env-aware ADVISORY rule: when an app exposes a login / mutating surface butargon2-cffiis not importable, the password-hashing path silently falls back to stdlib scrypt. scrypt is a correct, always-available fallback (no hash is ever rejected), but argon2id is the recommended algorithm for new production deployments. This rule nudges towardpip install chirp[auth]in production without breaking dev or scrypt-only CI.

Category:

  • password_extra: a mutating/login surface exists and argon2-cffiis not installed (_has_argon2() is False). Severity is env-aware: WARNING in production/staging, silent in development (the default) so dev apps and shipped examples — and the scrypt-only base CI env — stay clean. This is a posture advisory, never an ERROR: scrypt verifies and stores fine, so there is no correctness gap to fail loud on. Existing scrypt hashes re-derive to argon2 on the next successful login when the app calls verify_and_upgrade(..., upgrade_algorithm=True)(opt-in; storm-safe default is off) and persists the returned hash once the extra is installed.

Why built-in and not a plugin check: this rule must readconfig.envand the route surface (router+ discovered filesystem pages), which the plugin ContractCheckSnapshot does not expose. It mirrors rules_security_stack/ rules_cookie_securein that respect.

argon2 availability is detected via_has_argon2() — the same predicate the runtime uses to choose the hashing algorithm — not by sniffing a middleware class name. The "do we hash with argon2 or scrypt?" decision lives in one place, so the check and the runtime never disagree.

contracts.rules_password_extra

Name Type Default Description
type
qualified_name
element_type
description
source_file
line_number
is_autodoc
autodoc_element
_autodoc_template
_autodoc_url_path
_autodoc_page_type
title
doc_content_hash

Symbols on this page

check_password_extra
function
def check_password_extra(router: Router, config: Any, discovered_routes: list[Any] | None = None) -> list[ContractIssue]

Advise installingchirp[auth](argon2) on a production login surface.

Fires a singleWARNING(production/staging, silent in development) when the app has a mutating/login surface andargon2-cffiis not importable, so the password path falls back to scrypt. No issue is emitted for an app with no mutating routes, when argon2 is available, or in development.

discovered_routes carries the filesystem PageRouteobjects (which exposeactions); runtime router.routes expose methodsonly. Both are scanned so a GET-only page backed by_actions.pyform actions still counts as a mutating surface — the sameis_mutating_routedefinition security_stackowns.

Parameters

Name Type Default Description
router Router
config Any
discovered_routes list[Any] | None None

View source · /home/runner/work/chirp/chirp/site/../src/chirp/contracts/rules_password_extra.py:1