kat

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 19, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

kat - Kubernetes Admission Tester

CI Go Report Card License

kat is a lightweight, local testing tool for Kubernetes Admission Policies (ValidatingAdmissionPolicy and MutatingAdmissionPolicy). It allows you to write test cases using standard Kubernetes manifests and verify your policies' behavior without needing a running cluster.

Features

  • Standard Kubernetes YAML: Write tests using plain K8s manifests - no new DSL to learn.
  • Full CEL Support: Uses the official Kubernetes CEL libraries for 100% accurate evaluation.
  • Comprehensive Policy Support:
    • ValidatingAdmissionPolicy (Allow, Deny, Warn, Audit)
    • MutatingAdmissionPolicy (Mutate, No-op)
  • All Operations: Supports CREATE, UPDATE, DELETE, and CONNECT operations.
  • Golden File Testing: Automatically verifies mutated objects against expected golden files.
  • Rich Context: Simulate complex scenarios with userInfo, namespaceObject, and matchConditions.
  • Parameter Testing: Test parameter-driven policies (paramKind/paramRef).

Installation

go install github.com/zemanlx/kat@latest

Or build from source:

git clone https://github.com/zemanlx/kat.git
cd kat
go install

Usage

The recommended way to use kat is to run it from the root of your repository. It will automatically discover and execute all tests found in tests/ directories recursively.

kat .

This commands will:

  1. Find all tests directories.
  2. Locate the corresponding Policy and Binding for each test (by looking up in the directory tree).
  3. Execute all found tests.

You can also target specific directories or files:

# Run tests for a specific policy
kat ./policies/my-policy/tests

# Run a specific test case
kat ./policies/my-policy/tests/my-policy.basic-test.object.yaml
Flags
  • -run <regex>: Run only tests matching the regex pattern.
  • -v: Verbose output (shows detailed execution steps).
  • -json: Output results in JSON format.
kat -v -run "prod-.*-deny" .

Project Structure & Discovery

kat is designed to fit naturally into existing Kubernetes repositories, including those using Kustomize.

The tool works by discovery:

  1. It looks for tests/ directories containing test files.
  2. It looks for policy and binding files in the parent directory of tests/.

Supported filenames include:

  • policy.yaml / policies.yaml
  • binding.yaml / bindings.yaml
  • Any file ending in .policy.yaml or .binding.yaml

Note: You can define multiple policies and bindings in a single file (separated by ---), or split them across multiple files. The tool loads all valid policy/binding resources found in the directory.

This allows you to keep your tests co-located with your policy definitions. You just need to add a tests/ folder alongside your manifests.

Example Layout:

policies/
├── team-label-policy/
│   ├── kustomization.yaml  # (Optional) Kustomize file
│   ├── policy.yaml         # The AdmissionPolicy definition
│   ├── binding.yaml        # The AdmissionPolicyBinding
│   └── tests/              # Add this folder for kat
│       ├── team-label.has-label.allow.object.yaml
│       ├── team-label.missing.deny.object.yaml
│       └── ...

In this setup, running kat . at the root will automatically find the tests directory, associate it with the policy in the parent team-label-policy directory, and execute the tests.

Writing Tests

Tests are defined by file naming conventions. The filename structure determines the test type and expectations.

File Naming Convention

Pattern: <policy-name>.<test-name>.<expect>.<type>.yaml

Requirement: The <policy-name> prefix must match the metadata.name of the policy being tested. (If a directory contains only a single policy, kats automatically associates all tests with that policy).

  • expect: allow, deny, warn, audit (for Validating)
  • type: object, oldObject, request, params
Validating Admission Policy

1. Expect Allow: Create a file ending in .allow.object.yaml.

# my-policy.test-1.allow.object.yaml
apiVersion: v1
kind: Pod
metadata:
  name: allowed-pod
  labels:
    cost-center: "123"

2. Expect Deny: Create a file ending in .deny.object.yaml.

# my-policy.test-2.deny.object.yaml
apiVersion: v1
kind: Pod
metadata:
  name: denied-pod
  # Missing required labels

3. Expect Specific Message: Add a .message.txt file side-by-side.

# my-policy.test-2.deny.message.txt
Pod must have a cost-center label
Mutating Admission Policy

1. Mutation Test: Provide the input object and the expected output (golden file).

  • Input: my-policy.test-1.object.yaml
  • Expected: my-policy.test-1.gold.yaml

If the actual mutation result differs from the golden file, the test fails and prints a diff.

Advanced Scenarios
Request Context (.request.yaml)

Use a .request.yaml file to provide additional admission context like user info or namespace details.

# my-policy.test-1.allow.request.yaml
operation: CREATE
userInfo:
  username: "system:serviceaccount:kube-system:job-controller"
namespaceObject:
  metadata:
    labels:
      environment: production
Parameters (.params.yaml)

For policies using paramKind, provide the parameter resource.

# my-policy.test-1.allow.params.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: policy-config
data:
  excludedNamespaces: "kube-system,monitoring"
Operations (UPDATE / DELETE)
  • UPDATE: Provide both .object.yaml (new) and .oldObject.yaml (old).
  • DELETE: Provide only .oldObject.yaml (resource being deleted).

Examples

Check the test-policies-pass directory for a comprehensive set of examples covering:

  • Basic validation and mutation
  • Parameters and ConfigMaps
  • Namespace-based logic
  • CONNECT operations (kubectl exec)
  • Match conditions
  • Warnings and Audit annotations

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL