SafetyCard Request a review

Wren AI

GenBI / governed text-to-SQL with open context layer (semantic engine) for AI agents

github.com/Canner/WrenAI · 2026-10-03 · 2cc843f

Defense-in-depth score

2.6 / 10

Wren puts an always-on read-only SQL check in front of your databases, and handles secrets carefully, but most other agent-safety controls are missing. Its shipped Claude Code skill pre-approves every `wren` command, so an agent can query anything your database login can read and publish it to Vercel or Cloudflare with `wren genbi deploy` without a human prompt. Queries run directly under your credentials with no row or cost cap on the CLI, nothing is logged, and project files (.env, wren_project.yml) silently choose credentials. Use a read-only database role, turn on strict mode, and remove the blanket skill permission before pointing it at production data.

Safest setup

Wren keeps connection secrets in owner-only profile files, masks them in debug output, sends no telemetry and runs a read-only SQL check on every query. Beyond that the defaults are thin: the shipped skill pre-approves every wren command, queries run under your full database login with no row or time limit on the CLI, and nothing is logged. The safest setup narrows the database identity first, brings back a human prompt, and turns on the strict mode and limits Wren already includes.

SetupHowWhat it gives you
A read-only database rolePoint the connection profile at a database login, or for BigQuery a dedicated service account, that can only read the schemas the task needsThe database itself refuses writes and hides every other table, whatever SQL the agent sends C1
A prompt for each commandRemove the allowed-tools: Bash(wren:*) line from the installed wren skill so your host agent asks before each wren commandA person sees every query, memory write and deploy before it runs C2
The read-only MCP serverConnect agents through wren serve mcp and keep the default --allow-write offAgents get labelled query tools with results capped at 1,000 rows, and no deploy, cloud or memory-write tool C2
Strict modeSet strict_mode to true in ~/.wren/config.jsonQueries reach only the tables modelled in your project, with file and URL readers blocked C3
Row and time limitsPass --limit <n> on CLI queries and set job_timeout_ms in BigQuery profilesEach query returns a bounded result and a runaway warehouse job stops on time C10
A clean project directoryRun Wren from a project whose .env and wren_project.yml you wrote yourselfThe credential profile, secrets and deploy tokens come only from you C6
Its own container or VMRun Wren and the host agent in a container or VM holding only this task's profile and keys, with outbound access limited to your database hostsAn outer boundary around the deploy subprocess and a narrow path for data to leave C4
Database-side query loggingTurn on statement or audit logging in the database for the login Wren usesA record of every query Wren ran, kept outside the agent's workspace C9

Approving with confidence

  • Read each prompt and approve wren commands one at a time.
  • wren genbi deploy publishes the app and the data bundled in it to a public host, so check what it carries before approving.
  • Stored question-to-SQL pairs steer later queries and Git Sync shares them with teammates, so approve memory stores you have read.

Handling data

  • Profiles under ~/.wren are plaintext files readable only by you; ${VAR} placeholders keep the secret itself out of the file.
  • Review the project's knowledge/ files and rules in git like code, since they reach every teammate's agent.

Key gaps (4)

  1. The shipped Claude Code skill pre-approves every `wren` command (`allowed-tools: Bash(wren:*)`), including `wren genbi deploy`, which publishes warehouse data to a public host with no confirmation. C2 · Approval gates
  2. Model-written SQL executes directly on the target database under the operator's credential, and the wrangler deploy subprocess inherits the full environment, with no isolation layer. C4 · Code-execution isolation
  3. Workspace files auto-loaded without a trust decision (CWD/project `.env`, wren_project.yml `profile:`) choose the credential profile and supply secrets and deploy tokens. C6 · Memory, context & configuration integrity
  4. `npx wrangler` (unpinned) and the in-process embedding model run with all of Wren's credentials and environment. C7 · Third-party extensions

Criteria

C1 Identity & least privilege

0.13 / 1.00

Wren runs every query with whatever database credential sits in the active (or project-pinned) connection profile; it does not scope, downscope, or check authorization per request. For BigQuery it requests the broad cloud-platform and Google Drive scopes and falls back to the operator's Application Default Credentials when no key is given. Row- and column-level access rules in the semantic model exist, but in the default non-strict mode a query can name raw database tables outside the model and skip them. A project's own wren_project.yml chooses which stored credential profile is used.

C2 Approval gates

0.50 / 1.00

