Policy Inputs and Expressions
Each rule evaluates a boolean CEL expression or Starlark function body against a captured input object. Predicates do not execute commands, make network requests, read files, or collect additional inputs.
Expression variables
The table below uses CEL syntax. Starlark policies receive the same snapshots
as ctx.input, ctx.params, ctx.ci, and ctx.request, with dictionary indexing for nested fields.
| Variable | Type | Contents |
|---|---|---|
input | Object | Data for the rule's on kind |
params | Object | Rule's with values; empty object by default |
ci | Object or null | Provider-native CI snapshot; null when no provider is detected |
request.kind | String | terraform.plan, operation, atmos.affected, function, source, command, or component.command |
request.revisions | Object | governing, base, head; empty strings when not supplied |
request.subject | Object or null | Instance identity and metadata for plan/lifecycle attachments |
ci is a snapshot object, not the boolean ci variable used by ordinary hook/workflow conditions.
Affected analysis populates comparison base and head commit IDs. The governing revision is not
inferred from either comparison revision. Plan and lifecycle integrations leave revision fields empty.
To discover fields, open Examples on a library policy, choose a scenario,
and select Field explorer. It shows types and copyable CEL/Starlark expressions for each tested input. For the actual
CI payload in your job, run atmos ci context --paths.
Admission inputs
See Execution Admission for function names, CLI command paths, and component command capabilities. These inputs are available without affected analysis.
For on: source, see Source and Filesystem Policies for destination fields
and local path confinement. Source rules run before guarded reads and downloads.
Operation input
Use on: operation for Terraform, Helmfile, Helm, and Kubernetes lifecycle events.
{
"event": "after.terraform.plan",
"component_type": "terraform",
"command": "plan",
"component": "vpc",
"stack": "prod-us-east-1",
"status": "success",
"exit_code": 2,
"dry_run": false
}
| Field | Type | Meaning |
|---|---|---|
event | String | Canonical before.<component_type>.<command> or after.<component_type>.<command> lifecycle event |
component_type | String | terraform, helmfile, helm, or kubernetes |
command | String | Operation represented by the normalized event; deploy aliases use apply events |
component | String | Component argument |
stack | String | Selected stack |
status | String | success or failure; before-events begin with success. A Terraform plan exit code of 2 counts as success unless policy enforcement failed |
exit_code | Integer | Recorded command exit code; not proof that policies passed |
dry_run | Boolean | Whether this invocation is a dry-run |
Select the lifecycle event explicitly:
input.event == 'before.helm.delete' && input.stack.startsWith('prod-')
See Hooks for event selection and failure behavior. Operation input contains execution metadata, not resolved component settings or a changed-files/affected-component inventory.
Terraform plan input
With on: terraform.plan, input is the native saved-plan JSON object. See
Terraform Plans for extraction and validation rules.
has(input.resource_changes) && input.resource_changes.exists(r,
r.mode == 'managed' && 'delete' in r.change.actions)
Affected input
Use on: atmos.affected to inspect changed files, instances, components, stacks, and structured
fields before affected results are consumed. See Affected Changes for the
input contract, examples, collection scope, and enforcement requirements.
Missing and unknown values
| Condition | Handling |
|---|---|
| Optional field absent | Use has(object.field) before accessing it |
Field present with null | Check object.field != null before reading nested values |
| Terraform value unknown until apply | Inspect change.after_unknown; missing planned data is not evidence of compliance |
| CI data required for a decision | Declare required_ci; do not substitute an empty object |
| Expression error or non-boolean result | Block the command |
Use presence checks only when absence is acceptable. For a required attribute, deny when it is missing, null, empty, or unknown. See the required Owner tag example.
Evaluation results
| Result | Effect |
|---|---|
Predicate false | This rule does not apply |
Predicate true, action: deny | Block; another rule cannot override the denial |
Predicate true, action: hooks | Require the selected hooks according to their execution/success flags |
| Wrong input kind | Rule does not apply to this request |
| Missing required input, invalid expression, or evaluation error | Block |
CEL evaluation has a runtime cost limit of 100,000. Expressions over large inputs may hit this limit and block rather than evaluate without a bound.