Schema validation

CrowdControl has an opt-in static validator that catches field typos, type mismatches, and bad operator usage before any document is evaluated. It's a compile-time safety net.

Defining a schema

A schema is a JSON file that maps dotted field paths to expected types.

{
  "fields": {
    "user.name":      "string",
    "user.groups":    "list",
    "pr.draft":       "bool",
    "pr.approvals":   "number",
    "resource.type":  "string",
    "resource.name":  "string",
    "resource.change": "map",
    "labels":         "list",
    "plan.destroys":  "list",
    "plan.creates":   "list"
  }
}

Supported types: string, number, bool, list, map, any.

  • Fields typed as map allow arbitrary nested access (e.g. resource.change.after.acl is valid when resource.change is map).
  • Fields typed as any skip all type checks.

Running validation

cc validate --schema ./schema.json ./policies

What it catches

  • Unknown fields — a field path that does not appear in the schema and whose parent is not a map. Likely a typo.
  • Type mismatches — using a numeric operator (<, >) on a string field, contains on a bool field, intersects/is_subset on a non-list field, matches/matches_regex on a non-string field.
  • Aggregate target errorscount(field) where the schema says the field is neither a list nor a number.
  • Quantifier target errorsany field ... or all field ... where the field is not a list.
  • Arithmetic type errors — a field used in an arithmetic expression that the schema says is not a number.
  • Message interpolation errors{field.path} references in message strings that don't exist.

Example output

WARN [blast-radius]: unknown field "plan.destorys" — not in schema (typo?)
WARN [production-approval]: pr.approvals < used with numeric operator, schema says string
Note

Schema validation produces warnings, never errors. You can ship a policy with schema warnings — but CI should fail the build on them.