docs/documentation/platform/secret-validation-rules.mdx
Secret Validation Rules let you define constraints that secrets must satisfy before they can be created, updated, or generated. This helps teams enforce consistent naming conventions, prevent weak or malformed values, and maintain compliance standards across environments — all automatically at write time.
For example, you can require that all secret keys in production follow UPPER_SNAKE_CASE, that values meet a minimum length, that database connection strings always start with a specific prefix, or that passwords generated by a dynamic secret or rotation always match a particular pattern.
Infisical supports three rule types, each targeting a different kind of secret:
For dynamic-secret and rotation rules, you must select one or more providers the rule applies to. Currently supported providers:
| Rule Type | Supported Providers |
|---|---|
| Dynamic Secrets | SQL Database (PostgreSQL, MySQL, Oracle, Microsoft SQL Server), Milvus |
| Secret Rotations | PostgreSQL Credentials |
When a static secret is created or updated, Infisical checks it against all active validation rules whose scope (environment and folder path) matches the secret's location. If any constraint is violated, the secret is rejected and an error is thrown describing which rule and constraint was violated.
<Note> Static-secret validation rules are enforced on mutations only (create or update). Existing secrets that were created before a rule was added are not retroactively validated. </Note>For dynamic secrets and secret rotations, validation rules drive the generation of credentials rather than rejecting input. When a lease is issued (dynamic secret) or credentials are rotated (rotation), Infisical generates a password that satisfies the matching rule's constraints, replacing the default password generation logic.
If the rule has a Regex Pattern constraint, the password is generated directly from that pattern, and min/max length constraints are ignored for that rule. To enforce length when using a regex, express it inside the pattern itself (e.g. [A-Z0-9]{16,24}).
If the rule's constraints are statically infeasible (e.g. an invalid regex, or a min length larger than the max), the rule is rejected at save time so the issue surfaces immediately rather than at lease/rotation time.
Each rule contains one or more constraints. A constraint specifies what to check and how to check it.
| Constraint | Description | Example | Static Secrets | Dynamic Secrets | Secret Rotations |
|---|---|---|---|---|---|
| Min Length | Target must be at least N characters | At least 8 characters | ✓ | ✓ | ✓ |
| Max Length | Target must be at most N characters | At most 64 characters | ✓ | ✓ | ✓ |
| Regex Pattern | Target must match a regular expression | ^[A-Z][A-Z0-9_]*$ | ✓ | ✓ | ✓ |
| Required Prefix | Target must start with specific text | https:// | ✓ | ✓ | ✓ |
| Required Suffix | Target must end with specific text | _SECRET | ✓ | ✓ | ✓ |
| Prevent Value Reuse | New value must not match any of the last N versions | Last 10 versions | ✓ | — | — |
Applies To target by rule type:
Every rule is scoped to control where it applies:
production), or apply it to all environments./** for all paths, /services/* for immediate subfolders of /services).This means you can have different validation standards for different parts of your project. For instance, you might enforce stricter naming in production while keeping development more flexible, or require longer generated passwords for rotations on production databases.


- **Name** — A descriptive name (e.g., "Production key naming convention").
- **Description** (optional) — A brief explanation of what the rule enforces and why.
- **Rule Type** — **Static Secrets**, **Dynamic Secrets**, or **Secret Rotations**.
- **Providers** (dynamic-secret and rotation rules only) — Select one or more providers the rule applies to.
- **Environment** — Choose a specific environment or "All Environments".
- **Folder Path** — The path scope, supporting glob patterns (e.g., `/**`).
**Constraints**
Click **Add Constraint** and choose from the available constraint types. For static-secret rules, select whether each constraint applies to the secret **key** or **value**. For dynamic-secret and rotation rules, constraints apply to the **generated password**, then provide the constraint parameter (length, pattern, prefix, or suffix).
You can add multiple constraints to a single rule. All constraints must be satisfied — for static secrets the value/key must satisfy them, and for dynamic/rotation rules the generated password is built to satisfy them.

Infisical prevents you from creating rules that would conflict with each other. If two rules apply to the same scope (overlapping environment and folder path) and share a constraint of the same type targeting the same field, the second rule will be rejected.
For example, you cannot have two separate "Regex Pattern on key" constraints in overlapping scopes, as they could contradict each other. Instead, combine the patterns into a single rule.
For dynamic-secret and rotation rules, two rules also conflict only if their selected provider sets intersect. For example, a Postgres-only rotation rule on /db/* and a separate Postgres rotation rule on /** overlap on Postgres + the path glob, and the second one would be rejected. A Milvus-only rule on the same path would not conflict with a Postgres rule, because the providers don't overlap.
- Pattern: `^[A-Z][A-Z0-9_]*$`
This ensures all secret keys follow the `UPPER_SNAKE_CASE` convention (e.g., `DATABASE_URL`, `API_KEY`), rejecting names like `mySecret` or `api-key`.
- Minimum: `8`
This prevents secrets with very short or empty-like values from being saved, helping catch accidental pastes or placeholder values.
- Prefix: `postgresql://`
This ensures all secrets in the database folder contain valid PostgreSQL connection strings.
- Suffix: `_PROD`
This helps distinguish production secrets from those in other environments.
- Previous versions: `10`
When a secret is updated, its new value is validated against the specified number of prior versions. This is useful for enforcing rotation policies and ensuring that secrets are not recycled.
- **Min Length**: `24`
- **Required Prefix**: `INF_`
Every SQL dynamic-secret lease issued in the project will now produce a password that is at least 24 characters long and starts with `INF_`. The password configuration on individual SQL dynamic secrets is ignored while the rule is active.
- **Regex Pattern**: `^[A-Z][A-Za-z0-9]{19,29}$`
Postgres rotations in production will now produce passwords that start with an uppercase letter and are 20–30 characters of mixed-case alphanumerics. Because a regex is set, separate min/max length constraints would be ignored — express the length window inside the pattern instead.