Skip to content

Confirmation rules

Two safety tiers, both locked April 2026 and applied consistently across every dialect.

When the active connection is tagged prod, every commit of pending edits requires explicit typed-name confirmation, no matter how small the change.

  • ⌘S opens 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
  • Esc cancels — edits remain pending
  • Non-prod connections: ⌘S commits 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.

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.

  • DROP TABLE / DATABASE / SCHEMA / VIEW / INDEX / TRIGGER / FUNCTION / PROCEDURE
  • TRUNCATE TABLE
  • DELETE FROM <table> without WHERE
  • UPDATE <table> SET … without WHERE
  • ALTER TABLE … DROP COLUMN
  • Mongo dropDatabase(), collection.drop(), deleteMany({}) with empty/no filter
  • Redis FLUSHDB, FLUSHALL, DEL on > 10 keys

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.

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.

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.

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.