Frequently asked questions
Short answers, each drawn from the README and the docs. For anything not covered here, see the usage guide.
Which databases does locksql support?
MariaDB 10.1+, MySQL 8.0+, PostgreSQL 13+ and SQLite 3. All engines are pure Go. See supported engines.
Which operating systems? Does it run on Windows?
Linux and macOS, on amd64 and arm64. Native Windows is not supported: the separation relies on Unix accounts, socket peer credentials and terminals. On Windows, run locksql inside WSL2, with the agent inside WSL too for the boundary to hold. Windows: inside WSL2. A Docker image also runs it with nothing but Docker installed, with a weaker boundary against an agent that can run docker: Docker.
How do I set it up?
Install it, then run locksql setup in your project: it wires your agents, creates the locksql console account once you confirm, asks for a database profile (never a password) and prints the command that starts the console in that account’s session. locksql doctor checks the setup from either account, and locksql doctor --fix repairs what it safely can. Setup steps.
Which AI agents does it work with?
Claude Code, Codex, Gemini CLI and Cursor are wired automatically by bare locksql. An agent talks to the console either through the MCP server (locksql mcp, over stdio) or through the locksql CLI from a shell.
Does the agent ever see my database password?
No. The agent never sees a credential and never opens a connection. Credentials are typed at console start (no echo), or read from the OS keychain or HashiCorp Vault, and never appear in argv, environment, files, logs, the socket protocol or error messages. No config file may hold a secret.
Can the agent approve its own queries, or turn approval off?
Approval comes only from the console terminal: no socket method approves, and no socket method loosens the policy. Auto mode switches only from the console's keyboard; no client or config file can turn it on, and it is unavailable on production profiles. The agent’s account must be separate from the console’s.
Why does the console need its own OS account?
An agent in the console’s own account could read or type into its terminal. Separation is mandatory: without it the console refuses to start. sudo locksql install sets it up.
What happens if I don’t answer the approval prompt?
No answer within 5 minutes means denied. Anything other than y (or the profile name on a production profile) denies the query.
Can locksql run writes or DDL?
Tiers are read < write < ddl < admin; the default is read, which is also enforced server side. Above tier read the human’s approval is the gate, and the server does not restrict what an approved write does within the account’s privileges. While mask rules exist, a write whose rows come back (RETURNING, data-modifying CTEs) or that stores a query’s rows (INSERT ... SELECT) is analysed like a read, and the rows it returns are masked by where they come from. Write tiers.
How is personal data protected?
Every output column is traced to its source columns and masked on that source, not on its label; value detectors mask the other cells. Modes are redact (the default), partial and email. Quasi-identifiers (birth date, postal code, gender) are never masked unless you accept them one by one. Masking is best effort: use a database account that cannot read what the agent must never see. More on masking.
Can the agent look up a customer by email without seeing it?
Yes. It writes WHERE email = '${email}' and you type the address in the console, without echo; or it filters on the reference of a redacted cell from an earlier result ('${r1.2.3}'), whose clear value only the console holds. The value never reaches the agent, the audit log or a client error. More on placeholders and references.
Can I see the real values myself?
Yes: press Ctrl-O in the console (or start it with --show-results) and it prints each result in clear, in the console only; the agent still gets the masked cells. If the agent itself must see raw values, start the console with --allow-unmask, or type :unmask in it while it runs (no restart): only then may it ask for an unmasked query, which you still approve one by one. More on these flags.
Does k-anonymity stop all inference?
No. It is a decision aid: a query whose PII filter, group or aggregate covers fewer than k rows warns you on the approval screen, and you decide (in auto mode it runs). Even heeded, it does not stop differencing attacks that combine several approved queries. See the example.
Is the connection to the database encrypted?
Yes, and verified by default: the profile’s tls setting follows libpq’s sslmode (disable, prefer, require, verify-ca, verify-full). A remote host defaults to verify-full; set tls_ca for a private CA, tls_server_name when the certificate does not name host, and tls_cert/tls_key for a client certificate. Below verify-ca an attacker on the path can intercept the connection but is not handed the password: MariaDB/MySQL and PostgreSQL refuse to answer a request for it in clear on an unverified remote connection. locksql doctor checks the server’s certificate chain and expiry with a handshake that sends no secret. For a server behind a bastion, add an ssh table to the profile: the console opens the tunnel itself, checks the bastion’s host key and listens on no local port. Full details.
Why was my query refused, and what should the agent do?
Every refusal carries a stable code (E_NO_LIMIT, E_COST, E_MASKED_FILTER, …), the place in the statement where the check stopped, a hint and a retry rule: rewrite (fix it as the hint says, once), ask_user (only you can lift it) or stop. MCP clients get it as structured content. locksql stats counts your refusals by code; --export anonymises them for an issue. More on refusals · all codes.
Can text stored in the database manipulate my agent?
It can: locksql assumes the agent may be steered by data, so it treats the agent, and anything that can steer it, such as text stored in the database, as not trusted. Every check runs in the console and every statement needs your approval. Rows are framed as untrusted data in every output, and control and bidirectional characters are escaped so data cannot spoof the approval prompt.
Can the agent change the policy?
Agents may add mask rules and request changes. A change that loosens the policy only takes effect after you confirm it in the console. How policy changes work.
What is logged?
Every login, policy change, refusal, decision, run, catalog read, console switch and logout, in a JSONL audit log (mode 0600); the approval is written before the statement runs, its outcome after. Records contain the SQL and metadata, never secrets and never row data.
What is auto mode for?
Fast local iteration: Shift+Tab in the console (or --auto at start) auto-approves statements that the tier and the weight check allow, until Shift+Tab again. It is unavailable on production profiles, never auto-approves an unmasked query, never overrides a REFUSE verdict, shows on the console's status line, and each switch and each auto-approval is audited.
Can several people share one console, or export data?
No: one console per profile and project, one request at a time, no remote or shared consoles, no data export.
Do I need Go to install it?
No. Releases ship static binaries and Linux packages; no Go toolchain is needed. Building from source needs Go 1.26 or later. Install options.
Is locksql stable?
It is a pre-release (v0.8.x): any release may still change the config files, the MCP tools or the CLI. The path to 1.0 lists what must be true first (among others an external review and frozen contracts). The SQL analyzer is fuzzed nightly and a canary suite checks for leaks on real engines: how it is tested.
How do I report a vulnerability?
Privately, through GitHub security advisories, not in a public issue. See SECURITY.md.