sudo vs doas vs su for Privilege Escalation With Examples
Compare sudo, doas and su for privilege escalation: configuration syntax, features, attack surface, logging and which to use on Linux and BSD.

When a user needs to run a command as another user, most often root, the system offers three common tools with different philosophies. sudo does everything, doas does the common thing in a few lines, and su predates both. The behaviours here are for sudo 1.9.15, OpenDoas 6.8 and util-linux su 2.39; a related comparison is in su versus sudo.
sudo: the full-featured default
# /etc/sudoers.d/ops (edit with visudo -f)
%ops ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/journalctl
deploy ALL=(root) NOPASSWD: /usr/local/bin/release.sh
Defaults log_output, timestamp_timeout=5
sudo's policy language supports users, groups, hosts, target users, command lists with arguments, aliases and per-rule options. It keeps a detailed log, can record whole sessions with log_output, supports plugins and LDAP-based rules, and has a syntax checker, visudo. Its power and age bring a large code base, and it has had serious vulnerabilities over the years, such as CVE-2021-3156 ("Baron Samedit") and CVE-2025-32463, which were fixed in updates. See visudo and sudoers and giving a user sudo access.
doas: small by design
# /etc/doas.conf
permit persist :wheel
permit nopass deploy as root cmd /usr/local/bin/release.sh
permit nopass alice as root cmd /usr/bin/systemctl args restart nginx
deny alice as root cmd /bin/sh
doas -C /etc/doas.conf true && echo "syntax ok"
doas systemctl restart nginx
doas -u www-data idEach line says who may do what as whom. The last matching rule wins, and persist remembers authentication for a short time. There are no aliases, no per-host rules and no plugins, and the program is a few thousand lines of code, easy to read in an afternoon. That means fewer features to misconfigure and a much smaller attack surface, and also no session recording, less logging detail and less flexible argument matching. It originates in OpenBSD, and OpenDoas ports it to Linux; Alpine, Void and Gentoo ship it, and Debian and Fedora package it as opendoas.
su: the original
su - # root login shell, asks for root's password
su - deploy -c 'whoami'su switches to another user after asking for that user's password, so it requires sharing root's password with everyone who needs it, gives a full shell, and offers no per-command control or per-user audit. It still has a place when you have the password and want a login shell, and on systems where root has no password, it is unusable without sudo.
Choosing
For a laptop or single-admin server, doas or sudo both work, and doas is pleasantly simple. For a team that needs per-command rules, auditing, session logs or central policy through LDAP, sudo is the practical choice. In both cases write narrow rules, avoid allowing shells and editors, and prefer exact paths, as discussed in least privilege and allowing one command with sudo. Remember that an allowed editor or pager can be used to start a shell.
What changes in the security model
All three tools run a command as another user, and they differ in how much machinery they place between the request and the command. sudo is a large program with a plugin architecture, a rich policy language, an input and output logging facility, and a history of vulnerabilities proportional to its size. It has had serious bugs, and it is also one of the most examined security programs in existence, with a mature process for fixing them. doas, from OpenBSD, is a few hundred lines of core logic with a deliberately small configuration language: rules say who may run what as whom, with options for password persistence and environment handling. The argument for it is that less code means fewer places for a flaw. The argument against is that a small tool lacks features, such as logging command output and fine-grained argument matching, that larger environments want.
su is the oldest: it starts a shell as another user after asking for that user's password, which means everyone who needs root access must know the root password. That is the property that sudo and doas were designed to remove, since a shared password cannot be revoked for one person and does not say who used it. Treat su as a tool for the person who owns the password, not as a delegation mechanism.
Policy examples that show the difference
To let an operations group restart one service, sudo uses a rule with a command list, possibly with arguments pinned. doas uses a rule with cmd and args that must match exactly. Both allow environment control: sudo resets the environment by default and lets you list variables to keep, while doas keeps a small safe set and lets you add more with setenv. For logging, sudo records to syslog and can store full terminal sessions for replay, and doas logs to syslog through the authentication facility. If you need to answer "what did this user type as root", sudo's session logging answers it and doas does not.
Availability and portability
sudo is installed or installable everywhere and is the default on most Linux distributions and macOS. doas ships with OpenBSD, is available as a package on most Linux distributions and BSDs, and Alpine Linux and some minimalist systems favour it, together with the portable version called opendoas. Scripts that call sudo work on the widest range of machines, and a script that assumes doas should state the dependency. Containers frequently have neither, because the process runs as the intended user already, and adding a privilege tool to an image adds attack surface. Use the container runtime's user option instead.
Operational concerns
Whichever tool you choose, treat its configuration as code: store it in version control, validate it before deployment, and test it. sudo ships visudo -c for syntax checking, and doas has doas -C to check a file and report what a given rule would do. Avoid rules that allow shells, editors and interpreters, since they convert a narrow permission into full root. Prefer rules that name specific commands in specific paths owned by root, and make sure the directory and file cannot be written by the user the rule serves. Keep password prompts on for people, and grant passwordless execution only for specific commands run by automation, preferably with a separate account.
A practical decision
For a typical team on mainstream Linux, sudo is the sensible choice because of its features, documentation and universal presence, especially with sudoers drop-ins managed by configuration management. For a small server or workstation run by one person who values a minimal base system, doas is simple and sufficient. For anything where several people need root, an audit trail matters, and the safest answer is to use sudo with logging, keep the root password locked, and never use su as the routine way to become root.
Where this does not apply
If you only need a service to run as another user, use User= in a systemd unit, not a privilege tool. Scripts that rely on sudo options, such as sudo -E or sudo -S, do not port to doas, which has fewer options. Check compatibility before replacing sudo on a system with existing automation. See doas.conf(5) and the sudoers manual.


