---
title: Password Policy
slug: contact-center/password-policy
docTags: 
createdAt: 2025-12-29T08:30:35.476Z
---

Password policies let your organization control how strong local (platform) passwords must be, how often they expire, and whether old passwords may be reused. Policies are **scoped** (for example by **user type** and **hierarchy context** such as contact center) and can be **turned on or off** per scope. Several policy layers can apply together: composition (simple and complex rules), lifecycle and reuse (**enforce**), and extra string or identity checks (**regex** policy block—despite the name, it is driven by **substring** settings rather than a free-form regular expression field).

Users who sign in only through **SAML** or **Google** SSO still benefit from centralized IdP rules; this page covers **platform-stored passwords** used with **normal login** and password-change flows.

# How It Works

1. An **administrator** (or deployment process) defines one or more **policy rows** for the right **context** and **user type** (for example Agent vs Administrator), and sets `enable` so the rules apply.
2. When a user **sets or changes a password** (including forced change after reset), the platform evaluates **each enabled policy type** that is registered for that user and aggregates any violations into a single error for the user.
3. **New users** may be created in a **“new”** state: on the next login the platform can require a **password change** before normal access, in addition to any expiry rules.
4. **Password history** rows (salted hashes) are written when passwords change; **reuse prevention** compares the candidate password against those stored values.

## How policies combine

| Policy kind (configuration name)           | Purpose                                                                                                                                                     |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Simple** (`simpleConfigurationPolicy`)   | Yes/no composition: required upper, lower, digit, special; optional **allow-list** of special characters; optional ban on **adjacent repeated** characters. |
| **Complex** (`complexConfigurationPolicy`) | Numeric **minimums** for length, uppercase, lowercase, digits, and special characters, plus **maximum** length.                                             |
| **Enforce** (`enforceConfigurationPolicy`) | **Maximum age** (mandatory change), **minimum age** (early warning before expiry), and **reuse prevention** against password history.                       |
| **Regex** (`regexConfigurationPolicy`)     | **Substring** rules: forbid user id or display name inside the password (case-insensitive), forbid listed strings, or require one configured substring.     |

All four can be enabled independently for the same user type where your deployment supports it. Composition checks (**simple** and **complex**) typically run together when both are enabled.

***

## Simple password policy

Stored in the `simple_password_policy` data (linked from `password_policy_detail`).

| Field / parameter            | Meaning         | Behaviour when enforcing                                                                                                                                                                                                                  |
| ---------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `allowed_special_character`  | Allow-list text | If **non-empty**, every **non-alphanumeric** character in the password must appear in this list. If **empty**, no allow-list restriction is applied by this rule.                                                                         |
| `required_uppercase_letter`  | Boolean         | At least **one** Latin uppercase letter (`A`–`Z`).                                                                                                                                                                                        |
| `required_lowercase_letter`  | Boolean         | At least **one** Latin lowercase letter (`a`–`z`).                                                                                                                                                                                        |
| `required_number`            | Boolean         | At least **one** digit (`0`–`9`).                                                                                                                                                                                                         |
| `required_special_character` | Boolean         | At least **one** character that is **not** a digit or Latin letter (any other symbol qualifies as “special” here).                                                                                                                        |
| `allow_repeated_character`   | Boolean         | If **false**, the password must **not** contain the **same character twice in a row** (no `aa`, `11`, `@@`, etc.).                                                                                                                        |
| `allow_anagram`              | Boolean         | Stored with the policy record for compatibility. It is **not** evaluated during standard password validation in current product logic—do **not** rely on it to block anagrams of old passwords unless your release notes state otherwise. |

Typical validation messages users may see include reminders to use allowed specials, at least one small letter, one capital letter, one numeric value, one special character, or that the password contains repeated characters.

***

## Complex password policy

Stored in `complex_password_policy`.

