Skip to main content

Validation Policies

Validation policies assert security, compliance, and project hygiene rules against file contents (text, json, yaml), filesystem structure, or configuration values. They complement vulnerability / license / package policies by covering custom guardrails your org needs.

Overview

Each validation policy evaluates one path pattern (file(s) or filesystem) using rule objects. Diff categories (new | changed | removed | existing) still drive actions (see semantics: Diff-Based Analysis), but validation policies focus on pass/fail of rule checks within the current head version. Use them to block introduction of insecure patterns while observing existing debt. Staged rollout patterns: Progressive Enforcement.

Style & naming conventions (actions formatting info | warn | block, canonical change order) live in the Style & Naming Guide.

Canonical change category order everywhere: new, changed, removed, existing.

Rationale / Principles

PrincipleWhy
Explicit assertionsPrevent silent drift in critical config (Dockerfile, CI workflows, package.json).
Diff gatingOnly new / changed violations block; existing backlog can surface but remain non‑blocking.
Narrow policiesSingle intent per policy simplifies tuning & rollout.
Progressive enforcementStart warn → graduate to block after confidence.
AI governanceAI‑generated config/scripts may omit mandatory hardening; policies catch omissions early.

Schema (Subset)

Full schema, operators, allowed fields: Policy System. Style conventions: Style & Naming Guide.

{
"validation": [
{
"name": "dockerfile-non-root",
"type": "text",
"path": "Dockerfile",
"actions": {"new": "block", "changed": "block", "existing": "warn"},
"rules": [ {"type": "contains", "value": "USER"} ],
"outputs": [ {"format": "markdown", "template": "table", "destination": "git:pr", "fields": ["key","reason","passing"], "changes": ["new","changed","existing"]} ]
}
]
}

Notes:

  • Same per‑change actions map as other policies (no single action key).
  • rules array (OR). No nested keyed objects.
  • Types: text | json | yaml | yml | filesystem.
  • Filesystem rules use path with exists / not_exists.

Rule Reference (Implemented)

Type ContextKeysOperators
texttype, valueregex, contains, not_contains, hasPrefix, hasSuffix, eq, ne
json / yaml / ymltype, key, valueeq, ne, lt, gt, le, ge, contains, not_contains, hasPrefix, hasSuffix, regex, exists, not_exists
filesystemtype, pathexists, not_exists

Examples:

{"rules":[{"type":"regex","value":"^FROM.+@sha256"}]}
{"rules":[{"type":"exists","key":"scripts.test"}]}
{"rules":[{"type":"not_contains","value":"password"}]}
{"rules":[{"type":"exists","path":"README.md"}]}

Progressive Enforcement Examples

(See strategy guidance: Progressive Enforcement)

Harden Dockerfile Stepwise

"validation": [
{"name":"dockerfile-user","type":"text","path":"Dockerfile","actions":{"new":"warn","changed":"warn"},
"rules":[{"type":"contains","value":"USER"}],
"outputs":[{"format":"markdown","template":"table","destination":"git:pr","fields":["key","reason","passing"],"changes":["new","changed"]}]},
{"name":"dockerfile-user-block","type":"text","path":"Dockerfile","actions":{"new":"block","changed":"block","existing":"warn"},
"rules":[{"type":"contains","value":"USER"}],
"outputs":[{"format":"markdown","template":"table","destination":"git:pr","fields":["key","reason","passing"],"changes":["new","changed","existing"],"collapse":true}]}
]

Secure CI Workflow

{"name":"workflow-permissions","type":"yaml","path":".github/workflows/*.yml",
"actions":{"new":"block","changed":"block","existing":"warn"},
"rules":[
{"type":"eq","key":"permissions.contents","value":"read"},
{"type":"not_contains","key":"jobs.*.steps[*].run","value":"curl | sh"}
],
"outputs":[{"format":"markdown","template":"table","destination":"git:pr","fields":["key","reason","passing"],"changes":["new","changed"]}]
}

Required Files (filesystem)

{"name":"required-readme","type":"filesystem","path":".",
"actions":{"new":"info","changed":"info","removed":"info","existing":"info"},
"rules":[{"type":"exists","path":"README.md"}],
"outputs":[{"format":"json","destination":"file:/results/required-files.json","combined":true}]}

Output Strategy

GoalPattern
PR remediation clarityMarkdown table (key, reason, passing) with only failing new/changed (filter rules + changes).
Backlog surfacingSeparate policy routing existing to file:/ json.
Automation ingestionCombined JSON export; omit template field (see Combining & Grouping).
Minimal noiseRestrict fields to key, reason, passing.

Combined JSON semantics: a single concatenated array containing all selected records across all matching policies (not multiple JSON roots).

Best Practices

ObjectiveRecommendation
Avoid over-blockingStart with warnings to tune patterns.
Express rationaleUse comment for why rule matters.
Keep rules tightPrefer explicit regex anchors to broad contains.
Separate intentsOne policy per domain (Dockerfile user, workflow perms).
Maintain consistencyReuse shared output destinations & formats.

Common Mistakes & Fixes

ProblemCauseFix
Single action key usedLegacy schema misunderstandingReplace with actions map (new,changed,removed,existing).
Rules ignoredNested object form; missing arrayUse "rules": [ {..}, {..} ].
JSON output error (template)Template set while format=jsonRemove template key for json outputs.
Fields rejectedUnsupported display fieldUse only key,type,value,reason,passing,path.
Over-reporting existing debtIncluded existing in PR outputLimit changes to new/changed for PR outputs.

AI Governance: Validation policies ensure AI or human rapid edits cannot remove essential security lines (e.g., non-root USER) or add unsafe constructs without immediate detection.