From f4ec4cd5f4efb49727e2f7686b0914a6a1506804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simonyi=20Gerg=C5=91?= <28359278+gergosimonyi@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:31:46 +0000 Subject: [PATCH] blueprints: add default Password policy (#11793) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add password policy to default password change flow This change complies with the minimal compositional requirements by NIST SP 800-63 Digital Identity Guidelines. See https://pages.nist.gov/800-63-4/sp800-63b.html#password More work is needed to comply with other parts of the Guidelines, specifically > If the chosen password is found on the blocklist, the CSP or verifier > [...] SHALL provide the reason for rejection. and > Verifiers SHALL offer guidance to the subscriber to assist the user in > choosing a strong password. This is particularly important following > the rejection of a password on the blocklist as it discourages trivial > modification of listed weak passwords. * add docs for default Password policy * remove HIBP from default Password policy * add zxcvbn to default Password policy * add fallback password error message to password policy, fix validation policy Signed-off-by: Jens Langhammer * reword docs Co-authored-by: Tana M Berry Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com> * add HIBP caveat Co-authored-by: Jens L. Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com> * separate policy into separate blueprint Signed-off-by: Jens Langhammer * use password policy for oobe flow Signed-off-by: Jens Langhammer * kiss Signed-off-by: Jens Langhammer --------- Signed-off-by: Jens Langhammer Signed-off-by: Simonyi Gergő <28359278+gergosimonyi@users.noreply.github.com> Co-authored-by: Jens Langhammer Co-authored-by: Tana M Berry --- authentik/blueprints/tests/test_packaged.py | 3 ++- authentik/policies/password/models.py | 4 ++++ blueprints/default/flow-oobe.yaml | 1 - blueprints/default/flow-password-change.yaml | 13 +++++++++++++ website/docs/customize/policies/index.md | 4 ++++ website/docs/security/security-hardening.md | 11 +++++++++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/authentik/blueprints/tests/test_packaged.py b/authentik/blueprints/tests/test_packaged.py index 443173bac237..32d392447f72 100644 --- a/authentik/blueprints/tests/test_packaged.py +++ b/authentik/blueprints/tests/test_packaged.py @@ -27,7 +27,8 @@ def tester(self: TestPackaged): base = Path("blueprints/") rel_path = Path(file_name).relative_to(base) importer = Importer.from_string(BlueprintInstance(path=str(rel_path)).retrieve()) - self.assertTrue(importer.validate()[0]) + validation, logs = importer.validate() + self.assertTrue(validation, logs) self.assertTrue(importer.apply()) return tester diff --git a/authentik/policies/password/models.py b/authentik/policies/password/models.py index d8584617bcf2..ede76c9f3a03 100644 --- a/authentik/policies/password/models.py +++ b/authentik/policies/password/models.py @@ -89,6 +89,10 @@ def passes(self, request: PolicyRequest) -> PolicyResult: def passes_static(self, password: str, request: PolicyRequest) -> PolicyResult: """Check static rules""" + error_message = self.error_message + if error_message == "": + error_message = _("Invalid password.") + if len(password) < self.length_min: LOGGER.debug("password failed", check="static", reason="length") return PolicyResult(False, self.error_message) diff --git a/blueprints/default/flow-oobe.yaml b/blueprints/default/flow-oobe.yaml index 97b0258f1091..5264cb7d9b02 100644 --- a/blueprints/default/flow-oobe.yaml +++ b/blueprints/default/flow-oobe.yaml @@ -101,7 +101,6 @@ entries: - !KeyOf prompt-field-email - !KeyOf prompt-field-password - !KeyOf prompt-field-password-repeat - validation_policies: [] id: stage-default-oobe-password identifiers: name: stage-default-oobe-password diff --git a/blueprints/default/flow-password-change.yaml b/blueprints/default/flow-password-change.yaml index 2c0f8db217b2..31bb657c29bc 100644 --- a/blueprints/default/flow-password-change.yaml +++ b/blueprints/default/flow-password-change.yaml @@ -2,6 +2,17 @@ version: 1 metadata: name: Default - Password change flow entries: +- attrs: + check_static_rules: true + check_zxcvbn: true + length_min: 8 + password_field: password + zxcvbn_score_threshold: 2 + error_message: Password needs to be 8 characters or longer. + identifiers: + name: default-password-change-password-policy + model: authentik_policies_password.passwordpolicy + id: default-password-change-password-policy - attrs: designation: stage_configuration name: Change Password @@ -39,6 +50,8 @@ entries: fields: - !KeyOf prompt-field-password - !KeyOf prompt-field-password-repeat + validation_policies: + - !KeyOf default-password-change-password-policy identifiers: name: default-password-change-prompt id: default-password-change-prompt diff --git a/website/docs/customize/policies/index.md b/website/docs/customize/policies/index.md index 95ecff8ef374..39169ba9c69e 100644 --- a/website/docs/customize/policies/index.md +++ b/website/docs/customize/policies/index.md @@ -32,6 +32,10 @@ This policy can enforce regular password rotation by expiring set passwords afte ### Password Policy +:::warning +By default, authentik's Password policy is compliant with [NIST's recommendations](https://pages.nist.gov/800-63-4/sp800-63b.html#password) for passwords. To remain compliant with NIST, be cautious when editing the default values. For additional hardening configuration settings, refer to [Hardening authentik](../../security/security-hardening.md#password-policy). +::: + This policy allows you to specify password rules, such as length and required characters. The following rules can be set: diff --git a/website/docs/security/security-hardening.md b/website/docs/security/security-hardening.md index 0c6bc18ee8d7..a705e4ca2da3 100644 --- a/website/docs/security/security-hardening.md +++ b/website/docs/security/security-hardening.md @@ -4,6 +4,17 @@ title: Hardening authentik While authentik is secure out of the box, you can take steps to further increase the security of an authentik instance. As everyone knows, there is a consequential tradeoff between security and convenience. All of these hardening practices have an impact on the user experience and should only be applied knowing this tradeoff. +### Password policy + +authentik's default Password policy complies with the [NIST SP 800-63 Digital Identity Guidelines](https://pages.nist.gov/800-63-4/sp800-63b.html#password). + +However, for further hardening compliant to the NIST Guidelines, consider + +- setting the length of the password to a minimum of 15 characters, and +- enabling the "Check haveibeenpwned.com" blocklist comparison (note that this cannot be used on Air-gapped instances) + +For further options, see [Password policy](../customize/policies/index.md#password-policy). + ### Expressions [Expressions](../customize/policies/expression.mdx) allow super-users and other highly privileged users to create custom logic within authentik to modify its behaviour. Editing/creating these expressions is, by default, limited to super-users and any related events are fully logged.