Validators (Automated)
Automated validators use regular expressions (regex) to continuously check evidence artifacts pulled from your connected data sources. When an artifact is collected, the validator runs its regex pattern against the artifact's content and applies defined rules to determine a Pass or Fail result.
In this article
- Overview of Automated Validators
- Viewing Evidence Artifacts and Validation Results
- Understanding Validation Rules
- Other Types of Validation (Manual Attestations)
- Regex Basics (ECMAScript/JavaScript Flavor)
- Common Regex Patterns Reference
- Real-World Validator Examples
- Testing Your Regex
- Importing and Exporting Validators via CSV
Overview of Automated Validators
Each automated validator is composed of two parts:
- Regex Pattern – A regular expression that searches the evidence artifact text for specific patterns, values, or structures.
- Validation Rules – Logic that interprets what the regex found (match count, captured group value, etc.) and decides whether the result is a Pass or Fail.
Paramify uses the ECMAScript (JavaScript) flavor of regular expressions.
SUPPORTED REGEX FLAGS
The g (global) and s (dotAll) flags are applied automatically. The m (multiline) flag is not applied by default — anchors ^ and $ match the full document, not individual lines. Use [\s\S]*? to span across lines.
Viewing Evidence Artifacts and Validation Results
To review how an automated validator evaluated a specific evidence artifact:
1. Navigate to Implementation
Select Implementation in the top navigation bar.
2. Select the desired evidence set
Choose your evidence set (e.g., GitLab Merge Request Summary) from the Evidence list.
3. Review the Result Summary tab
The Result Summary tab shows all collected artifacts with their validation results.
Each row in the table shows:
- Artifact ID – Unique identifier for the evidence artifact (e.g.,
gitlab_merge_request_summary_project_1) - Effective Date – When the evidence was collected
- Source Type – How data was retrieved (e.g., API via Evidence Fetcher)
- Validation Result – Pass or Fail
Understanding Validation Rules
Click the Validation Rules tab to see exactly how the regex interprets each artifact and what constitutes a pass or fail. The Validation Rules tab shows the regex pattern and the criteria that determine a Pass or Fail disposition.
| Field | Description |
|---|---|
| Index | Rule order (01, 02, …). When multiple rules are defined, all must pass. |
| Regex Operation | Match Count — how many times the pattern matched. Match Group — the value of a specific capture group. |
| Criteria | Comparison operator: Equals, Greater Than Or Equal To, Contains, etc. |
| Value | What to compare against: a fixed Custom Text value, or the value of another Match Group. |
| Disposition | Result when the criterion is met: Pass or Fail. |
Regex Operation Types
| Operation | What it does | When to use |
|---|---|---|
| Match Count | Counts how many times the full pattern matches in the artifact | Checking presence/absence of a value, confirming a boolean flag is set, counting occurrences |
| Match Group | Extracts the value of capture group (...) number N | Extracting a numeric percentage, a compliance status string, or comparing two captured values |
Criteria Options
| Criteria | Example use case |
|---|---|
| Equals | Compliance status must exactly equal COMPLIANT |
| Greater Than Or Equal To | KMS rotation percentage must be ≥ 90 |
| Contains | SSL policy name must contain TLS13 |
| Not Equals | Compliance type must not be NON_COMPLIANT |
Regex capture groups can also be named with the following syntax: ?<name>
Other Types of Validation (Manual Attestations)
Not all evidence is validated automatically. Some evidence sets use manual questionnaires that are answered periodically (typically quarterly) to attest to compliance.
Manual attestation evidence sets use a Questionnaire tab. Each Yes/No response maps to a Pass or Fail, with support for nested conditional sub-questions.
Manual validators support:
- Top-level Yes/No questions mapping directly to Pass or Fail
- Nested sub-questions (a, b, c) that unlock based on parent answers
- Based On Nested disposition — the parent passes only when all child questions also pass
Regex Basics (ECMAScript/JavaScript Flavor)
Character Classes
| Pattern | Matches | Example |
|---|---|---|
\d | Any digit (0–9) | \d+ matches 42 or 100 |
\s | Any whitespace (space, tab, newline) | :\s* matches : or : |
\S | Any non-whitespace character | [\s\S] matches any character including newlines |
[^"] | Any character except a double-quote | "([^"]+)" captures a quoted string |
\w | Word character (letters, digits, underscore) | \w+ matches hello_world |
Quantifiers
| Pattern | Means | Notes |
|---|---|---|
* | Zero or more | Greedy — matches as much as possible |
+ | One or more | Greedy |
? | Zero or one | Makes the preceding token optional |
*? | Lazy zero or more | Stops at the earliest possible match |
Capture Groups
Use (...) to define capture groups. Groups are numbered left-to-right starting at 1. Paramify's Match Group operation references these by number.
Example pattern:
"rotation_percentage"\s*:\s*(\d+)
Group 1 captures the numeric value after the key — e.g., 94 from "rotation_percentage": 94.
Spanning Multiple Lines
Because the m flag is not applied, use [\s\S]*? to match across lines between two patterns:
"rds_total":\s*(\d+)[\s\S]*?"rds_ssl_enforced":\s*(\d+)Lookaheads
Use (?!...) (negative lookahead) to exclude specific values from matching:
"GroupName":\s*"(?!Administrators")([^"]+)"This matches any group name that is not "Administrators".
Common Regex Patterns Reference
| Pattern | Purpose |
|---|---|
\s*:\s*(\d+) | Capture a numeric value after a JSON key |
"([^"]*)" | Capture a quoted string value |
[\s\S]*? | Span any content including newlines (lazy) |
(?!SomeValue") | Negative lookahead — skip a specific value |
(true|false) | Capture a boolean value |
\[\s*\{ | Match the opening of a JSON array of objects |
[^\]]* | Match any character except a closing bracket |
Real-World Validator Examples
These examples come directly from Paramify's validator library.
Example 1 – Change Management Active
What it checks: All four change management flags are true in the same artifact.
"change_management_active":\s*true[\s\S]*?"approval_process_enabled":\s*true[\s\S]*?"review_process_active":\s*true[\s\S]*?"meets_minimum_review":\s*true| Operation | Criteria | Value | Disposition |
|---|---|---|---|
| Match Count | Equals | 1 | Pass |
If the full pattern matches exactly once (all four flags present and true in sequence), the artifact passes. A match count of 0 means a flag is missing or false — the artifact fails.
Example 2 – KMS Key Rotation Percentage
What it checks: At least 90% of KMS keys have rotation enabled.
"rotation_percentage"\s*:\s*(\d+)| Operation | Group | Criteria | Value | Disposition |
|---|---|---|---|---|
| Match Group | 1 | Greater Than Or Equal To | 90 | Pass |
Group 1 captures the percentage number. If the captured value is 90 or higher, the artifact passes.
Example 3 – RDS SSL Enforcement (Comparing Two Groups)
What it checks: The count of SSL-enforced RDS instances equals the total.
"rds_total":\s*(\d+)[\s\S]*?"rds_ssl_enforced":\s*(\d+)| Operation | Group | Criteria | Compare To | Disposition |
|---|---|---|---|---|
| Match Group | 1 | Equals | Group 2 | Pass |
Group 1 = total RDS instances, Group 2 = SSL-enforced count. When they match, 100% of instances are compliant. The same pattern works for S3, ALB, NLB, and other resources by swapping the key names.
Example 4 – AWS Config Rule Compliance Status
What it checks: The AWS Config rule for KMS key rotation shows COMPLIANT.
"ConfigRuleName": "cmk-backing-key-rotation-enabled-conformance-pack[^\]]*"ComplianceType": "([^\]]*)"| Operation | Group | Criteria | Value | Disposition |
|---|---|---|---|---|
| Match Group | 1 | Equals | COMPLIANT | Pass |
Example 5 – Load Balancers Using FIPS & TLS 1.3 (Multiple Rules)
What it checks: Every SSL policy must reference both FIPS and TLS 1.3.
\s*"ssl_policy":\s*"([\s\S]*?)"| Index | Operation | Group | Criteria | Value | Disposition |
|---|---|---|---|---|---|
| 01 | Match Group | 1 | Contains | TLS13 | Pass |
| 02 | Match Group | 1 | Contains | FIPS | Pass |
Both rules must pass. Each match's captured policy name is checked for both substrings. A policy with only TLS13 but not FIPS would fail rule 02.
Example 6 – IAM Users Not in Unexpected Groups
What it checks: No IAM groups exist with names other than "Administrators".
"GroupName":\s*"(?!Administrators")([^"]+)"| Operation | Criteria | Value | Disposition |
|---|---|---|---|
| Match Count | Equals | 0 | Pass |
The negative lookahead skips the Administrators group. If any other group is found (count > 0), the artifact fails.
Example 7 – Vulnerability Scan Has No Critical Findings
What it checks: A CSV vulnerability report contains zero rows with "Critical" severity.
,"Critical",| Operation | Criteria | Value | Disposition |
|---|---|---|---|
| Match Count | Equals | 0 | Pass |
A simple literal string match against CSV data. Each row containing the Critical column value increments the count. A related validator uses the same pattern but checks for "High" severity.
Example 8 – WAF Rules Configured
What it checks: At least one WAF rule is configured.
"Rules":\s*\[\s*\{| Operation | Criteria | Value | Disposition |
|---|---|---|---|
| Match Count | Greater Than Or Equal To | 1 | Pass |
Matches the opening of a non-empty JSON array under the "Rules" key. An empty array ("Rules": []) would not match.
Testing Your Regex
Before saving a validator, always test your regex against real artifact content. Recommended tool: regex101.com — select ECMAScript / JavaScript flavor. Paste your artifact content as the test string and your pattern in the expression field. Enable the g (global) and s (dotAll) flags to replicate Paramify's behavior.
Testing Checklist
- Set flavor to ECMAScript (JavaScript) and enable the
gandsflags. - Paste a real artifact payload as the test string.
- Verify match count matches your expectation.
- If using capture groups, confirm each group contains the correct value.
- Test a failing case to confirm the pattern does not match when it shouldn't.
- Test edge cases: missing keys, null values, extra whitespace.
NOTE — BACKSLASH ESCAPING
In Paramify's UI regex field, enter single backslashes (e.g., \s, \d). The CSV export doubles them (e.g., \\s, \\d) for the file format. When testing on regex101, use single backslashes.
Importing and Exporting Validators via CSV
Validators can be managed in bulk via CSV — useful for backups, environment migrations, or building validators in a spreadsheet before uploading.
Exporting Validators
1. Navigate to Implementation → Evidence
Select Implementation in the top navigation bar, then choose Evidence.
2. Open the more options menu
Click the ⋮ (more options) menu in the Validators section.
3. Select Export as CSV
The file downloads with all validator definitions.
Importing Validators
1. Prepare your CSV file
Use the column structure shown below. The easiest starting point is to export existing validators and modify them.
2. Navigate to Implementation → Evidence and select Import CSV
Select Implementation in the top navigation bar, choose Evidence, then click Import CSV.
3. Upload and confirm
Upload the file and review any validation warnings before confirming the import.
CSV Column Reference
| Column | Description |
|---|---|
| Type | AUTOMATED or MANUAL |
| Name | Display name of the validator |
| Statement | Human-readable description of what is being validated |
| Regex | The ECMAScript regex pattern. Backslashes are doubled in the CSV (\\s in file = \s in the UI). |
| Validation Rules | JSON array of rule objects (see structure below) |
| Evidence | Evidence ID(s) this validator applies to, newline-separated (e.g., EVD-KMS-ROT) |
| Reviewers | Assigned reviewer(s) |
| Review Notes | Optional notes for reviewers |
Validation Rules JSON Structure
[
{
"index": 1,
"regexOperation": "MATCH_COUNT", // or "MATCH_GROUP"
"regexOperationGroupNumber": 0, // group number for MATCH_GROUP; 0 for MATCH_COUNT
"criteria": "EQUALS", // EQUALS | GREATER_THAN_OR_EQUAL_TO | CONTAINS
"value": "CUSTOM_TEXT", // CUSTOM_TEXT | MATCH_GROUP
"valueGroupNumber": 0, // group number when value is "MATCH_GROUP"
"valueCustomText": "1" // literal value when value is "CUSTOM_TEXT"
}
]TIP
Export an existing validator and inspect the Validation Rules column to understand the format hands-on. Copy a row that uses a similar operation (Match Count vs. Match Group) as your starting point.
Comments
0 comments
Please sign in to leave a comment.