---
title: Password generation and validation
summary: Generates temporary passwords and validates password composition against library-defined rules.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Business.External.Users
reference_type: package
operation_id: OP-EU-11
trigger: Caller requests a generated password or validates a proposed password.
---

# Password generation and validation

This operation documents the standalone password utility used by the external-user library. It can generate temporary passwords from configurable character sets and validate a caller-supplied password against the library's length, complexity, and personal-data exclusion requirements.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-EU-11 |
| **Trigger** | `clsPassword.Generate` or `clsPassword.IsValid` is called |
| **Inputs** | Requested password length, special-character count, candidate password, user ID, first name, last name |
| **Outputs** | Generated password string or `PasswordValdationResult` with success flag and messages |
| **Primary components** | `clsPassword.Generate`, `clsPassword.IsValid` |
| **Entry point** | `Business\SAIF.Business.External.Users\clsPassword.vb` |

## Steps

1. **Initialize the allowed character pools.** The constructor records which upper-case, lower-case, numeric, and symbol sets are enabled and adds each enabled set to both `possibleChars` and `requiredChars`.
2. **Remove excluded characters from every active pool before generation.** `Generate` strips the configured `CharsToExclude` values from the full candidate list and from each individual required character class.
3. **Normalize the requested generation parameters.** The method keeps a zero length as zero and clamps the requested special-character count so it cannot exceed the password length.
4. **Generate the base password body.** For each requested character position, the method chooses either a random special character or a random character from `possibleChars`.
   - Special characters are forced in when the remaining length must satisfy the requested special-character count.
   - Otherwise, a random branch occasionally inserts a special character early.
5. **Guarantee at least one character from each enabled required set.** After the base loop, the method appends one random character from every required set that is not yet represented in the generated password.
6. **Validate the candidate password against the library rule set.** `IsValid` checks minimum and maximum length, class complexity, and personal-data exclusion, adding one or more validation messages when the password fails ([BR-EU-06](../business-rules.md#br-eu-06-password-composition-and-personal-data-exclusion)).
   - Password length must be at least eight characters and no more than 128 characters.
   - The password must satisfy at least three enabled character classes.
   - The password cannot contain the user ID.
   - The password cannot contain the user's first name or last name.
7. **Return the accumulated validation result.** The method leaves `IsValid` set to `False` when any rule failed and returns the collected UI messages to the caller ([BR-EU-06](../business-rules.md#br-eu-06-password-composition-and-personal-data-exclusion)).

## Process flow

The following diagram visualizes this operation's control flow.

```mermaid
flowchart TD
    Start([Generate or validate password]) --> Mode{Generate or validate?}
    Mode -->|Generate| Pools[Build enabled character pools]
    Pools --> Randomize[Generate random password body]
    Randomize --> Ensure[Append any missing required classes]
    Ensure --> Done([Return generated password])
    Mode -->|Validate| Checks[Run length, complexity, and personal-data checks]
    Checks --> Result([Return validation result and messages])
```

## Failure and edge-case behavior

- Validation accumulates multiple messages, so one password can fail several checks in a single pass.
- Generated passwords can be longer than the requested length when the post-pass has to append missing required character classes.
- The complexity check counts satisfied character classes from the currently enabled `requiredChars` sets rather than scanning hard-coded character categories.

## Related documentation
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [SQL catalog](../sql/index.md)
- [Database tables](../database-tables.md)

## Sources
- `Business\SAIF.Business.External.Users\clsPassword.vb`