| Field / parameter               | Meaning           | How it is checked                                                                                           |
| ------------------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------- |
| `min_pwd_length`                | Minimum length    | Password length must be **≥** this value.                                                                   |
| `max_pwd_length`                | Maximum length    | Password length must be **≤** this value.                                                                   |
| `min_number_allow`              | Minimum digits    | Count of `0`–`9` in the password.                                                                           |
| `min_special_character_allow`   | Minimum “special” | Count of characters **not** matching `[0-9A-Za-z]`.                                                         |
| `min_lowercase_character_allow` | Minimum lowercase | Count of `a`–`z` after non-letters are stripped from consideration (same family of rules as simple policy). |
| `min_uppercase_character_allow` | Minimum uppercase | Count of `A`–`Z` in the same sense.                                                                         |

If any bound fails, the user receives guidance that length or character counts are below the configured minimums (wording may vary slightly by deployment).

***

## Enforce password policy

Stored in `enforce_password_policy`. Works together with `user_password_history` (prior salted hashes per user).

| Field / parameter            | Meaning | Behaviour                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `max_pwd_age`                | Days    | Uses the **most recent** password change timestamp from history. If the password is **older than** this many **whole-day** buckets (see rounding below), login / expiry handling treats it as **expired** and the user must change password.                                                                                                                                                                                                                                                                                                           |
| `min_pwd_age`                | Days    | After the password is **older than** this threshold (and still within `max_pwd_age`), the user may receive a **warning** that the password **will expire** in a shown number of days (derived from `max_pwd_age` and age).                                                                                                                                                                                                                                                                                                                             |
| `disallow_previous_password` | Integer | When **non-zero**, reuse prevention is **on**: the new password is hashed and compared to **each** password history entry the platform still holds for that user in its active configuration cache; a match rejects the change. Values **greater than 20** are **stored capped at 20** in one code path, but the comparison itself does **not** stop after *n* rows—it evaluates **all** cached history rows for that user. Plan retention and audits accordingly. Setting the field to **0** disables this reuse check (other rules may still apply). |
| `pwd_grace_value`            | Integer | Present in the schema for compatibility; **not** used by password logic—leave unset or ignore.                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

**Reuse and&#x20;**`max_pwd_age`**:** When reuse prevention is on **and** `max_pwd_age` is set, the platform also rejects a password whose hash matches a password that was set within the **last&#x20;**`max_pwd_age`**&#x20;days** (in addition to the general history scan).

**User state “new”:** If the account is still in a **new** user state, the expiry path can respond with a **force change password** outcome so the first platform password meets policy.

**Rounding:** Age in days is derived from calendar time difference; partial days are rounded **up** when deciding whole-day age for expiry, so behaviour matches “full days since last change.”

***

## Regex password policy (substring and identity rules)

Stored in `regex_password_policy`. The name reflects legacy wording; operators configure **plain substrings**, not a regular-expression editor.

| Field / parameter    | Meaning | Behaviour                                                                                                                                                                                                        |
| -------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `disallow_user_id`   | Boolean | If true, the password must **not** contain the user’s **login id** as a substring (**case-insensitive**).                                                                                                        |
| `disallow_user_name` | Boolean | If true, the password must **not** contain the user’s **display name** as a substring (**case-insensitive**).                                                                                                    |
| `exclude_strings`    | Text    | **Comma-separated** list of forbidden fragments. If the password **contains** any listed fragment (**case-sensitive** match), it is rejected. Example: `password,123456,welcome` forbids those exact substrings. |
| `contain_substring`  | Text    | If non-empty, the password **must include** this exact substring (**case-sensitive**). Only **one** required phrase is supported in this field (not a list).                                                     |

***

## Master policy row

`password_policy_detail` links everything to `user_type`, `context`, `context_id`, a `name`, and `enable`. Each enabled row can have child rows in the simple, complex, enforce, and regex tables as your deployment defines.

***

## Configuration parameters

Use these **policy type identifiers** when integrating with configuration APIs or exports that list password policy blocks. Exact **UI navigation** depends on your edition (on-prem Administrator vs cloud configuration portal); map these keys in your **user / security / password** settings area for the right **hierarchy** and **user type**.

