Skip to content

feat: per-database read_only mode with runtime tamper protection#548

Merged
dosco merged 5 commits intodosco:masterfrom
amitdeshmukh:feat/support-database-read_only
Feb 21, 2026
Merged

feat: per-database read_only mode with runtime tamper protection#548
dosco merged 5 commits intodosco:masterfrom
amitdeshmukh:feat/support-database-read_only

Conversation

@amitdeshmukh
Copy link
Contributor

Summary

  • Add read_only: true option on DatabaseConfig to block all mutations (insert, update, delete) and DDL against a
    database
  • Propagate database-level read_only to role-table entries via NormalizeDatabases(), leveraging existing block
    enforcement in the query compiler
  • Snapshot read_only flags at startup so MCP tools (update_current_config, apply_schema_changes) cannot disable them at runtime
  • Add database parameter to DDL tools for explicit multi-db targeting

Test plan

  • Unit tests for config tamper protection (serv/mcp_test.go)
  • Unit tests for DDL blocking on read-only databases (serv/mcp_ddl_test.go)
  • E2E test sending GraphQL mutations through the full engine against a read-only database (tests/readonly_test.go)
  • Verified against PostgreSQL via testcontainers

amitdeshmukh and others added 5 commits February 19, 2026 16:02
preview_schema_changes and apply_schema_changes used anyDB() and conf.DB,
which hit an arbitrary database when multiple are configured. Add a required
database parameter so DDL operations target the correct connection, type,
and schema. Includes getDBByName helper and tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add a `read_only` field to DatabaseConfig that blocks all mutations and
DDL against a database. The value is snapshotted at MCP server startup
and cannot be changed to false at runtime via MCP tools, preventing
LLMs from accidentally modifying production/reporting databases.

Enforcement points:
- apply_schema_changes blocked on read-only databases
- update_current_config preserves read_only: true from startup snapshot
- NormalizeDatabases propagates DB-level read_only to role table entries
- Admin API exposes readOnly in database stats

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…se-read_only

# Conflicts:
#	serv/mcp_ddl.go
#	serv/mcp_ddl_test.go
@dosco dosco merged commit df70eb9 into dosco:master Feb 21, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants