mud_server.api.password_policy ============================== .. py:module:: mud_server.api.password_policy .. autoapi-nested-parse:: Password policy enforcement for secure authentication. This module implements a comprehensive password policy that balances security with usability. The policy is based on NIST SP 800-63B guidelines and industry best practices, while avoiding overly restrictive rules that lead users to create predictable passwords. Policy Philosophy: Modern password security research (NIST SP 800-63B, 2017) recommends: - Length over complexity (longer passwords are more secure) - Blocking common/compromised passwords - Avoiding arbitrary complexity rules that frustrate users - Not requiring periodic password changes (unless compromise suspected) This implementation follows these principles while providing configurable enforcement levels for different deployment scenarios. Policy Levels: - BASIC: Minimum viable security (8 chars, basic checks) - STANDARD: Recommended for most deployments (12 chars, common password check) - STRICT: High-security environments (16 chars, all checks enabled) Usage: from mud_server.api.password_policy import ( validate_password_strength, PasswordPolicy, PolicyLevel, ) # Using default (STANDARD) policy result = validate_password_strength("my_password_123") if not result.is_valid: print(result.errors) # Using a specific policy level result = validate_password_strength("password", level=PolicyLevel.STRICT) # Custom policy policy = PasswordPolicy( min_length=14, require_uppercase=True, require_lowercase=True, require_digit=True, require_special=True, check_common_passwords=True, ) result = policy.validate("my_password") Security Considerations: - Common password list is checked in constant time to prevent timing attacks - Password strength feedback helps users create better passwords - All validation errors are returned at once (not fail-fast) for better UX - Entropy estimation provides a security score for password meters Attributes ---------- .. autoapisummary:: mud_server.api.password_policy.COMMON_PASSWORDS mud_server.api.password_policy.POLICY_BASIC mud_server.api.password_policy.POLICY_STANDARD mud_server.api.password_policy.POLICY_STRICT Classes ------- .. autoapisummary:: mud_server.api.password_policy.PolicyLevel mud_server.api.password_policy.ValidationResult mud_server.api.password_policy.PasswordPolicy Functions --------- .. autoapisummary:: mud_server.api.password_policy.validate_password_strength mud_server.api.password_policy.get_policy mud_server.api.password_policy.get_password_requirements Module Contents --------------- .. py:data:: COMMON_PASSWORDS :type: frozenset[str] .. py:class:: PolicyLevel(*args, **kwds) Bases: :py:obj:`enum.Enum` Predefined password policy levels for different security requirements. Each level provides a balance between security and usability appropriate for different deployment scenarios. .. attribute:: BASIC Minimum viable security. Suitable for development/testing environments or low-risk internal applications. - 8 character minimum - No complexity requirements - Basic common password check .. attribute:: STANDARD Recommended for most production deployments. Provides strong security without being overly restrictive. - 12 character minimum (NIST recommended) - Encourages but doesn't require complexity - Comprehensive common password check - Sequential/repeated character detection .. attribute:: STRICT For high-security environments handling sensitive data. - 16 character minimum - Requires uppercase, lowercase, digit, and special char - All security checks enabled - Maximum entropy requirements .. py:attribute:: BASIC :value: 'basic' .. py:attribute:: STANDARD :value: 'standard' .. py:attribute:: STRICT :value: 'strict' .. py:class:: ValidationResult Result of password validation containing success status and feedback. This class provides detailed feedback about password validation, including all errors encountered and suggestions for improvement. All errors are collected (not fail-fast) to provide complete feedback to users. .. attribute:: is_valid True if the password meets all policy requirements. .. attribute:: errors List of human-readable error messages describing each validation failure. Empty if password is valid. .. attribute:: warnings List of suggestions for improving password strength. May be present even for valid passwords. .. attribute:: score Estimated password strength score from 0-100. Higher is better. Based on length, character diversity, and entropy estimation. .. attribute:: entropy_bits Estimated entropy in bits. Passwords with 60+ bits are considered strong, 80+ bits are excellent. .. admonition:: Example >>> result = validate_password_strength("weak") >>> result.is_valid False >>> result.errors ['Password must be at least 12 characters long (currently 4)'] >>> result.score 15 .. py:attribute:: is_valid :type: bool .. py:attribute:: errors :type: list[str] :value: [] .. py:attribute:: warnings :type: list[str] :value: [] .. py:attribute:: score :type: int :value: 0 .. py:attribute:: entropy_bits :type: float :value: 0.0 .. py:class:: PasswordPolicy Configurable password policy with comprehensive validation rules. This class encapsulates all password policy settings and provides validation methods. It can be configured for different security levels or customized for specific requirements. .. attribute:: min_length Minimum password length. NIST recommends 8 minimum, but 12+ provides significantly better security. .. attribute:: max_length Maximum password length. Set high (128) to allow passphrases. Bcrypt has a 72-byte limit internally. .. attribute:: require_uppercase Require at least one uppercase letter (A-Z). .. attribute:: require_lowercase Require at least one lowercase letter (a-z). .. attribute:: require_digit Require at least one digit (0-9). .. attribute:: require_special Require at least one special character. .. attribute:: special_characters Set of characters considered "special". .. attribute:: check_common_passwords Check against known common passwords. .. attribute:: check_sequential Detect sequential characters (abc, 123). .. attribute:: check_repeated Detect repeated characters (aaa, 111). .. attribute:: max_repeated Maximum allowed consecutive repeated characters. .. admonition:: Example >>> policy = PasswordPolicy(min_length=14, require_special=True) >>> result = policy.validate("MySecurePass123!") >>> result.is_valid True .. py:attribute:: min_length :type: int :value: 12 .. py:attribute:: max_length :type: int :value: 128 .. py:attribute:: require_uppercase :type: bool :value: False .. py:attribute:: require_lowercase :type: bool :value: False .. py:attribute:: require_digit :type: bool :value: False .. py:attribute:: require_special :type: bool :value: False .. py:attribute:: special_characters :type: str :value: '!@#$%^&*()_+-=[]{}|;\':",./<>?`~' .. py:attribute:: check_common_passwords :type: bool :value: True .. py:attribute:: check_sequential :type: bool :value: True .. py:attribute:: check_repeated :type: bool :value: True .. py:attribute:: max_repeated :type: int :value: 3 .. py:method:: validate(password) Validate a password against this policy. Performs all configured validation checks and returns a comprehensive result with all errors, warnings, and a strength score. Validation is not fail-fast - all checks are performed to provide complete feedback. :param password: The password string to validate. Should be the raw password before hashing. :returns: - is_valid: True if all requirements are met - errors: List of validation failure messages - warnings: List of improvement suggestions - score: Strength score 0-100 - entropy_bits: Estimated entropy :rtype: ValidationResult containing .. admonition:: Example >>> policy = PasswordPolicy() >>> result = policy.validate("short") >>> result.is_valid False >>> "at least 12 characters" in result.errors[0] True .. py:data:: POLICY_BASIC .. py:data:: POLICY_STANDARD .. py:data:: POLICY_STRICT .. py:function:: validate_password_strength(password, level = PolicyLevel.STANDARD) Validate password strength using a predefined policy level. This is the primary function for password validation. It uses one of the predefined policy levels (BASIC, STANDARD, or STRICT) to validate the password and return comprehensive feedback. :param password: The password to validate. Should be the raw password before any hashing. :param level: Security level to enforce. Defaults to STANDARD which is appropriate for most production deployments. :returns: ValidationResult containing validation status, errors, warnings, strength score, and entropy estimate. .. admonition:: Example >>> result = validate_password_strength("MyStr0ng!Pass#2024") >>> result.is_valid True >>> result.score 85 >>> result = validate_password_strength("weak", level=PolicyLevel.STRICT) >>> result.is_valid False >>> len(result.errors) > 0 True .. seealso:: PasswordPolicy: For custom policy configuration. PolicyLevel: For available predefined levels. .. py:function:: get_policy(level = PolicyLevel.STANDARD) Get the PasswordPolicy instance for a given level. Useful when you need to inspect policy settings or use the policy object directly. :param level: The policy level to retrieve. :returns: The PasswordPolicy instance for that level. .. admonition:: Example >>> policy = get_policy(PolicyLevel.STRICT) >>> policy.min_length 16 >>> policy.require_special True .. py:function:: get_password_requirements(level = PolicyLevel.STANDARD) Get a human-readable description of password requirements. Useful for displaying password requirements to users in registration forms or password change dialogs. :param level: The policy level to describe. :returns: Multi-line string describing all password requirements. .. admonition:: Example >>> print(get_password_requirements(PolicyLevel.STANDARD)) Password Requirements: - At least 12 characters long - Cannot be a commonly used password - Cannot contain sequential characters (abc, 123) - Cannot repeat the same character more than 3 times