Skip to main content

Main Config Reference (config.json)

Authoritative reference for the versioned Codeward policy file. For an orientation guide see: Configuration Overview. For deeper field/operator definitions see: Policy System. Style conventions: Style & Naming Guide.

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

Purpose

Define what Codeward scans, how findings are filtered, which change categories trigger actions (new | changed | removed | existing), and how results are output. Runtime context (diff mounts, GitHub metadata, environment variables) is intentionally external.

Top-Level Shape

{
"global": { "dependency_tree": false },
"vulnerability": [ /* vulnerability policies */ ],
"license": [ /* license policies */ ],
"package": [ /* package policies */ ],
"validation": [ /* validation policies */ ]
}

All arrays optional. Empty arrays are allowed for clarity.

Global

KeyTypeEffect
dependency_treebooleanAdds relationship enrichment fields (Relationship, Parents, Children, Targets) for package / license / vulnerability domains (slight performance cost).

Common Policy Schema (non‑Validation)

{
"name": "crit-high-block",
"disabled": false,
"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-diff.json", "changes": ["new","removed","changed"]}
]
}

Key Points:

  • rules is ALWAYS an array of objects: {"field": string, "type": operator, "value": string|number}.
  • Array entries are ORed (any rule passing keeps the record). Absence of rules means no filtering (all findings for the policy domain).
  • Only include actions you need (omitted change type defaults to no action → treated as informational if surfaced by outputs).
  • Multiple policies in the same domain can target different severities / subsets for progressive rollout.

Allowed Record Fields (Summary)

Full canonical tables: Policy System.

DomainCommon Filter / Display Fields (subset)
vulnerabilityVulnerabilityID, PkgName, PkgID, Severity, InstalledVersion, FixedVersion, Status
licenseName, Category, Severity, PkgName
packageName, Version, Relationship, Parents, Children
validationKey, Type, Value, Reason, Passing, Path

Validation Policy Differences

Validation requires content or filesystem context.

Additional Required Keys:

KeyPurpose
typeOne of `text
pathFile / directory / glob root for evaluation

Example (filesystem existence):

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

Example (text content):

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

Validation rule object shapes differ (some use path instead of field/value). See: Policy System — Validation Rule Shapes.


Domain Examples

Vulnerability (Progressive Rollout Pair)

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

License

[
{
"name": "prohibited-gpl",
"actions": {"new": "block", "existing": "warn"},
"rules": [ {"field": "Name", "type": "contains", "value": "GPL"} ],
"outputs": [ {"format": "markdown", "template": "table", "destination": "git:pr", "fields": ["Name","Category","Severity","PkgName"], "changes": ["new","changed"]} ]
}
]

Package

[
{
"name": "removed-deps-warn",
"actions": {"removed": "warn"},
"rules": [ {"field": "Name", "type": "hasPrefix", "value": "@types/"} ],
"outputs": [ {"format": "markdown", "template": "table", "destination": "log:stdout", "fields": ["Name","Version","Relationship"], "changes": ["removed"]} ]
}
]

Validation (text) — shown earlier


Rule Operators (Summary)

OperatorMeaning
eq / neEquality / inequality
lt / gt / le / geNumeric comparisons (where applicable)
contains / not_containsSubstring match
hasPrefix / hasSuffixString edge match
regexRegular expression (RE2 compatible)
exists / not_existsPresence (validation / filesystem)

Refer to Policy System for authoritative list and domain applicability.


Outputs (Quick Reference)

Minimal per-policy output object:

{"format": "markdown", "template": "table", "destination": "git:pr", "fields": ["VulnerabilityID","Severity"], "changes": ["new"]}

Common keys: format, template (omit for JSON), destination, fields, changes, group_by, combined, collapse, title, comment.

Detailed formatting / destinations: Output Formats, Output Destinations.

Combined JSON outputs must all be JSON and share a destination (enforced). Markdown/HTML may share a comment thread when combined.

Combined JSON semantics (anywhere in this file): a single concatenated array per destination (no wrapper object) when combined:true outputs share format+destination.


Actions

ActionEffectTypical Use
infoRecord only (non-blocking)Baseline visibility
warnNon-blocking signal (non-zero severity)Progressive rollout step
blockFails run (non-zero exit)Critical guardrail

Progressive enforcement pattern: start with block only for CRITICAL; later add HIGH; then gradually include other categories as backlog shrinks.


AI Governance Rationale

AI‑assisted commits can introduce high-severity vulnerabilities or prohibited licenses at scale. Diff‑aware policies let you block only net‑new critical risk while still surfacing historical issues for phased remediation, maintaining developer velocity without silent regression.


Common Mistakes & Fixes

ProblemCauseFix
Rules ignoredUsed legacy nested object (e.g. "rules": { "severity": [...] })Replace with array of {"field":"Severity","type":"eq","value":"CRITICAL"} entries
Everything marked newMissing main branch mount or CI_EVENT=prProvide /main, /branch volumes + set CI_EVENT=pr
Block not triggeredOnly existing findings presentEnsure actions include new and thresholds capture net‑new items
Validation rule errorMissing type / path for validation policyInclude both required keys
Mixed JSON + markdown in combined outputIncompatible formats with combined:trueUse uniform format or separate outputs
Unsupported field in fieldsField not in allowed domain setCheck allowed field tables; remove or adapt

Best Practices

GoalRecommendation
Noise reductionLimit PR outputs to new + changed changes; send existing to file/issue
ExplainabilityInclude fields that justify the action (e.g. Severity, FixedVersion)
Progressive rolloutUse multiple policies per domain for staged enforcement
ObservabilityAt least one JSON output per critical policy for dashboards
MaintainabilitySmall focused policies > one large multi-purpose policy
ReusabilityKeep environment-dependent values (paths, tokens) out of config file


Minimal final reminder: use array-based rules everywhere (except specialized validation rule forms) and keep runtime context in environment variables, not the config.