SQLiteKit: embedder-bound hardened policy for untrusted SQL#1
Open
ronaldmannak wants to merge 37 commits into
Open
SQLiteKit: embedder-bound hardened policy for untrusted SQL#1ronaldmannak wants to merge 37 commits into
ronaldmannak wants to merge 37 commits into
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in, embedder-bound security policy (
SQLitePolicy) to thesqlite3shell port so it can run untrusted, LLM-generated SQL safely under SwiftBash — without breaking sqlite3 parity or thesqlite-vec/ FTS5 feature surface.This is the SwiftPorts half of a comparison with PicoMLX/SwiftSQLite#1: SwiftSQLite is a purpose-built security-first sandboxed engine; SwiftPorts is a fidelity-first sqlite3 clone. This PR brings SwiftSQLite's escape-boundary and DoS hardening over, while leaving the SQL feature surface (vtables, functions, PRAGMA) untouched.
The core idea: policy is not argv
When the command is a SwiftBash builtin, the LLM writes the command line, so any hardening expressed as an opt-in flag is no boundary — the agent just omits or inflates it. So the policy is bound by the trusted embedder (
Sqlite3Builtin(policy:)) or auto-derived fromShell.current.sandbox, and no in-band channel — argv or dot-command — may relax it:-hardenedcan only turn hardening on (no flag turns a bound policy off).limitmay lower/show a limit but not raise it (else.limit attached NundoesATTACHED=0).openre-applies the full policy to the new handle (previously it re-armed only safe mode)Shell-layer controls (all no-ops unless hardened)
$(…)SQLITE_LIMIT_ATTACHED=0,…_LENGTH,…_SQL_LENGTHPRAGMA temp_store=MEMORY(temp confinement)FileAuditSink, JSON Lines,O_NOFOLLOW+ preflight) written outside the DB; destination is embedder-set, never an argv pathFeature preservation (deliberate)
Hardened mode does not port SwiftSQLite's blanket default-deny authorizer (which would reject
CREATE VIRTUAL TABLEand break vec0/FTS5). It touches only limits / temp / caps / audit / canonicalization, so vector and full-text workloads keep working. There's a test asserting hardened output equals permissive for ordinary queries, and one asserting DDL/DML/PRAGMA still work.Honest scope
Several deeper guarantees need the raw
sqlite3*handle, which lives in the externalCocoanetics/SQLiteKitSDK (not in this package). These are specced inDocs/PORTING-FROM-SWIFTSQLITE.mdas follow-up PRs:sqlite3_progress_handler+sqlite3_interrupt) — the shell budget is a script budget, can't interrupt one long querySQLITE_OPEN_NOFOLLOW;DBCONFIG_DEFENSIVE/TRUSTED_SCHEMA=0; compile flagsNotes for review
-hardened(tighten-only). Existing default and-safebehavior are unchanged — the 60-test parity suite should stay green.🤖 Generated with Claude Code
https://claude.ai/code/session_01E8VSWQJZ3ZxVcG6kwiwygJ
Generated by Claude Code