Feature Request: DFX safe mode

There are a number of scripts that I use locally during development, and some of them often reinstall canisters in my local environment before seeding them with a specific state.

Within dfx, there certain actions that are destructive and unrecoverable, such as canister upgrades and deletion, or actions that have security implications such as updating the controllers of a canister. A small config change (error) that results in one of these commands hitting production instead of one’s local environment could be catastrophic. Even worse, this could be the fault of a 3rd party tool.

Therefore, I’d like to suggest DFX safe mode, which automatically rejects

  • deleting a canister
  • canister upgrades that result in a breaking candid interface or lost state
  • changes to a canister’s controllers
  • changes to a canister’s log visibility
  • creating or deleting a canister snapshot
  • stopping a canister

DFX safe mode could be toggled on and off with a simple command, and the developer can additional override safe mode for a one-off command by using the --force flag. Additionally, certain commands made in safe/unsafe mode could show up as different colors in the terminal, providing another layer of feedback to the developer.

2 Likes

For breaking candid changes and reinstalling canisters (uninstall too?) we do ask for confirmation by the user unless they add --yes to the command. Is this roughly what you imagine? IMO it would not be a big deal to add this to other commands as well. How do you like the ergonomics of that?

A generally good practice in the same spirit that I recommend occasionally: Have a separate identity for mainnet deployments. I generally keep default as my selected dfx identity. When I do something on mainnet I either use dfx --identity mainnet <rest of the command> or when ising a script I dfx identity use mainnet, run the script, and shortly after run dfx identity use default

Fundamentally, there isn’t really a definite list of destructive operations. Every operation, including every canister call, is potentially destructive; the most dangerous operations are already ones you should be taking extreme care with anyway. Confirmations on operations you thought you intended to do but realize in hindsight are a mistake don’t work; you click through the confirmation dialogue like you click through the command. The most important one here that can just slip under the radar is changing canister controllers, and if you attempt to remove yourself as a controller dfx does first confirm that you meant to do so.

It’s a bit different. A lot of my local and CI setup scripts already have echo "yes" | dfx deploy -m reinstall <my_canister> in them in order to refresh the state for local frontend development and testing.

I’m mostly worried that an identity or configuration might be swapped in, hitting mainnet instead of my local configuration, or even using a different identity without me realizing it.

I guess where I’m coming from is that the easiest way to “hack” a canister isn’t from the outside, but by compromising the toolchain that a developer works with.

There are a number of tools that plug into and work with dfx, so this request is mostly to add some additional opt-in (but highly recommended) protection.

This is great, but what if I’m pulling down a PR from an external contributor to run tests, and the test setup script has been modified to swap in one identity for another, and target production instead of local.

If I have safe mode activated (maybe requires password/key or more than just yes to continue), then this can’t happen as easily.