Beetl Docs
Core concepts

The agent trust boundary

What the assistant reads, what it writes, and where the exceptions are.

The claim, stated the short way:

Beetl reads your systems, never writes back to them, and publishes only where you explicitly told it to.

That is accurate, and it is also the version a technical buyer will push on. Calling the product flatly "read-only" is an overclaim, and anyone who reads the tool list will catch it. So here is the precise version, including every exception.

The useful split is two planes. The analysis plane cannot mutate anything, anywhere. The platform plane mutates Beetl's own artifacts, behind gates described below. Nothing in either plane writes to a system you connected.

Could it mutate production data?

No, and not because it was told not to.

The query engine is constructed with DML disabled. No model-generated SQL can write anywhere, on any surface, regardless of what the model attempts or what a prompt injection asks it to do. That is a property of how the engine is built, not a filter wrapped around it, so it does not depend on a prompt staying intact.

The same holds at the edge. beetl-connector, the binary you run inside your own network, extracts from local systems and pushes batches out. It has no write path back into them.

What the assistant does write

Four things, each with a different gate.

Live page state. Since August 2026 the assistant edits the page you are looking at. Four surfaces publish their state to it: Query, Graph, Pipeline Editor and Automation Editor. Two generic tools, get_page_state and patch_page_state, read that state and apply JSON Patch operations to it.

This is the widest of the four, so be exact about it. There is no confirmation step. What contains it instead is four layers of validation, and reversibility: read-only path prefixes are rejected, a size cap applies, the client's own JSON Schema must accept the result, and for the pipeline surface the server validates against its own pipeline definition schema. Every field the assistant touched flashes until your next click, and a per-turn revert undoes the whole set. Nothing is persisted by the assistant. Your Save is the trust boundary.

Pipeline drafts. build_pipeline creates a new working set. update_pipeline edits an explicit one. Both write server-side, both stay in the Working version, and neither can execute. An ambiguous request pauses the turn and asks rather than guessing. There is no undo for these from chat.

Deployment. deploy_pipeline promotes a saved working draft to Deployed. It is the one production-scoped tool wired end to end through confirmation: in chat the turn pauses and renders an Allow or Deny card, and the server validates the pending request for staleness and double-settlement before resuming the exact paused call. Over MCP it is gated by the calling key's scope instead, so a read key cannot reach it.

Pipeline runs, and their destinations. run_pipeline triggers a deployed pipeline. A pipeline with a destination writes a dataset when it runs. This is real, intended writing, and it is the part a blanket "read-only" claim hides. What makes it a boundary rather than a hole is that the destination is a Beetl dataset a human configured, and that the pipeline being run is the deployed version, not a draft.

Everything on that list writes to Beetl. None of it writes to a connected source system.

Could untrusted content take over the conversation?

Data you ingest is data, and Beetl treats it that way structurally. Every chat-visible tool result is wrapped in an untrusted-data envelope with nested tags neutralized, and the instruction to treat the contents as data rather than instructions is appended in code on every surface, not left to whichever prompt file happened to load.

Secrets sit behind a secrets backend and never enter the model's context. API keys are scoped and enforced at a single dispatch choke point, so scope cannot be forgotten in one handler. A caller below a tool's required scope gets an error naming both, and a hidden or unknown tool returns an identical error, so the registry cannot be enumerated by probing.

What the agent cannot reach

The tool registry has 17 entries. MCP exposes 13 of them, and the four missing ones are excluded structurally rather than by configuration: the two page-state tools need an attached page surface that an MCP client does not have, and the two automation run-history tools need run context.

The assistant's knowledge base is read-only. list_files, read_file and search_files read platform reference documents and generated per-pipeline docs. There is no write tool. The agent cannot record what it learned, which is a real limitation and also a containment property: nothing it read in one session can shape another.

Automations are observe-only by construction. An automation run executes under a read ceiling, proposes no actions, and has no approval flow to abuse. It investigates and reports.

Can a conclusion be verified afterwards?

Yes, and this is the part worth showing a security reviewer.

Every turn is a durable, append-only event log. The Timeline tab in chat renders it: user messages, assistant outputs, each tool call with its arguments summarized by name and value kind, timings, token counts, and per-tool durations. Automation runs go further, recording the stated purpose of every query alongside the SQL actually executed and a link to the durable result.

Query results themselves carry a lineage profile. Click any cell and you get the column's role, the SQL expression behind it, and the relations it drew from, with a drill-down to the contributing rows wherever a deterministic path exists.

Known sharp edges

Stated plainly, because they are the ones a reviewer will find.

  • patch_page_state is an unconfirmed write path. It relies on schema validation, the visual flash, and the revert affordance rather than an approval step. That is a defensible trade for draft state you still have to Save, and it is a wider agent-write surface than the rest of this page describes.
  • deploy_pipeline is the only tool wired through end-to-end confirmation. Other tools are gated by scope, not by asking you.
  • Chat sessions run at full write scope. The restriction that separates surfaces is chat versus automation, so there is no way to open a deliberately restricted chat session today.
  • Working-set mutations from build_pipeline and update_pipeline cannot be undone from chat.
  • API keys have no expiry, no rotation, no per-key resource allow-list, and no rate limiting. They authenticate MCP only. See API keys.

The version for a security review

The analysis plane cannot mutate anything: DML is disabled at engine construction. The platform plane mutates Beetl's own artifacts, which means pipeline drafts, page drafts, and datasets written by deployed pipelines a human configured. Source systems are read-only in both directions of the claim: extraction is one-way, and nothing in the product opens a write path back to them. Every mutation is attributable to a user or a scoped key and recorded in a durable event log.

Longer form for a reviewer is in Security and compliance.

On this page