Alright, let’s talk about the NOPASSWD tag. This is the sudo equivalent of handing your friend your credit card and saying, “Just get the groceries, don’t buy a jet ski.” It’s incredibly powerful and, if used carelessly, a fantastic way to create a gaping security hole. But sometimes, for automation and specific service accounts, entering a password is either impossible or a massive pain. That’s where NOPASSWD comes in.

The rule is simple: when a user runs a command tagged with NOPASSWD in the sudoers file, sudo will not ask for their password. It just executes the command with elevated privileges. The syntax in /etc/sudoers is the same as a normal rule, you just slap NOPASSWD: in front of the command list.

# /etc/sudoers
# User 'deploybot' can restart the web server without a password
deploybot ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx.service

# Group 'data-processors' can run the data crunching script as user 'app' without a password
%data-processors ALL=(app) NOPASSWD: /opt/scripts/crunch-data.sh

Why You’d Actually Want This

The primary legitimate use case is for non-interactive scripts and service accounts. Think about an automated deployment tool (like Ansible or a custom CI/CD script) that needs to restart a service or copy files into a root-owned directory. You can’t have a robot type a password. Locking down a specific service account to run only one or two commands as root without a password is a classic and sane approach. It follows the principle of least privilege: you’re granting the absolute minimum access required for the job, nothing more.

The Obvious and Glaring Dangers

The danger should be self-evident. If an attacker compromises the user account that has a wide-ranging NOPASSWD rule, they now have a password-less on-ramp to root. The most common and egregious mistake I see is being lazy with the command specification.

Never, ever do this:

# /etc/sudoers
# This is how you get your server pwned.
myuser ALL=(ALL) NOPASSWD: ALL

This rule is a signed, blank check for root access. If myuser’ password is cracked, or a vulnerability is found in an application running as myuser, the attacker has immediate and total control. You’ve effectively made myuser another root account, but without the scrutiny that the real root account gets.

Locking It Down: The Art of Specificity

The golden rule with NOPASSWD is to be pathologically specific. Don’t grant access to apt; grant access to /usr/bin/apt install package-name and /usr/bin/apt remove package-name. The more you constrain the command, the safer you are.

Watch out for wildcards, though. They’re powerful but tricky. A rule like NOPASSWD: /usr/bin/apt * is only marginally better than ALL because apt can be used to install a package that, say, provides a shell or modifies sudoers itself. Always ask yourself, “What’s the worst someone can do with this exact command path?”

The Subtle Edge Case: Shell Escapes

Here’s a classic pitfall. Let’s say you grant a user the ability to run vim as root without a password to edit a specific config file. Seems safe, right?

# /etc/sudoers
user1 ALL=(ALL) NOPASSWD: /usr/bin/vim /etc/nginx/nginx.conf

Well, from within vim, a user can easily escape to a shell by typing :!bash. Congratulations, they now have a full root shell, completely bypassing the intent of your rule. This is called a shell escape, and many utilities are susceptible to it (less, more, man, git, etc.).

The best practice is to avoid using editors or interactive tools in sudoers rules altogether. Instead, write a simple, safe wrapper script that performs the action you need. For our example, you could have a script that makes a backup of the file and then opens it for editing as the user, not as root. The need to actually edit as root is rare.

#!/bin/bash
# /usr/local/bin/safe-edit-nginx.sh
cp -p /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup.$(date +%Y%m%d)
vim /etc/nginx/nginx.conf
# Then the sudoers rule would be:
# user1 ALL=(ALL) NOPASSWD: /usr/local/bin/safe-edit-nginx.sh

This script doesn’t need to run as root until you want to save the file, which is a problem. A better alternative is often to use sudoedit (which uses a temporary copy and doesn’t allow shell escapes) or to manage configuration through a proper deployment process. The point is, you must think several steps ahead. The rule isn’t just about the command you intend to be run; it’s about everything that command is capable of doing.