Block agent deployments to production
Deny production apply, deploy, shell, and exec commands launched by Claude Code or Codex.
Production apply, deploy, shell, and exec are blocked from coding-agent sessions. Use a reviewed deployment workflow.
apiVersion: atmos/v1
kind: Policy
metadata:
name: component-deny-agent-production-deploy
description: Deny production apply, deploy, shell, and exec commands launched by Claude Code or Codex.
spec:
policies:
guard:
on: component.command
action: deny
reason: Production apply, deploy, shell, and exec are blocked from coding-agent sessions. Use a reviewed deployment workflow.
rule: |
((has(env.CLAUDECODE) && env.CLAUDECODE == '1') ||
(has(env.CODEX_THREAD_ID) && env.CODEX_THREAD_ID != '')) &&
input.command in ['apply', 'deploy', 'shell', 'exec'] &&
input.stack.matches('(?i)(^|[-_/])(prod|production)([-_/]|$)')
1 Configure
env is collected from the invoking process before configuration loading:
| Environment marker | Value that detects the agent |
|---|---|
CLAUDECODE | Exactly 1 |
CODEX_THREAD_ID | Any nonempty value |
The shared context exposes environment values to every engine; do not include them in diagnostics.
Claude Code also sets CLAUDECODE=1 in IDE-integrated terminals,
so this policy denies human-run production applies, deployments, shells, and exec commands from those terminals too.
For a reviewed manual deployment or production shell, use a terminal without the marker.
Codex sets CODEX_THREAD_ID in its shell environment.
The presence of a CLI executable, an API key, or a configured home directory does not identify an agent invocation.
The rule treats prod or production as a case-insensitive name segment separated by -, _, or /.
Examples: prod, acme-ue2-prod, production/us. product-dev does not match.
Adapt the stack naming condition to your organization, or use literal inherited component labels in a match selector.
The rule covers apply, deploy, shell, and exec on component types that use shared stack admission,
and on atmos secret shell and atmos secret exec, which are admitted as shell and exec.
shell is included because a component shell starts with the production identity already
authenticated, so an agent could run terraform apply inside it without passing through Atmos admission again.
secret shell and secret exec put production secret values in the environment of the shell or command they start.
To target only some of these commands, match input.command_path, such as ['secret', 'shell'].
Production plans and diffs, non-production applies, and invocations without either marker do not match.
It deliberately also denies apply --dry-run from a recognized agent on a production stack.
These environment markers are an accidental-action guardrail, not authenticated caller identity: a caller can remove them before launching Atmos, and a tool that does not forward them will not be detected. Protect governing policy files and enforce cloud authorization independently. Direct Terraform/cloud CLI execution is outside Atmos admission.
2 Save
Save the CEL policy as policy.d/component-deny-agent-production-deploy.yaml. Install only one implementation of each policy.
Atmos discovers policy.d/ at the project root selected by atmos.yaml discovery. Set ATMOS_POLICY_DIR to use another directory.
3 Run
atmos terraform apply app -s acme-ue2-prod
Review required tools and callback settings before running. In CI, load policies from a protected, pinned revision. See enforcement configuration.