Skip to content

Sudo Passwords

To install services, harden a box, or run maintenance, managed sometimes needs to run commands as root. It does that with sudo. On most servers this needs no password — but some servers you bring yourself require one, so managed lets you store a sudo password for them.

Do you even need one?

Usually not. Every server managed provisions is set up to need no sudo password: it creates a deploy user that logs in with your SSH key, gives it passwordless sudo (NOPASSWD), and locks the account's password entirely. There is no password to type and none is stored — not a shared one, not a random per-box one. This is the standard, safe way to run automation, and it's why the sudo-password feature is optional.

You only need a sudo password for a bring-your-own server (one you imported with managed server add / import) whose login user isn't root and asks for a password when it runs sudo. If that box already has passwordless sudo, or you log in as root, you can ignore this page.

The resolution order

For any given server, managed picks the sudo password to use in this order — most specific first — and stops at the first one that's set:

OrderSourceSet it with
1The server's own sudo passwordmanaged server sudo-password <name>, the dashboard's server page, or servers.<name>.sudo_password in managed.yaml
2The MANAGED_SUDO_PASSWORD environment variableExported in your shell / CI for a single run
3The project-wide defaultmanaged sudo-password, or Dashboard → Project → Settings → Security
4Passwordless sudo (sudo -n)Nothing — this is the fallback when none of the above is set

So a per-server password always wins; a one-off MANAGED_SUDO_PASSWORD beats the stored project default; and if nothing is set, managed just tries passwordless sudo. If a box genuinely needs a password and none is found, the step fails with a clear message (see Troubleshooting) rather than hanging.

Setting a password on one server

Pick whichever fits how you work:

bash
# Prompted, hidden input:
managed server sudo-password web-1

# From the environment (keeps it out of your shell history):
MANAGED_SUDO_PASSWORD= managed server sudo-password web-1

# Set it, then connect and check that sudo actually works:
managed server sudo-password web-1 --verify

# The box has passwordless sudo after all — remove the stored password:
managed server sudo-password web-1 --clear

In the dashboard, open the server (Servers → the server) and use the Sudo password panel to set, replace, or clear it.

You can also set it while importing:

bash
managed server add [email protected] --name web-1 --sudo-password
managed server import --provider do_prod --all --sudo-password

(Prefer the MANAGED_SUDO_PASSWORD environment variable to --sudo-password so the password never lands in your shell history or the process list.)

The project-wide default

If a group of bring-your-own boxes shares one sudo password, set it once as the project default instead of on each server:

bash
managed sudo-password              # prompted
managed sudo-password --clear      # remove it

Or in the dashboard: Project → Settings → Security → Default sudo password.

A per-server password and MANAGED_SUDO_PASSWORD both still take precedence over it (see the resolution order).

Declaring it in managed.yaml

For a GitOps / checked-in workflow, reference an environment variable per server — never a literal password in the file:

yaml
servers:
  web-1:
    ip: 203.0.113.7
    ssh_user: deploy
    sudo_password: ${WEB1_SUDO_PW}   # resolved from your environment at load

The ${WEB1_SUDO_PW} is expanded when the config is read, and the resolved value is stored sealed in state — the same as if you'd set it any other way. An unset variable simply resolves to empty (no password), so it never overwrites one set from the dashboard.

How it's stored and sent

  • Encrypted at rest. Sudo passwords are sealed (AES-256-GCM) in the project state, exactly like database credentials and WireGuard keys. They are never written to managed.yaml and never appear in the dashboard's database in cleartext. The dashboard only ever knows whether a password is set, never its value.
  • Never on the command line. When managed runs sudo, the password travels over the SSH session's standard input (sudo -S), or a locked-down askpass helper for streamed commands — never as a command-line argument, so it can't be seen in the box's process list.
  • Passwordless when it can be. With no password to use, managed runs sudo -n (non-interactive). It never falls back to prompting on the remote box and never sets a password on a box for you.

Troubleshooting

"this server needs a sudo password, but none is set for it" — the box's login user asked for a password and managed had none. Set one for the server (or the project default), or configure passwordless sudo on the box for that user.

"sudo rejected the sudo password for this server" — the stored password is wrong (or was rotated on the box). Set the correct one:

bash
managed server sudo-password web-1 --verify

The --verify flag connects and runs a harmless privileged command so you get an immediate ✓ / ✗ instead of finding out during your next deploy.

See also