# atmos policy

The `policy` commands support policy authoring. They read literal policy documents from
`policy.d/`, or the directory selected by `ATMOS_POLICY_DIR`, without loading `atmos.yaml`,
discovering stacks, contacting CI APIs, installing tools, or executing hooks.

```shell
atmos policy check
atmos policy check --syntax-only
atmos policy check --root /path/to/project
atmos policy list
atmos policy schema function
atmos policy test tests/cases.json
```

`check` displays a human-readable summary by default; use `--format json` or `--format yaml` for structured output on stdout.
`list`, `schema`, and `test` produce JSON on stdout. Invalid configuration, unsupported input kinds, malformed
fixtures, and failed expectations return a nonzero exit status. They deliberately do not enforce
command admission against themselves, so a broken or denying bundle can still be inspected.
Normal operational commands retain their policy gates.

## check

`atmos policy check` validates document fields, CEL/Starlark/OPA compilation, JSON Schemas, unique rule identities,
selectors, CI requirements, approval specifications, hook references and definitions, and tool-pin
consistency. It then evaluates configured `on: file` rules against YAML/JSON files selected by globs,
relative to `--root` (default: current working directory). Use `--syntax-only` to check definitions
without reading input files. See [file checks](/policies/validation-engines#file-checks) for diagnostics,
input handling, and exit behavior. Other input kinds are not evaluated by this command. It does not require
installed hook executables or CI credentials. An absent or empty policy bundle is an error.

The default summary reports validation status and the rule and hook counts on stderr.
File checks also report each file's status and any field diagnostics.
It uses terminal styling when available and degrades to plain text when redirected or colors
are disabled. For scripts, request JSON or YAML explicitly:

```shell
atmos policy check --format json
atmos policy check --format yaml
```

```json
{
  "hooks": 0,
  "rules": 1,
  "valid": true
}
```

- **--format / -f** — Output format: text (default), json, or yaml.
  Structured output is written to stdout without the human-readable summary.
- **ATMOS\_POLICY\_CHECK\_FORMAT** — Environment equivalent of --format. The command-line flag takes precedence.
  ATMOS\_POLICY\_FORMAT is a fallback when ATMOS\_POLICY\_CHECK\_FORMAT is unset.

## list

`atmos policy list` prints the loaded definitions in deterministic order, including rule IDs,
input kinds, expressions, selectors, parameters, and effects. This is a view of the configured bundle;
it does not resolve remote libraries or execute predicates. Treat literal policy parameters as
potentially private when sharing the output.

## schema

- **input-kind** — One of command, component.command, function,
  source, plugin, auth, operation, terraform.plan,
  atmos.affected, or file. Prints the JSON Schema for input, rather than the
  entire request envelope. Terraform retains its native plan shape. The plugin kind
  describes the input of on: plugin rules; see plugin policies.

Use `atmos ci context` to inspect the provider-native CI snapshot. A schema describes available
fields; it does not attest that a particular command collected them.

## test

- **cases.json** — A nonempty JSON array of named fixtures, at most 16 MiB. Each fixture supplies a complete
  policy request and the expected aggregate decision. The format matches the policy library's
  tests/cases.json files.

```json
[
  {
    "name": "deny exec",
    "request": {
      "kind": "function",
      "input": {"name": "exec", "engine": "yaml", "provenance": "local", "source_file": "example.yaml"}
    },
    "status": "deny"
  }
]
```

Statuses are `allow`, `deny`, `not_applicable`, `awaiting_approval`, and `error`. A false predicate
normally produces `not_applicable`. Optional `error` values are `input_unavailable` or `evaluation`.
Use `hooks` to assert the selected hook requirements and `approvals` to assert approval requirements.
Approval fixtures test the outstanding requirement, not live review verification. No network calls or
hook execution occur. Fixtures contain supplied data and cannot authorize a real operation.

## Explain an operation

```shell
atmos terraform plan vpc -s prod --explain
atmos terraform plan vpc -s prod --dry-run --explain
```

- **--explain** — Add policy diagnostics to stderr while preserving normal command execution, enforcement,
  and stdout. Reports reached gates, rule outcomes, selector exclusions, approval verification,
  selected hook requirements, and configured input kinds never reached. Input values and function
  arguments are not printed.
- **ATMOS\_EXPLAIN** — Environment equivalent of `--explain`. The command-line flag takes precedence. When `--explain`
  is set, Atmos exports `ATMOS_EXPLAIN=true` to the processes it starts, so nested Atmos commands run by
  scripts, steps, workflows, and custom commands report their own policy diagnostics too.

`--explain` is not a preview flag. Combine it with a command's existing `--dry-run` when supported.
Dry-run cannot evaluate a saved-plan policy without a real plan; the diagnostic explicitly reports
that no saved-plan verdict was obtained. A failed earlier gate can prevent later gates from being reached.

## Try it out

### policies

Copy the example into a new directory and make it your own:

```shell
atmos init examples/policies
cd policies
```

Only Atmos is required. Validate the rule and run its offline fixtures, then follow the README to compare an allowed command with an intentional denial.

```shell
atmos policy check
atmos policy list
atmos policy test tests/cases.json
```

- [Installation guide](/install)
- [Explore the example](/examples/policies)
- [Initialization and repository settings](/cli/commands/init#examples-and-source-directories)
