Skip to main content

Policy System

Codeward applies a consistent, diff‑aware policy model across all scan domains so you can codify governance (security, license, supply chain, structural validation) and enforce it pre‑merge.

Canonical change category order: new, changed, removed, existing (see Glossary). Formatting & naming conventions: Style & Naming Guide.

Why Policies (AI & Velocity Context)

High‑velocity and AI‑assisted changes can silently introduce vulnerable or prohibited components. Policies:

  • Express guardrails as code (repeatable, reviewable)
  • Reduce subjective review effort (objective actions per change type)
  • Allow gradual tightening (warn → block) without large rewrites

Supported Policy Types

TypeSource DataPrimary Use
vulnerabilityTrivyGovern CVE exposure (severity / fixed versions)
licenseTrivyRestrict license categories / names (compliance posture)
packageTrivyTrack dependency additions / removals / version shifts
validationFilesystem / contentAssert structural & content requirements (text/json/yaml/filesystem)

Change Categories (Diff Mode)

new, changed, removed, existing — canonical order (see Glossary). Each policy defines an action for any subset (omitted keys ignored).

Actions

ActionEffect
infoRecord in output only
warnRecord + non‑blocking signal
blockMarks run as failing (non‑zero exit) if any section produced

A policy need only define the change keys it cares about (others can be omitted).

Configuration Overview

Top-level arrays in config.json: vulnerability, license, package, validation (any may be empty). Each element:

{
"name": "string",
"disabled": false, // optional
"actions": {"new":"block","existing":"warn"},
"rules": [ {"field":"Severity","type":"eq","value":"CRITICAL"} ],
"outputs": [ { ...output config... } ],
...validation only extras...
}

Validation policies add required keys: type (text|json|yaml|yml|filesystem) and path (target file / directory). Rule objects differ per validation type (see below).

Filter Rule Object (non-validation policies)

{"field": "<AllowedField>", "type": "op", "value": "string"}

Allowed operators (generic): eq, ne, lt, gt, le, ge, contains, not_contains, hasPrefix, hasSuffix, regex (depending on field semantics). Only fields from the underlying record type are valid.

Allowed Record Fields (Filter / Display) (Canonical)

PolicyFields
vulnerabilityVulnerabilityID, PkgID, PkgName, InstalledVersion, FixedVersion, Status, Severity, Relationship, Children, Parents, Targets
licenseSeverity, Category, PkgName, Name, Relationship, Children, Parents, Targets
packageID, Name, Version, Relationship, Children, Parents, Targets
validationKey, Type, Value, Reason, Passing, Path (display fields; filtering not applied in same manner)

Rule Operators (Canonical)

Generic operators (filtering across vulnerability, license, package domains): eq, ne, lt, gt, le, ge, contains, not_contains, hasPrefix, hasSuffix, regex.

Validation adds (by rule type):

  • Text / JSON / YAML / YML: same generic set above, plus context-specific usage of values.
  • JSON / YAML / YML additionally: exists, not_exists (for key presence checks) if using path-style rules (see Validation shapes below).
  • Filesystem: exists, not_exists.

Summary:

OperatorMeaning
eq / neEquality / inequality
lt / gt / le / geNumeric comparison (where applicable)
contains / not_containsSubstring presence/absence
hasPrefix / hasSuffixString edge match
regexRE2-compatible regular expression
exists / not_existsPresence/absence (validation & filesystem)

(Operator applicability: see individual validation rule shape tables below.)

Output Configuration

(See also: Combining & Grouping for destination merge rules.) High-level description of output configuration options. Combined JSON groups produce a single concatenated array (no wrapper object; uniform format required).

Per Policy Output

FieldPurpose
formatmarkdown | html | json
destinationfile:<path> | log:stdout | log:stderr | git:pr | git:issue
templatetable | text (ignored for json)
fieldsSubset of allowed display fields
group_byArray of fields to merge/group results
changesLimit change categories for this output
combinedCombine multiple policy reports at same destination
collapse(markdown/html) make section collapsible
title/commentPresentation overrides

