atmos ai skill install atmos-policyAtmos Policy
Use this skill for the experimental policy engine and reusable library, not for general validation
or ordinary lifecycle-hook configuration. Use atmos-hooks for non-policy hook definitions and
atmos-validation for existing JSON Schema/OPA settings.validation behavior.
Establish capabilities before authoring
Check the installed Atmos version/help and the matching source/docs. Do not infer a command exists
from the PRD: atmos policy check/test/explain is proposed, not implemented in this branch.
The current opt-in is policy.d/ at the project root that atmos.yaml discovery selects (the working directory, then the Git root, then the nearest ancestor with atmos.yaml), overridden by ATMOS_POLICY_DIR, containing strict atmos/v1
kind: Policy documents. Inline CEL and restricted Starlark run. A Starlark predicate is a
function body over detached, read-only JSON data that must return a strict boolean; it has no
automation host, module loader, filesystem, network, or logging API. Rego is not available
through this loader. Existing Rego validation is separate and remains supported. Do not migrate legacy configuration to proposed policy:
attachments yet.
Use central match selectors for instance attachments: literal labels (all), tags (any by default,
tag_mode: all supported), exact component names, stacks, and component types. These use resolved
metadata from existing inheritance, not inline policy inheritance. Protect the governing directory.
Distinguish input kind, component type, and CI provider:
terraform.plan: native JSON extracted privately from a saved binary plan. Evaluated after successful plan, including no-change plans, and again before applying the evaluated private copy. Implicit apply/deploy and direct destroy are rejected when plan policies are enabled.operation: lifecycle event, component type/name, stack, command, status, exit code, dry-run. Current integration uses existing Terraform, Helmfile, Helm, and Kubernetes hooks. Do not claim enforcement for Packer, Ansible, containers, emulators, or custom components yet.- GitHub Actions context:
ci.provider == 'github-actions',ci.schema == 'github-actions/v1'. Metadata retains allowlisted environment variable names underci.metadata.data; native event fields remain underci.event.data. No tokens or arbitrary environment variables are copied. Events are triggering evidence, not current reviews. Missing required data blocks. atmos.affected: deny rules run in shared affected analysis before output filtering/scheduling. Inputs include files, instances, component/stack groups, and structured before/after fields. Collection requires clean worktrees; static inventories use the active, protected discovery configuration on both revisions. This is not independent historical discovery or a transitive execution graph. Missing imports and unsupported inventory types block. Inspect before/after explicitly; affected rules do not accept single-instancematchor dispatch lifecycle hooks.git.change, function/source, and approval input types have core contracts or design examples, not complete CLI collectors/enforcement. Affected is explicit; ordinary lifecycle and saved-plan rules do not depend on--affected.
Author and test
- Start with
policy-library/<name>/: each entry has aREADME.md, onepolicy.yaml, andtests/cases.json. Browse/policies/libraryin the matching-version documentation.examples/policies/{terraform,github,lifecycle}are demonstration bundles, not the library. Copy only selected manifests into a protected, flatATMOS_POLICY_DIR; loading is not recursive. - Choose a supported input and effect. A true CEL predicate selects its effect; a false predicate
is not applicable, not denial. Use
action: denyfor a violation predicate, not a safety predicate.action: hooksis supported on operation inputs. - Keep predicates pure. Available roots are
input,params,ci, andrequest. Supply parameters withwith. No network, shell, filesystem, clock, or automation host is exposed. Includemetadata.descriptionwith the document's plain-English purpose. It is optional literal text, separate from the CELruleand denialreason; catalog entries require it. - Treat missing, null, and unknown separately. Read Terraform
after_unknownalongsideafter. Deletion includes replacement action lists. Decide whether a removal is forbidden or allowed remediation. Do not print plan JSON or sensitive values to explain a violation. - Add colocated
tests/cases.jsonfixtures for each catalog entry: matching and non-matching inputs, threshold boundaries, null/missing/unknown data, relevant input kinds, and exact hook requirements.TestPolicyCatalogloads the actual manifests and checks combined identities. Demonstration bundles retain table-driven cases inpkg/policy/library_test.go. - Run targeted tests, not production applies or callbacks:
go test ./pkg/policy -run TestPolicyCatalog -vgo test ./pkg/policy -run TestSampleLibrary -vgo test ./pkg/hooks -run 'TestPolicyHooksLifecycle|TestPolicyHookFailuresBlock'go test ./pkg/ci/... -run TestPolicySnapshot
Tests prove only the layers they execute. A supplied-data predicate test does not prove CI collection, approvals, an artifact binding, or component command admission.
Policy-selected hooks
Place hook definitions in governing spec.hooks, not workspace hooks:. Reference them from
an operation rule's hooks list with ref, event, required, and require_success. Local
references resolve to metadata.name/ref. The predicate must select the same lifecycle event
as the hook requirement. Selection happens now, not as scheduling for a later event.
Use existing hook kinds and steps. Keep conditions in the policy: this slice rejects hook-level
events/when and nested skip/background controls, and does not render hook templates or YAML
functions. Use protected executable dependencies; optional spec.tools pins cannot be overridden
by component dependencies. Tool configs and runtime credentials still need protection.
Set both booleans for a mandatory successful check. required prevents --skip-hooks bypass;
require_success forces failure propagation regardless of a hook's weaker on_failure setting.
Dry-run reports selections without executing. A denial is never canceled by a successful hook.
After-apply failures do not roll back completed infrastructure. Avoid callbacks without an
idempotency strategy; there is no durable replay ledger or exactly-once guarantee.
CI and trust boundaries
Reading supplied Actions events requires no API permission. Repository checkout needs
contents: read. Native CI status reporting separately needs statuses: write. Do not recommend
write-all, a PAT, or a GitHub App just to enable OSS policy input. PR reads, current reviews,
check/run facts, review requests, and approval verification are not implemented by this collector.
Live organization-team membership is not a GITHUB_TOKEN workflow permission.
Protect the workflow, governing revision/directory, environment, CODEOWNERS, and executables.
The comparison base is not necessarily the governing revision. Never claim an editable checkout
is tamper-proof. Do not suggest privileged execution of fork code under pull_request_target.
Keep local/current-job evaluation in OSS. Cross-component/job outcome aggregation, durable
coordination, organization identity enrichment, and webhook orchestration belong to Atmos Pro.
Keep unimplemented designs in docs/prd/policies.md, not website docs or runnable catalog entries.
The library governs Atmos operations and consumed artifacts; do not duplicate Kubernetes admission
rules. Required external validators retain ownership of their resource-security rules.