Skip to content

What the agent writes

“Can this thing touch my infrastructure?”

No. RootPilot is read-only by construction, with exactly five exceptions — and none of them touch your infrastructure. All five write to systems of record: ticketing, chat and issues, which is where an incident gets written down and communicated.

Tool Where it writes Operation executed
create_incident_ticket Jira tickets.createIssue
update_jira_issue Jira tickets.transitionIssue, tickets.addComment
post_slack_message Slack chat.postMessage
create_slack_channel Slack chat.createChannel
create_github_issue GitHub tickets.createGithubIssue

The list is neither arbitrary nor merely historical. A write gets in when it is a reversible record, in the place your team already works: it asserts that something deserves attention, it does not change what runs in production, and undoing it costs one click and leaves a trail. A GitHub issue passes that test for the same reason a Jira ticket does — plenty of teams use one where others use the other.

A pull request does not pass, and the refusal is deliberate. A PR proposes code, and the value of proposing code lies in someone accepting it — so the failure mode is not “they opened a stray PR”, it is someone merging a diff written on top of a cause the agent inferred. The obvious counter-argument (“a PR goes through human review by construction”) is weak for a reason we measured: across five findings from our own improvement loop, the symptom was right in all five and the proposed mechanism wrong in four. PR review is a gate against bad code, not against a wrong cause.

AWS, GCP, Magalu and Datadog stay out, and now for a stated reason rather than an inherited one: those are infrastructure, not record.

The scope of that guarantee deserves to be stated precisely, because it is the kind of sentence a security team will check: the token the Agent holds cannot write to your sources. That is not the same as saying nothing anywhere writes — if the product opens a pull request for you, that happens by another path, outside the Agent and with another credential. What this page guarantees is what goes through the agent surface and through the Agent running in your infra.

Every write requires explicit confirmation, and the confirmation is checked twice, on different sides of the boundary.

Layer 1 — control plane. The tool takes a confirmed parameter. With confirmed: false (the default) it returns a preview and touches nothing: the channel, the text, the ticket that would be created. Only confirmed: true executes.

Layer 2 — your Agent. The confirmation travels on the wire alongside the call. The Agent running in your infra refuses to execute any operation marked as a write in the catalog if the confirmation is not there, answering op_not_authorized.

Two independent checks, both before any effect:

  • The mcp:write permission — held by owner and admin. A token whose owner is a member does not write; a token with no owner (CLI, or legacy) never writes. This is the one that is fail-closed: an inactive user, a role that does not resolve, a query error — all of them deny the write rather than allow it.
  • The token scope — a read token blocks writes even if its owner holds the owner role. It is a restriction layered on the first, not a second chance: all it can do is block.

The full matrix is in MCP tokens. Neither check ever reaches your infra: the refusal happens in the control plane, before the call exists.

Every confirmed write becomes a record in your organization’s audit trail, carrying the actor_id of the person who owns the token — not “the agent”. That is what makes the autonomy auditable rather than anonymous, and it is visible under Governance.

The record has two phases, and the order is deliberate:

  1. Before the effect, the intent is recorded, and this is fail-closed: if it cannot be recorded, the write does not happen. Policy requires a trail for every confirmed write, and a write without a trail would be worse than a write that failed.
  2. After the effect, the outcome is recorded — success or failure — and that one is best-effort: the effect already happened, and a recording failure here cannot undo it.

What goes into the trail is metadata: the action, the target, the length of the text, whether redaction occurred. Not the raw content.

Canonical PII redaction happens at the Agent’s edge, before any data leaves your infra (see PII redaction). But the text of a Slack message is composed by the model — it did not come from there, so it did not pass through there.

Hence a second, high-confidence pass over the text the tool is about to send: ARNs, email addresses and AWS access keys are masked before it goes out. The preview shows the already redacted text — what you approve is what leaves — and the trail records that redaction happened.

What it deliberately does not mask: IPs, UUIDs and commit hashes. Those are the evidence that makes the message useful during an incident, and masking them would turn the record into something nobody can use.

There are exactly two situations where RootPilot writes without someone asking at that moment, and a customer who discovers that on their own is right to be suspicious. So:

When What it does
Your fleet’s integration health changes (or a new Agent connects) Posts one line to Slack with the new state
An automatic incident investigation concludes Posts the diagnosis to Slack

Both use post_slack_message with confirmation already given, and both share the same hard limit: they only report. Never a corrective action, never a change to a system of yours. Posting the result of a read is the boundary, and it does not move.

That limit is not an intention, and each one holds it differently: the automatic investigation is handed a tool list with none of the five write tools in it — the model driving it has no way to ask for them — and the fleet health notice does not talk to your environment at all: its only outlet is a line of text to a channel.

Both are also off by default and only happen with three things simultaneously true: the feature enabled in the process, a Slack channel configured, and — for fleet health — your organization having opted in. Both become records in the trail, marked with their own origin (not as an agent write), so what a person asked for stays distinguishable from what the system reported.

Four paths, from finest to bluntest:

  1. Issue read tokens. Blocks writes even for owners, and it is the form’s default.
  2. Do not grant mcp:write. With no owner/admin, no token writes.
  3. Do not configure Jira/Slack in the Agent. With no connector serving those operations, the tools do not even appear to the model.
  4. Deny by policy. The tool denylist refuses the operations inside your infra, regardless of what the control plane asks for.

The first two are our controls; the last two run on your side of the boundary. If your risk assessment needs a guarantee that does not depend on us, it is the third or the fourth.