Confirmation rules
Two safety tiers, both locked April 2026 and applied consistently across every dialect.
Tier 1 — Modifications on PROD
Section titled “Tier 1 — Modifications on PROD”When the active connection is tagged prod, every commit of
pending edits requires explicit typed-name confirmation, no matter
how small the change.
⌘Sopens a confirmation modal- The modal shows the full list of pending edits (target + old → new)
- You must type the connection name to enable the Commit button
Esccancels — edits remain pending- Non-prod connections:
⌘Scommits without the typed-name step (the pending buffer + multi-edit review already provide friction)
Why typed-name and not just a Yes/No dialog: typing the name forces
you to look at which connection you’re about to modify. A scrolling
muscle-memory click on a generic confirm dialog is cheap; typing
my-prod-database is not.
Tier 2 — Destructives, all environments
Section titled “Tier 2 — Destructives, all environments”Any destructive database operation requires typed-name confirmation regardless of the connection’s tag. Listed below per family — the trigger is the operation itself, not the env.
Database side (always typed-name confirm)
Section titled “Database side (always typed-name confirm)”DROP TABLE/DATABASE/SCHEMA/VIEW/INDEX/TRIGGER/FUNCTION/PROCEDURETRUNCATE TABLEDELETE FROM <table>withoutWHEREUPDATE <table> SET …withoutWHEREALTER TABLE … DROP COLUMN- Mongo
dropDatabase(),collection.drop(),deleteMany({})with empty/no filter - Redis
FLUSHDB,FLUSHALL,DELon > 10 keys
Multi-target modifier
Section titled “Multi-target modifier”When the operation hits many rows, the modal shows the count + asks you to type either the count or a filter description. Example:
About to delete 12,400 rows matching status='deleted'.Type 12400 to confirm.This is a defence-in-depth against the “I meant to delete 5 rows but the WHERE clause was wrong and it’ll delete 12k” failure mode.
Quay-side (simple confirm, not typed)
Section titled “Quay-side (simple confirm, not typed)”Some destructive operations don’t touch the database directly — they only affect Quay’s own state:
- Delete connection profile
- Delete project
- Discard pending edits (with multiple changes)
- Disconnect a session that has pending edits
These get a simple Yes/No confirm dialog. The “delete connection” flow doesn’t ask you to type anything because the user is already in the connection settings — typing a name there is redundant friction.
Where it’s enforced
Section titled “Where it’s enforced”Confirmation rules are enforced at the UI layer (ConfirmDestructive
component, used in 21 sites across the codebase) AND the analyser
layer (analyseRisk function in lib/risk.ts that scans SQL before
execution). The UI catches grid actions; the analyser catches direct
SQL pasted into the editor that didn’t come through a button.
Disabling friction
Section titled “Disabling friction”You can’t. The rules are the product — the whole point of Quay is that production safety isn’t a setting. If you want a tool that defaults to YOLO, that exists elsewhere.
The one knob: tag your connection dev (the default for new
connections is non-prod). That removes Tier 1, but Tier 2 still applies
on destructives. There’s no Tier 0.