sudo rules: give a user exactly the rights they need
Write sudoers rules with visudo: full admin for operators, a short list of commands for a deploy account, no-password rules for automation, and how to check what a user may run.
Drafted with AI from official documentation. Scripts were run in a test environment and repository links verified. Awaiting a human check. Did it work for you? Last edited Outdated?
“Add them to the sudo group” gives someone the whole machine. Often the real need is much smaller: restart one service, read one log, run one deployment script. sudo can express exactly that, and a precise rule is also an audit trail: every sudo call is logged with the user, the command and the time.
Where rules live and how to edit them
Rules are in /etc/sudoers and in files under /etc/sudoers.d/. Always edit them with visudo: it locks the file, checks the syntax and refuses to save a broken rule. A syntax error in sudoers can disable sudo for everyone, including you. Keep your own rules in separate files so package updates never touch them:
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo visudo -f /etc/sudoers.d/deploy # opens an editor, validates on save
sudo visudo -c # check every sudoers file
sudo -l # what may I run?
sudo -l -U deploy # what may this user run?
Files in sudoers.d must not contain a dot or end in ~, and should be mode 0440. visudo -f takes care of the mode.
Anatomy of a rule
deploy ALL=(root) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/systemctl status myapp
Read it as: user deploy, on ALL hosts (the hostname field matters only when one file is shared across machines), may run as root, without a password, exactly these two commands. Details that matter:
- Commands are full paths.
which systemctltells you the right one; on Debian and Ubuntu it is/usr/bin/systemctl. - Arguments are part of the match.
/usr/bin/systemctl restart myappallows exactly that;/usr/bin/systemctlalone would allow any systemctl command includingpoweroff. - A trailing
""means “no arguments allowed”:/usr/bin/journalctl "". - Wildcards exist but are dangerous:
/usr/bin/systemctl restart my*also matchesrestart my* ; rebootin some shells and every unit starting withmy. Prefer listing commands. %nameis a group:%operators ALL=(ALL:ALL) ALLis what thesudoandwheelgroups get.
Three common patterns
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
# 1. Full administrator, password required (what the sudo/wheel group already has)
%admins ALL=(ALL:ALL) ALL
# 2. Operators: manage services and read logs, nothing else
Cmnd_Alias SERVICES = /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl restart *, /usr/bin/systemctl status *
Cmnd_Alias LOGS = /usr/bin/journalctl
%operators ALL=(root) SERVICES, LOGS
# 3. Automation account: one script, no password, no shell
ci ALL=(root) NOPASSWD: /usr/local/bin/deploy-myapp.sh
For pattern 3, the script itself becomes the security boundary: it must be owned by root, not writable by ci (chmod 755, owner root), and must not pass user input to a shell. If ci could edit the script, the NOPASSWD rule would be a root shell.
Commands that are really a root shell
Some programs can start a shell or write any file, so allowing them allows everything: vi, less, find -exec, tee, cp with arbitrary targets, bash, package managers. For editing a specific file use sudoedit (sudo -e), which copies the file, runs the editor as the user and copies it back:
deploy ALL=(root) sudoedit /etc/myapp/myapp.env
Useful Defaults
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
Defaults timestamp_timeout=5 # minutes before asking the password again (default 15)
Defaults logfile=/var/log/sudo.log # a dedicated log in addition to the journal
Defaults use_pty # run commands in a pseudo-terminal
Defaults:deploy !requiretty # per-user: allow sudo without a terminal (scripts)
Defaults lines apply globally, Defaults:user to one user. Leave env_reset and secure_path at their defaults; they are what keep a user’s PATH and environment from influencing a root command.
Test before you rely on it
Check before you run this
- Runs with administrator rights. Make sure you understand every line.
sudo -u deploy sudo -l # as root: list the rules deploy gets
sudo -u deploy sudo -n /usr/bin/systemctl status myapp # -n: fail instead of asking a password
sudo journalctl _COMM=sudo -n 20 # every recent sudo call
Careful: when you tighten rules for your own account, keep a root shell open in another terminal until you have confirmed sudo -v still works for you. On a machine without a root password, that open shell is the only way back.
Official documentation
Did this work for you?
No votes yet. Be the first.
If it did not work, the report form below tells the editors what went wrong.
See also
- 0177 Users, groups and sudo on Debian, Ubuntu and RHEL How Linux accounts and groups work, how to create users, and how sudo gives admin rights through the sudo group on Debian/Ubuntu… Beginner · Explains an idea · Linux Article Users, sudo & hardening 15 Oct 2026
- 0178 Create a sudo user with an SSH key and disable password login A bash script that creates an admin user in the sudo or wheel group, installs their SSH public key and can switch… Advanced · Step by step · Linux Script Keys & config · Users, sudo & hardening 15 Oct 2026
- 0249 Set up and harden a fresh Linux server in one afternoon Take a new Ubuntu, Debian or Rocky/Alma server from first login to a safer baseline: sudo admin, SSH keys only, firewall, automatic… Beginner · Guided project · Linux Article Networking & firewalls · Packages & updates · Users, sudo & hardening 15 Oct 2026
- 0306 What is hashing? Hashing turns any data into a fixed length fingerprint that cannot be reversed, used to check files and store passwords. Beginner · Explains an idea · Any system Article Secrets & access 15 Oct 2026
- 0317 Fix: Permission denied when running a script (chmod +x) bash: ./script.sh: Permission denied means the file exists but you may not execute it. Usually the execute bit is missing; sometimes the… Beginner · Fixes an error · Linux, macOS Article Basics · Users, sudo & hardening 15 Oct 2026
- 0322 Fix: user is not in the sudoers file sudo refuses because your account is not allowed to use it. Add the user to the sudo group (Debian, Ubuntu) or wheel… Beginner · Fixes an error · Linux, macOS Article Server hardening · Users, sudo & hardening 15 Oct 2026
Repos in the wild
- Gitleaks: find secrets that were committed to a Git repository gitleaks/gitleaks Gitleaks scans Git history, working trees and arbitrary files for passwords, API keys, tokens and private keys using a library of patterns, and is usually run as a pre-commit hook and in CI. GitHub
- age: a small, modern tool for encrypting files FiloSottile/age age is a simple file encryption tool and Go library with short public keys, SSH key support and no configuration options, designed as a modern replacement for ad hoc GPG use when you need to encrypt a backup or a secret. GitHub
History
Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.
- Dominik +4,286 chars