Implement guardrails and accountability
An autonomy level is a decision; a guardrail is what makes it hold
A team writes "workflow-file changes must not merge without code owner approval" into .github/copilot-instructions.md, and a pull request from Copilot cloud agent (the Copilot agent that runs on GitHub Actions and opens pull requests) that changes a workflow file is merged without that approval anyway. The instruction was not enforced: an instructions file is read by a model that is trying to cooperate and binds no other contributor, while a CODEOWNERS file (which names the owners of paths) plus a ruleset that requires Code Owner review is evaluated by GitHub and gates merging on owner approval; it still does not stop the agent editing those files or proposing the change. This domain covers how much an agent may do on its own and what holds it to that (the Implement tool use and environment interaction domain covers choosing and connecting an agent's tools, and how an agent recovers from failures), and it rests on two steps. First set the autonomy level, meaning how much the agent may do before a person looks, from what the task risks and requires rather than from the size of the change alone. Then make that level hold with a guardrail, a control evaluated outside the agent. Three guardrail jobs (this guide's own names, not GitHub feature names) make the level hold: limit what the agent can reach, block a forbidden action, or gate an action on a person's decision. A fourth job, record, such as session logs, explains afterwards what happened (the accountability in this domain's title), but it prevents nothing. The classic trap is an option that only describes a limit to the agent and is presented as if it enforced one.
The domain unfolds in two steps: set the autonomy level, then make it hold
Define autonomy levels for agent tasks covers the first step: classify work by what it risks and requires (production-critical, security and authentication work, and ambiguous requests, among others, pull the level down even when the change is small), then match how wide a grant is and how long it persists to the trust you mean, from Copilot CLI (GitHub's terminal agent) plan mode (in which the agent plans without editing project files, yet may still allow effects such as external tool calls) and a session-scoped grant up to organizational policy when no developer may be able to widen the level. Implement guardrails and human-in-the-loop workflows covers the second step, one guardrail job at a time, through controls such as these: it limits reach with a custom agent's tools list, Agents secrets (the store cloud agent reads, unlike Actions secrets) and the cloud agent firewall; it blocks with rulesets (though a ruleset requiring review is a gate), --deny-tool rules and preToolUse hooks (hooks that run before a tool call and can deny it); it gates with an independent required review or a protected GitHub Actions environment (a deployment target whose required reviewers must approve before a job that targets it starts); and it reads the record left by Verified agent commits and the session logs they link to. The table maps each step to its subtopic, and the decision tree routes a single requirement to the control it needs.
When two controls both work, pick the narrow one that holds without the agent's cooperation
The default this domain rewards is the narrowest control that meets the stated requirement and is evaluated outside the agent: one high-risk tool reserved for human approval rather than agent mode switched off, a session-scoped grant rather than global auto-approval, and a required review rather than a line in an instructions file, which only describes a limit. Before trusting the choice, check two facts about it. The first is its documented scope, because a wrong answer stretches a real control one step too far: plan mode can still allow, among other effects, calls to connected external or MCP (Model Context Protocol) tools, and the cloud agent firewall applies only to processes started through the agent's Bash tool, not to MCP servers or configured setup steps. The second is its failure direction: in Copilot CLI and cloud agent, a command preToolUse hook (a hook that runs a local command) that exits non-zero denies the call, but a hook that times out lets processing continue as if it had not run, and cloud agent treats a hook's ask decision (asking a person to approve the call) as deny because no one is there to answer.
Two steps: set the autonomy level, then make it hold with a guardrail
| Step | Decides | Key controls | Tempting wrong answer | Drill into |
|---|---|---|---|---|
| Set the autonomy level | How much the agent may do before a person looks, how widely and how persistently a grant applies, and how long the agent may keep working, judged by what the task risks and requires | Copilot CLI plan mode; once, session or persisted approvals; VS Code session permission levels; organizational policy | Asking developers to pick a safer mode when the requirement is that nobody can choose a broader one | Define autonomy levels for agent tasks |
| Make it hold with a guardrail | Which job the control must do: limit, block, gate, or leave a record | Limit: custom agent `tools` list, Agents secrets, cloud agent firewall. Block: rulesets, `--deny-tool`, `preToolUse` deny. Gate: required review, protected environment. Record: Verified agent commits, session logs | An instructions file, a hook that runs after the tool, or a Verified agent commit offered as if it enforced the limit | Implement guardrails and human-in-the-loop workflows |