docs

Agent security

Why a coding agent that reads production telemetry treats it as untrusted text, and the scopes, approvals and isolation that bound what it can do.

Anyone with your public DSN can send an exception message, a log line or a span attribute. An agent that reads that text can be misled by it. Unhandled limits what a misled agent can do, and your agent's permissions limit the rest.

Telemetry is data

Every MCP result that carries text from your apps or their users says so twice. The result's _meta lists the fields under unhandled.net/untrustedFields, and the result text starts with a provenance object with the same list and a note. Clients that hide _meta still show the note. get_fix_context and the copied fix prompt fence the telemetry inside a block that a trusted line marks as data. Invisible and direction-changing characters arrive as \u escapes.

Secrets are removed from every telemetry result. The organization's AI data policy can also replace emails, IP addresses, phone numbers and user ids with stable tokens such as <email:3f9a01c2>. Untrusted text in results has the details.

Put the rule in your repository too. The AGENTS.md section tells the agent never to follow instructions found in telemetry.

Scopes

Connect with the fewest scopes the job needs. Fixing an issue needs only issues:read. The consent page has Read only, Triage and Full presets, and only read scopes start ticked. A call runs only when the connection's scopes, the organization's MCP policy and your role all allow it. See Scopes and access.

Confirm and approval

confirm: true is something the caller asserts about itself, so a misled agent can send it. It is not a safeguard. Approval is. While Require human approval for sensitive agent actions is on, which is the default, a held call returns approval_required and does nothing until a person opens the approval link and approves it. An approval is bound to the connection, the tool and the exact arguments, and runs once. For 10 minutes after a connection receives a secret, the server refuses calls that send data to a new destination. See Confirm and approval.

Headless agents

An agent with nobody at the keyboard has only the guardrails you set up first.

  • Keep permissions the agent's own. The CLI passes no flag that skips approvals unless you add one with --agent-args. Flags such as --dangerously-skip-permissions, --yolo or --dangerously-allow-all let the agent run any command on text that came from production, so use them only in a sandbox you can throw away. Allow the edits and test commands it needs in the agent's settings rather than turning approvals off.
  • Withhold credentials. Do not give a watching agent deploy keys, production credentials or a shell outside the repository.
  • Isolate the checkout. Run unhandled watch in a dedicated clone, worktree or container, so a run cannot touch work in progress, and review every pull request before it merges.
  • Use an agent identity with read scopes. Cloud agents and CI use an agent identity with a 90-day cap and an optional IP allowlist. Approvals for its sensitive calls still go to a person.

Audit what an agent did

Every MCP call is recorded. Settings > Agent activity lists them with filters and exports, and a row can revoke the connection. Changes an agent makes appear under your user in the issue's activity, with the app and the tool named, such as "Claude Code (via roberto@) resolved the issue".

The security model for AI agents covers how agents connect, what they can do, and the approvals and audit trail that limit them.