Skip to content

Security model

RootPilot asks for privileged read access to your entire stack. For a tool like that, transparency is a requirement rather than a courtesy, which is why this half is open. What follows is what the code actually guarantees, and where.

The control-plane asks what. The runner decides whether it may. That decision lives in exactly one place, apps/runner/src/enforcement.ts, and it does three things:

  1. Catalog allowlist. Only operations from the versioned catalog. Anything outside it is refused, regardless of what the control-plane asks for.
  2. Strict arguments. Validated against the operation’s inputSchema, in strict mode.
  3. Deadline. Enforced per operation (RUNNER_INVOKE_DEADLINE_MS, default 30 s).

That the decision lives on the runner’s side is the point: a compromised control-plane cannot request an operation the catalog doesn’t have.

The catalog is read-only except for five operations, all ticketing and chat:

Operation Service
tickets.createIssue Jira
tickets.addComment Jira
tickets.transitionIssue Jira
chat.postMessage Slack
chat.createChannel Slack

AWS, Datadog, GitHub, and everything else remain strictly read-only.

Human confirmation is defense in depth, enforced on both sides:

  • Control-plane: the confirmed gate and the preview live in the write tool.
  • Runner: independently of that, the runner requires confirmed: true on the invocation to execute any operation marked write in the catalog. Without it, it answers op_not_authorized.

The second exists precisely so as not to depend on the first. It is a wire-level gate.

Three operations accept free-form queries: MongoDB aggregation, Athena, and CloudTrail Lake. They shipped with write-safety validation in the handler, not on trust:

  • Aggregation pipelines containing $out or $merge are rejected.
  • SQL containing DDL or DML is rejected.

The ConnectorRuntime upholds four guarantees. It’s worth being precise about which are actually enforced and which are merely declared:

Guarantee native sidecar
Per-connector scoped secrets enforced enforced
Egress allowlist declaratory enforced
Contract conformance enforced (in tests) enforced
Declared-field redaction enforced enforced

The runner is an outbound client, full stop. It listens on no port, exposes no health endpoint, and needs nothing opened in your firewall for ingress. The tunnel is reverse WSS with mTLS, and the certificate comes from an enrollment whose identity is proven by the platform.

The diagnostic intelligence is closed and lives in the control-plane. That matters to your risk assessment in two ways:

  • In favor: everything touching your credentials is here, auditable. The executor is the surface that matters for security, and it is open.
  • Against: you cannot audit what the control-plane does with the already-redacted results it receives.

Both are honest to say.

Some useful starting points if you’re reviewing the code:

Question Where to look
What can be executed? packages/protocol, the versioned catalog.
What gets refused, and how? apps/runner/src/enforcement.ts.
What gets redacted? apps/runner/src/redact/ and packages/core-edge/src/policy/.
How is identity proven? apps/runner/src/enroll/attestation.ts.
Which credential does each connector ask for? apps/runner/src/connectors/manifests/real.ts.