| Key / parameter              | Description                                                           | How to configure                                                                                  | Constraints / allowed values                                                                                                                                                            | Sample                                                             |
| ---------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| `simpleConfigurationPolicy`  | Simple composition toggles and optional special-character allow-list. | Enable per **user type** + **context**; edit `simple_password_policy` fields (or equivalent UI).  | Booleans `true`/`false`; allow-list is a string of permitted special characters; empty allow-list disables allow-list filtering.                                                        | `required_number=true`, `allowed_special_character=@#$%`           |
| `complexConfigurationPolicy` | Minimum counts and password length bounds.                            | Same scope as simple; edit `complex_password_policy`.                                             | Non-negative integers; `min_pwd_length` ≤ `max_pwd_length`.                                                                                                                             | `min_pwd_length=12`, `min_number_allow=2`                          |
| `enforceConfigurationPolicy` | Age, warning, reuse.                                                  | Same scope; edit `enforce_password_policy` and ensure history retention matches compliance goals. | Ages in **days**; `disallow_previous_password` **0** = off, **non-zero** = on (stored value may cap at **20**, but checks use **all** retained history rows); `pwd_grace_value` unused. | `max_pwd_age=90`, `min_pwd_age=80`, `disallow_previous_password=5` |
| `regexConfigurationPolicy`   | Substring / identity rules.                                           | Same scope; edit `regex_password_policy`.                                                         | Comma-separated `exclude_strings`; single `contain_substring`; booleans for id/name checks.                                                                                             | `exclude_strings=companyname,welcome`                              |

***

## Configuration steps (administrator checklist)

1. Decide **which user types** (for example agents, supervisors, administrators) need stricter rules.
2. Identify the correct **hierarchy context** (for example contact center or tenant) where policy is defined for your product edition.
3. Create or update `password_policy_detail` with `enable = true` for that combination.
4. Fill **simple** and/or **complex** rows if you need composition rules.
5. Fill **enforce** if passwords must **expire** or **cannot repeat**; confirm **password history** is populated on change.
6. Fill **regex** row if you must block **company names**, **default passwords**, or forbid **user id / name** fragments.
7. Test with a **non-production** user: set passwords that should **pass** and **fail** each rule and confirm messages are acceptable for your agents.

***

## Show / Hide Password (Eye Icon)

Starting from version 4.13.3, a **show/hide toggle** (eye icon) is available on the `/app` and toolbar login screens, allowing users to reveal or hide their password while typing. In version 4.13.4, this was extended to **all password fields** throughout the UI.

## User ID and Username Character Restrictions

Starting from version 4.13.48, administrators can enforce character restrictions on user IDs and usernames via two configurable regex flags in the `server_preference_store` at the **contact center** level:

- `allowed_userId_regex` — Restricts which characters are accepted when creating or updating a user ID.
- `allowed_username_regex` — Restricts which characters are accepted for usernames.

These constraints apply to both individual user creation/update in the UI and bulk user uploads.

## Limitations and notes

- `allow_anagram` is **not** enforced by the standard validator despite appearing in the schema.
- `pwd_grace_value` is **unused**.
- `disallow_previous_password`: effective ceiling **20**; behaviour depends on **how many** history rows exist for the user.
- **SSO users** may rarely set a local password; strongest guarantees come from the **IdP** for SAML/Google.
- **MFA**: Release notes reference password policy alignment with MFA—keep MFA and local policy coordinated.
- **Cloud vs on-prem**: Behaviour and UI entry points should be confirmed for your specific release; configuration keys above align with shared service naming.

## Related topics

- **User Login & Single Sign-On (SSO)** — **Normal login** (platform User ID and password), **SAML**, and **Google** SSO; password policies apply to local passwords and complement IdP rules for SSO users.
- **Administrator Login** / **Supervisor Login** — Where login options appear for each persona.
- **Login – Logout** (reporting) — Audit of sign-in and sign-out events.

## Version History

| Version | Enhancement                                                                              | Release Notes                                                                          |
| ------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| 4.13.3  | Show/hide password eye icon on `/app` and toolbar login screens                          | [4.13.3 Release Notes](docId\:AAQ9HD2jykMjBsrFYAaNe)                                   |
| 4.13.4  | Eye icon extended to all password fields in the UI                                       | [4.13.4 Release Notes](docId\:jomNaxU6JtlBECPeCEyXc)                                   |
| 4.13.48 | Configurable `allowed_userId_regex` and `allowed_username_regex` at contact center level | [Contact Center - Patch Release Notes - Version 4.13.48](docId\:ohMtI-DQXjPuEjRDrCdz0) |
