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 invariants
Section titled “The invariants”The enforcement point
Section titled “The enforcement point”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:
- Catalog allowlist. Only operations from the versioned catalog. Anything outside it is refused, regardless of what the control-plane asks for.
- Strict arguments. Validated against the operation’s
inputSchema, in strict mode. - 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 five write operations
Section titled “The five write operations”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.
The human gate, in two layers
Section titled “The human gate, in two layers”Human confirmation is defense in depth, enforced on both sides:
- Control-plane: the
confirmedgate and the preview live in the write tool. - Runner: independently of that, the runner requires
confirmed: trueon the invocation to execute any operation markedwritein the catalog. Without it, it answersop_not_authorized.
The second exists precisely so as not to depend on the first. It is a wire-level gate.
Read-only SQL and aggregation
Section titled “Read-only SQL and aggregation”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
$outor$mergeare rejected. - SQL containing DDL or DML is rejected.
Connector isolation
Section titled “Connector isolation”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 |
Network surface
Section titled “Network surface”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.
What sits outside this repository
Section titled “What sits outside this repository”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.
Auditing it yourself
Section titled “Auditing it yourself”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. |