JSON outputs must omit template. Combined JSON groups must be uniformly JSON.

Validation Policy Rule Shapes

Validation TypeRule KeysRule Types
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

Example (text validation – disallow common secret tokens):

{
"validation": [
{
"name": "disallow-inline-secrets",
"type": "text",
"path": "app/config.env",
"actions": {"new": "block"},
"rules": [
{"type": "regex", "value": "(?i)(password|secret|apikey)\s*=\s*.+"}
],
"outputs": [
{"format": "markdown", "template": "text", "destination": "git:pr", "title": "Potential Inline Secrets"}
]
}
]
}

(If targeting many files, invoke multiple validation policies or supply path patterns per implementation constraints.)

Correct Example Policies

Vulnerability (Block Critical & High New; Warn Existing)

Example focuses on severity gating and mixed output formats.

{
"vulnerability": [
{
"name": "crit-high-vulns",
"actions": {"new": "block", "existing": "warn", "removed": "info", "changed": "warn"},
"rules": [
{"field": "Severity", "type": "eq", "value": "CRITICAL"},
{"field": "Severity", "type": "eq", "value": "HIGH"}
],
"outputs": [
{"format": "markdown", "template": "table", "destination": "git:pr", "fields": ["VulnerabilityID","PkgName","Severity","FixedVersion"], "changes": ["new","existing"], "collapse": true},
{"format": "json", "destination": "file:/results/vuln-changes.json", "changes": ["new","removed","changed"]}
]
}
]
}

License (Block Introduction of Certain Categories)

{
"license": [
{
"name": "no-copyleft-intro",
"actions": {"new": "block", "existing": "warn", "removed": "info"},
"rules": [
{"field": "Category", "type": "eq", "value": "Copyleft"}
],
"outputs": [
{"format": "markdown", "template": "text", "destination": "git:pr", "title": "License Category Introductions", "changes": ["new"]}
]
}
]
}

Package (Track Additions Only)

{
"package": [
{
"name": "new-deps-tracker",
"actions": {"new": "warn"},
"rules": [],
"outputs": [
{"format": "json", "destination": "file:/results/new-deps.json", "changes": ["new"], "fields": ["Name","Version","Relationship","Parents"]}
]
}
]
}

Validation (Filesystem Presence)

{
"validation": [
{
"name": "require-security-policy",
"type": "filesystem",
"path": ".",
"actions": {"new": "block"},
"rules": [
{"type": "exists", "path": "SECURITY.md"}
],
"outputs": [
{"format": "markdown", "template": "table", "destination": "git:pr", "title": "Required Governance Files"}
]
}
]
}

Multiple Policies Per Type

Combine granular policies instead of one large, hard‑to‑tune policy:

  • Separate severity bands
  • Separate license categories (copyleft vs restricted vs audit‑only)
  • Separate package introduction tracker vs remediation tracker

Progressive Enforcement

Moved to dedicated page: see Progressive Enforcement for phased rollout strategy and escalation guidance.

Best Practices

ObjectiveRecommendation
Minimize noiseLimit PR outputs to new + changed; route existing elsewhere
Show improvementsDedicated output with removed only
Justify blockingInclude remediation fields (e.g., FixedVersion)
Automate dashboardsEmit JSON arrays (deterministic)
Avoid config sprawlCompose many small focused policies
Safe rolloutApply phases from Progressive Enforcement page

Common Mistakes & Fixes

ProblemCauseFix
Validation policy rejectedMissing type or pathAdd required keys
Rules ignoredWrong schema (object instead of array)Use an array of rule objects
Combined JSON errorMixed markdown + JSON in combined groupUse single format per combined destination
Everything blockedOverbroad rule + block on all change typesNarrow rules / limit new to block
License rule ineffectiveUsed non-existent field name (e.g., "license")Use Name or Category

Next: review full configuration structure in the Main Config Reference.