> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenable.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Conftest

> OPA-based configuration file testing with cross-file support

## Overview

Conftest tests structured configuration data against Rego policies. It supports many config formats and can validate consistency across multiple files using the `--combine` flag.

## Capabilities

* Tests YAML, JSON, HCL, Dockerfile, TOML, XML, INI, and many more formats
* Cross-file analysis via `--combine` flag
* `deny`, `warn`, and `violation` rule types
* Structured error metadata via `violation` rules

## Limitations

* Tests structured config data, not application source code -- check out [Semgrep](/integrations/guardrails/semgrep) or [CodeQL](/integrations/guardrails/codeql) for source code analysis
* Does not test runtime infrastructure state -- check out [InSpec](/integrations/guardrails/inspec) or [Goss](/integrations/guardrails/goss) for runtime validation

## Cross-File Analysis

By default, conftest processes each file independently. The `--combine` flag merges all input files into a single array where each element has:

* `path`: the file path
* `contents`: the parsed file data

This enables policies that correlate data across files -- e.g., verifying Deployment selectors match available Services, or ensuring config values are consistent across environments.

```bash theme={null}
# Each file tested independently
conftest test deployment.yaml service.yaml

# Files combined into single input array for cross-file checks
conftest test deployment.yaml service.yaml --combine
```

## Generated Format

* **Language:** Rego
* **Structure:** Policy files in `package main` with `deny`/`warn` rules
* **Execution:** `conftest test <files> [--combine]`

## Example Guardrail

```rego theme={null}
package main

# Single-file check
deny contains msg if {
  input.kind == "Deployment"
  not input.spec.template.spec.securityContext.runAsNonRoot
  msg := sprintf("Deployment %s must run as non-root", [input.metadata.name])
}

# Cross-file check (requires --combine)
deny contains msg if {
  some i
  input[i].contents.kind == "Deployment"
  deploy := input[i].contents
  not has_matching_service(deploy)
  msg := sprintf("Deployment %s has no matching Service", [deploy.metadata.name])
}

has_matching_service(deploy) if {
  some j
  input[j].contents.kind == "Service"
  input[j].contents.spec.selector.app == deploy.spec.selector.matchLabels.app
}
```

Learn more at [Conftest documentation](https://www.conftest.dev/) and [OPA Rego language](https://www.openpolicyagent.org/docs/latest/policy-language/).
