Custom policies
YAML and Python checks.
Built-in checks cover the common cases, but every org has its own rules — “all resources must have a cost-center tag,” “only these instance types,” “no security group named legacy-*.” Checkov lets you write custom policies two ways: simple ones in YAML (a declarative attribute check), and complex ones in Python (full logic against the parsed resource). You point Checkov at your policy directory with --external-checks-dir.
metadata:id: "CKV_ACME_1"name: "Ensure resources have a cost-center tag"category: "CONVENTION"definition:cond_type: "attribute"resource_types: ["aws_instance", "aws_s3_bucket"]attribute: "tags.cost_center"operator: "exists"
$ checkov -d . --external-checks-dir ./policiesCheck: CKV_ACME_1: "Ensure resources have a cost-center tag"FAILED for resource: aws_s3_bucket.logs
YAML vs Python, and reuse
Use YAML policies for straightforward attribute/connection checks (a field equals/exists/matches) — they are readable and quick. Drop to Python when you need real logic: cross-resource relationships, computed conditions, custom messages. Either way, custom policies are code: keep them in a versioned repo, test them against fixtures, and distribute them as a shared pack so every team’s CI enforces the same org rules. This is where Checkov overlaps with OPA/Conftest — choose based on how much programmability you need.