Agent environment tagging
Tag an agent as production or preview so its token, its policies, and its env var resolution all agree.
An agent can carry a named environment tag: production, preview, development, or a custom one. The tag is not a label for humans to read. It flows into the agent's JWT as an environment claim, it can gate policies, and it can drive env var resolution automatically.
- environment: the tag itself.
- environment_locked: once set at bootstrap it cannot be changed, so a production agent cannot be quietly relabelled.
- env_auto_resolve: the resolve endpoint fills in the environment from the agent's tag instead of trusting a query parameter.
- per_environment_guardrails: JSON overrides so the same agent definition enforces tighter limits in production.
Requires: an agent you can update, and a vault with env vars from the previous lesson.
- 1
Create an agent tagged for production, locked so the tag cannot drift.
bash1claw agent create prod-deployer \ --environment production \ --environment-locked \ --env-auto-resolve - 2
Confirm the tag landed. The JWT the agent exchanges for will now carry an environment claim.
bash1claw agent get prod-deployer - 3
Scope a policy to environments with the environment_in condition. This policy only grants access when the calling principal is tagged production.
bashcurl -s -X POST https://api.1claw.co/v1/vaults/$VAULT_ID/policies \ -H "Authorization: Bearer $ONECLAW_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "principal_type": "agent", "principal_id": "'$AGENT_ID'", "path_pattern": "deploy/**", "permissions": ["read"], "conditions": { "environment_in": ["production"] } }' - 4
Resolve env vars as the agent. Because env_auto_resolve is on, you omit the environment parameter entirely: the server uses the agent's tag.
bashcurl -s "https://api.1claw.co/v1/vaults/$VAULT_ID/env-vars/resolve" \ -H "Authorization: Bearer $AGENT_TOKEN"
Turn on the org setting env.enforce_agent_environment_scope to block agents from resolving variables outside their tagged environment. Without it, a preview-tagged agent can still ask for production values if a policy allows it.
The payoff is that one mistake stops being possible: a preview agent cannot read production values, because the environment is fixed in its identity rather than supplied per request.
Where this goes wrong in practice. Tagging is easy to adopt and easy to adopt decoratively, which is worse than not adopting it.
- Tags are set without enforcement. Without env.enforce_agent_environment_scope an agent can still resolve variables outside its tag, so the label documents intent without constraining anything.
- The tag is left unlocked on production agents. environment_locked is immutable only if you set it, and an unlocked production tag can be edited to development to widen access.
- env_auto_resolve is left off. With it off the environment comes from a caller-supplied query parameter, which is exactly the value an attacker would choose.
- Per-environment guardrails are configured once and diverge. Overrides per environment are powerful and become the place where production quietly ends up looser than preview.
The whole value of tagging is that the environment comes from identity rather than from a request. Every one of these failures gives that back.
Check your understanding
3 questionsWhy does env_auto_resolve improve safety over passing ?environment=production?
What does environment_locked prevent?
Which org setting stops a preview-tagged agent from resolving production variables?