Safety and guards
Environments, graded confirmations, read-only connections, and manual transactions.
RED is built for inspecting live databases, so its defaults lean toward not surprising you. Three mechanisms do the work: a connection's posture, a statement's grade, and an explicit transaction when you want one.
Read-only connections
A connection marked read-only opens read-only at the driver and refuses every write path up front - the editor, in-grid editing, the Redis and MongoDB write affordances, and the AI assistant alike. It is not a UI-level hint.
Environments
Mark a connection Local, Dev, Staging or Prod and the write guards follow the marker:
| Environment | Behaviour |
|---|---|
| Local | Asks about nothing short of destroying an object, so a scratch database stays out of your way |
| Dev / Staging | The standard graded confirmations below |
| Prod | Confirms from the first risky statement, makes every confirmation typed rather than clicked, and offers no "Don't ask again" at all |
An unmarked connection behaves exactly as it did before markers existed. The marker shows as a coloured badge on the connection card and beside the connection name, and the connection form guesses one from the host and name.
Graded confirmations
Statements are graded before they run, and the confirmation matches how dangerous they actually are:
- Runs uninterrupted - a filtered
UPDATE … WHERE id = 42, anALTER TABLE … ADD COLUMN. - Stops and says what it noticed - an
UPDATEorDELETEwith noWHERE("No WHERE clause: this removes every row in orders"), a privilege change, aMERGE,GRANT/REVOKE,CREATE USER, a stored-procedure call, anALTER TABLE … DROP COLUMN, or aWITHquery whose CTE writes. - Asks you to type the object's name before the run button enables - a
DROP TABLE, aTRUNCATE.
The confirmation also asks the database how much it will touch: "This
affects 8,412 rows", or "orders holds 8,412 rows" before a DROP TABLE. The
count runs over the same table and WHERE clause the statement uses, so a
predicate that matches more than you expected shows up before the run rather
than after. It never holds up the dialog - it fills in a moment later, gives up
after two seconds, and says plainly when it can't tell.
"Don't ask again" silences only the kind of statement in front of you, so
hiding the routine prompts never hides the one before a DROP DATABASE. On a
Prod connection it isn't offered at all.
The threshold is query.confirm_from in settings.toml, taking write,
risky, critical, or never.
Across the shells
One setting governs all three shells. Deleting a Redis key or a MongoDB document asks first, like a destructive SQL statement, and every confirm dialog carries the "Don't ask again" checkbox. MongoDB's drop-collection confirm stays server-gated and always asks.
A Redis delete additionally drops into a session recycle bin, so the toast that follows carries an Undo.
Staged edits
In-grid edits never reach the database as you type. They are staged: make a
batch, review the change set below the grid, then submit them together or revert
(⌥⌘ZCtrl+Alt+Z). Submitting runs through the same confirmation guards a
hand-written statement does, and the confirmation shows the real statements and
their matched row counts.
Manual transactions
"Transaction: begin" pins the connection and holds every write, with the pending count in the status bar, until you commit or roll back. PostgreSQL, MySQL and SQLite only. Reads still come from the pool, so they show committed data.
Secrets
Connection passwords, SSH secrets, proxy passwords, and AI API keys all live in
your OS keychain (Keychain / Credential Manager / Secret Service). RED's own
config and history files are written 0600. A Debug-printed connection
redacts its password by construction, so a stray log line cannot spill one.
Remove all RED data (Settings → Behavior, the palette, or
red reset) deletes RED's config and cached-data
directories and every keychain secret in one step. It shows what will be
removed, is irreversible, and leaves the binary untouched.