Validator Extension Guide
Learn how to add custom validators and override embedded ones using the --data flag.
Overview
Validators follow the same extensibility model as components. The --data flag points to a directory containing custom resources that merge with (or override) the embedded ones. For validators, this means providing a validators/catalog.yaml in your data directory.
External catalog entries merge with embedded entries at load time. If an external entry has the same name as an embedded one, the external entry replaces it.
Adding a Custom Validator
Step 1: Write the Validator
A validator is any container that follows the exit code contract:
The container receives:
- Snapshot at
/data/snapshot/snapshot.yaml - Recipe at
/data/recipe/recipe.yaml - Kubernetes API access via in-cluster ServiceAccount
Evidence output goes to stdout. Debug logs go to stderr. On failure, write a reason to /dev/termination-log (max 4096 bytes).
Step 2: Build and Push the Image
Step 3: Create a Catalog Entry
Create my-data/validators/catalog.yaml:
Step 4: Reference in Recipe
Add the check to your recipe’s validation section:
If you omit the checks list, all catalog entries for the phase run (embedded + custom).
Step 5: Run Validation
Overriding Embedded Validators
To replace an embedded validator with a custom implementation, use the same name:
The external entry replaces the embedded operator-health validator entirely.
Language-Agnostic Contract
The validator contract is a process convention, not a Go interface. Any language works as long as the container follows the exit code and I/O contract.
Bash Example
Dockerfile:
Catalog entry:
Image Requirements
- Must run as non-root (validator Jobs use
runAsNonRoot: true) - Must handle the mounted data paths (
/data/snapshot/,/data/recipe/) - Should respect timeout — the Job has
activeDeadlineSecondsset from the catalog entry - Should write meaningful evidence to stdout for the CTRF report
- Must use explicit image tags (not
:latest) for reproducibility in external catalogs
Private Registries
If your validator image is in a private registry, use --image-pull-secret:
The secret must exist in the validation namespace and be of type kubernetes.io/dockerconfigjson.
See Also
- Validator Development Guide — Writing upstream Go checks
- Validator Catalog Reference — Catalog schema
- CLI Reference — Validate command flags
- Data Architecture — External data provider system