Policy CI Context
In GitHub Actions, policy rules can inspect the supplied event and allowlisted runner
metadata through ci. Declare required_ci when a rule needs complete provider data.
Inspect your inputs
Use atmos ci context in the job where the policy runs:
# List observed field names and JSON types without values.
atmos ci context --paths
# Inspect event identity and availability.
atmos ci context --query '{"event_name": .ci.metadata.data.GITHUB_EVENT_NAME, "status": .ci.event.status}'
Without --paths, the command prints the collected snapshot under ci, including native event
values. Keep snapshots private: event payloads can contain sensitive user-supplied content.
Collection requires no API permissions and does not fetch live reviews. Command admission still applies.
Every library policy includes an Inputs and examples section. Choose an example, search its fields, and copy a CEL or Starlark field expression. The Input JSON tab shows the corresponding request. These are tested examples, not exhaustive provider schemas.
GitHub event reference
Atmos defines the snapshot envelope; GitHub defines the keys inside ci.event.data.
ci.metadata.data.GITHUB_EVENT_NAME identifies the event. The payload is read from
GITHUB_EVENT_PATH, corresponding to the workflow's github.event object—not the entire
github context. See GitHub's variables reference
and context reference.
| Event name | Example native fields | Provider reference |
|---|---|---|
pull_request | action, pull_request.head, pull_request.base | Pull request payload |
pull_request_review | action, review, pull_request | Review payload |
push | ref, before, after | Push payload |
workflow_dispatch | ref, inputs | Manual workflow payload |
workflow_run | action, workflow_run | Workflow run payload |
These are lookup examples, not an event allowlist. The collector preserves the supplied JSON object without normalizing provider fields. Consult events that trigger workflows for Actions-specific availability, activity types, and payload differences. Check the actual snapshot and guard optional or null fields; do not assume every webhook example is present in every Actions run.
GitHub event names are separate from Atmos lifecycle events such as input.event == 'after.terraform.plan'.
A triggering pull_request_review payload is historical event data, not proof of a current qualifying
approval. Use approval requirements for fresh verification.
Snapshot schema
GitHub Actions uses provider github-actions and schema github-actions/v1.
| Path | Type | Contents |
|---|---|---|
ci.provider | String | Provider identifier |
ci.schema | String | Provider-owned schema version |
ci.metadata | Dataset | Allowlisted environment variables; values remain strings |
ci.event | Dataset | Native JSON object read from GITHUB_EVENT_PATH |
ci.facts | Object | Empty for the supplied-event collector; no live API facts |
Each dataset has this shape:
{
"data": {"GITHUB_EVENT_NAME": "pull_request"},
"status": "available",
"complete": true,
"provenance": {
"source": "github-actions:environment",
"collected_at": "2026-10-12T12:00:00Z",
"revision": "<GITHUB_SHA>"
}
}
| Dataset field | Meaning |
|---|---|
data | Provider-native object; can be absent when collection fails |
status | available, unavailable, or incomplete |
complete | Whether collection completed successfully |
provenance.source | github-actions:environment or github-actions:GITHUB_EVENT_PATH |
provenance.collected_at | UTC collection timestamp, not the event timestamp |
provenance.revision | GITHUB_SHA when supplied |
reason | Explanation when data cannot be supplied |
Missing or unreadable event files are unavailable. Invalid JSON, non-object JSON, read failures,
or events exceeding 8 MiB are incomplete. Missing data is not replaced by an empty event.
Outside a detected CI provider, ci is null. A provider without snapshot support reports
unavailable datasets. Requiring GitHub data in either case blocks the command.
Required inputs
required_ci:
- provider: github-actions
schema: github-actions/v1
dataset: event
provider- Required string. Exact provider identifier.
schema- Required string. Exact snapshot schema version.
dataset- Required string. Use
metadataoreventfor the GitHub supplied-event collector. The schema also acceptsfacts, but this collector supplies no facts. fact- Required only for
dataset: facts; invalid for other datasets.
Requirements are checked before evaluating a matching-kind rule's predicate. The provider and
schema must match, and each dataset must be available, complete, and contain non-null data.
rule: false does not bypass a missing requirement.
Reject fork PR plans
apiVersion: atmos/v1
kind: Policy
metadata:
name: github-safety
spec:
policies:
reject-fork-plan:
on: terraform.plan
action: deny
reason: This privileged plan job does not accept fork pull requests
required_ci:
- provider: github-actions
schema: github-actions/v1
dataset: event
rule: >-
has(ci.event.data.pull_request) &&
ci.event.data.pull_request.head.repo.full_name != ci.event.data.pull_request.base.repo.full_name
This rule is a plan gate, not a sandbox. It runs after planning and before saved-plan apply. Do not execute untrusted pull-request code with privileged credentials and rely on this check to make that execution safe.
Metadata allowlist
Only variables present in the runner environment are included:
Example: ci.metadata.data.GITHUB_EVENT_NAME == 'pull_request'.
Tokens and arbitrary environment variables are not copied into metadata.
GitHub permissions
| Capability | Workflow permission |
|---|---|
| Evaluate supplied event/metadata and produce local output | No additional API permission; collection makes no API calls |
| Check out repository policies/configuration | contents: read |
| Verify designated reviewers against current PR details and paginated reviews | pull-requests: read |
| Publish existing Native CI commit statuses | statuses: write |
Minimal permissions for a job that checks out policies and evaluates them:
permissions:
contents: read
When the job also publishes Native CI statuses:
permissions:
contents: read
statuses: write
Use GITHUB_TOKEN; a PAT or GitHub App is not required for these capabilities. Configure the
checkout and policy directory using the enforcement setup.
See CI authentication and permissions
for the surrounding workflow.
Fork and Dependabot runs can have reduced token permissions. Keep policy failures blocking even when status publication is unavailable. The supplied event records the triggering event, not current review state; it must not be treated as verified approval. Approval requirements fetch fresh evidence separately when selected. These policies evaluate the current invocation, not outcomes aggregated from other component jobs.