Wren has no approval step of its own: queries, memory writes, context changes and `wren genbi deploy` (which publishes an app with bundled data to Vercel or Cloudflare) all run without confirmation. Worse, the skill stub it ships for Claude Code pre-approves every `wren` command, so the host agent's own permission prompt is skipped for deploys too. The deploy step only runs a structural and secret-pattern preflight. The MCP server mode is better behaved: every tool carries a read-only or write hint, and the single write tool is only registered when the operator passes --allow-write.

C3 Tool & action scoping

0.50 / 1.00

Every SQL statement, from the CLI, MCP server and SDKs alike, passes through one policy function that parses it and rejects anything that is not a single read-only SELECT-family query, including hidden writes such as data-modifying CTEs or SELECT INTO. That check is real but not a full boundary: it does not cover every path, and the re-check of the final planned SQL is skipped when it cannot be parsed. The stronger strict mode, which limits queries to tables defined in the semantic model and blocks file/URL/remote-database reader functions, is off by default. Beyond SQL, the CLI exposes everything at once (query, deploy, cloud push, memory writes) with no narrower default tool set.

C4 Code-execution isolation

0.00 / 1.00

Wren's core job is to run model-written SQL against live databases, and it does so directly with the operator's database credential; there is no isolation boundary around that execution beyond the database's own permissions. The Cloudflare deploy path also launches the wrangler CLI (or `npx wrangler`) as the same user with the full process environment. DuckDB files are attached read-only, which is a narrow mitigation for that one connector.

C5 Untrusted input blast radius

0.13 / 1.00

Wren returns database rows, project knowledge files, AGENTS.md and business rules to the host agent as plain content with no untrusted marking, and the onboarding and enrichment flows have the agent read raw documents. Nothing in Wren limits what a hijacked agent does next: with the shipped skill pre-approving every wren command, injected content in a database row or document could steer the agent to query sensitive tables and publish them with `wren genbi deploy`, unattended. Plain SQL writes are still blocked by the read-only check.

C6 Memory, context & configuration integrity

0.25 / 1.00

Several files in the project directory steer Wren without any trust decision. Every run auto-loads `.env` from the current directory and the project root into the process environment, supplying values for credential placeholders and deploy tokens, and the project's wren_project.yml picks which stored credential profile is used. Rule files and AGENTS.md from the project are served to the agent as instructions, and stored question-to-SQL pairs are recalled as proven examples. Memory is plain markdown under knowledge/ that is easy to review in git, and the MCP write tool is off by default, but the CLI store command and Git Sync share it with the whole team.

C7 Third-party extensions

0.13 / 1.00

Wren loads little third-party code, but what it does load is unpinned and unconfined. Cloudflare deploys fall back to `npx wrangler` (latest from npm) when wrangler is not installed and pass it the whole environment, and the optional memory extra downloads a Hugging Face embedding model, chosen by an environment variable, at whatever revision is current. Nothing is verified by hash or signature.

C8 Secrets & sensitive-data protection

0.50 / 1.00

Secret handling is one of Wren's better areas. Connection secrets are typed as masked values, profiles and Wren Cloud keys are stored in owner-only files, profiles can hold ${VAR} placeholders that are filled from the environment only at connection time, `profile debug` masks sensitive keys, tokens are never taken as command-line flags, and deploys refuse to ship `.env` files or obvious inlined credentials. There is no telemetry. Gaps: stored secrets are plaintext on disk, the wrangler subprocess receives the whole environment, and database passwords and service-account keys are long-lived.

C9 Audit & traceability

0.13 / 1.00

Wren keeps no record of the queries it runs or the commands it executes: there are no log statements on the query path, and the MCP server does not log tool calls. The only durable trace of an action is the last-deploy entry written into the project's .wren/apps.yml, which sits inside the workspace and is overwritten on the next deploy. Reconstructing what an agent did through Wren depends entirely on the host agent's own transcript.

C10 Limits & kill switch

0.33 / 1.00

Wren does not own the agent loop, so its limits are bounds on its own work. The MCP server caps query results at 1,000 rows by default and 10,000 maximum, deploy subprocesses time out after 10 minutes and Vercel calls after 2 minutes. The README-led CLI path, however, returns unlimited rows when no --limit is given, and there is no default statement timeout or cost cap, so a runaway BigQuery or Snowflake query bills until the warehouse stops it.