Skip to content
This repository was archived by the owner on Jun 7, 2026. It is now read-only.
This repository was archived by the owner on Jun 7, 2026. It is now read-only.

daemon: enforce read-only at the engine, not via a keyword guard #30

Description

@timkicker

The query socket (src/daemon.rs) is meant to be read-only, but it enforces that with a lexical guard (is_write_query) that rejects a statement carrying a write keyword. A blocklist is the wrong layer. A same-uid client can reach mutating Kuzu statements that carry none of the listed keywords, for example ALTER, COPY FROM, IMPORT DATABASE, ATTACH DATABASE, CREATE SEQUENCE, CREATE TYPE, LOAD EXTENSION, and non-read-only call functions. That permits schema drift, data import or corruption, database attach, or native extension loading in the daemon process.

The robust fix is engine-level read-only. lbug exposes SystemConfig::read_only(true) at database open, so the query path should execute against a read-only database handle. Two things to resolve first:

  • lbug has no per-statement read-only classification (only prepared_statement_error_message), and there is no read-only mode on an individual connection. So this means a separate read-only Database handle for the query path, not a per-query check.
  • The daemon currently uses one read-write handle for both promotion writes and socket reads. Opening a second read-only handle on the same database files alongside the writer needs Kuzu's read-write plus read-only concurrency behaviour confirmed (file locking) before relying on it.

This affects the legacy text query mode and the typed-row mode equally. It is pre-existing and was not introduced by the typed-row work, which only tightened the lexical guard to catch a write hidden after a MATCH. The same-uid residual is consistent with the other same-uid items in the security model (closed properly only by installd inode-keyed identity), but a truly read-only socket is the right enforcement regardless of that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions