Read-only enforcement
How Datatape ensures all SQL executed through MCP tools is read-only, preventing data modification by AI agents.
Read-only enforcement
Datatape enforces that every SQL query executed through an MCP tool is read-only. This is a platform-level guarantee — AI agents cannot bypass it, regardless of how they craft their requests.
How it works
Every SQL template is validated using SQLGlot, a SQL parser that analyzes the query's abstract syntax tree (AST) before execution.
User creates tool → SQL template saved
│
Agent calls tool → Parameters injected → SQL parsed by SQLGlot
│
┌────────┴────────┐
│ │
Read-only? Mutating?
│ │
Execute Reject with
query errorBlocked statements
The following SQL statement types are rejected:
| Statement | Example |
|---|---|
INSERT | INSERT INTO users (name) VALUES ('test') |
UPDATE | UPDATE users SET role = 'admin' |
DELETE | DELETE FROM users WHERE id = 1 |
DROP | DROP TABLE users |
ALTER | ALTER TABLE users ADD COLUMN ... |
TRUNCATE | TRUNCATE TABLE users |
CREATE | CREATE TABLE ... |
GRANT / REVOKE | GRANT ALL ON users TO public |
Validation happens at the platform level, before the query reaches your database. It cannot be disabled per tool or per agent.
What's allowed
Only SELECT statements and read-only operations pass validation:
-- All of these are allowed
SELECT * FROM orders WHERE status = 'active';
SELECT COUNT(*) FROM events GROUP BY type;
WITH monthly AS (
SELECT date_trunc('month', created_at) AS month, SUM(amount) AS total
FROM payments GROUP BY 1
) SELECT * FROM monthly;Defense in depth
Read-only enforcement is one layer of a defense-in-depth strategy:
- SQLGlot validation — platform-level query analysis before execution
- Read-only database credentials — connect with a user that only has
SELECTprivileges - Parameterized templates — SQL injection is prevented by Jinja2 template rendering with typed parameters
Always connect Datatape with read-only database credentials. SQLGlot validation is a strong safeguard, but defense in depth means no single layer is your only protection. See the PostgreSQL source guide for instructions on creating a read-only user.
Edge cases
- Database-specific syntax — SQLGlot supports PostgreSQL, MySQL, Snowflake, BigQuery, and other dialects. Dialect-specific read-only functions (e.g.,
pg_sleep) are allowed since they don't modify data. - Stored procedures —
CALLandEXECstatements are blocked, since stored procedures can contain arbitrary mutations. - Dynamic SQL — Since Datatape controls the template and parameter injection, there is no mechanism for an agent to inject arbitrary SQL outside the template.
