The principle of least privilege means every user, process, and service should have only the minimum access necessary to do its job — nothing more. This guide covers applying it practically across a typical VPS setup.
Why It Matters
When (not if) something goes wrong — a compromised application, a mistaken command, a stolen credential — least privilege limits the blast radius. An attacker who compromises a service account with minimal permissions can do far less damage than one who compromises a fully privileged account.
Applying Least Privilege to User Accounts
- Never use root for daily administration — see How to Create a New User with Sudo Access on a Linux VPS
- Grant sudo access only to specific commands where possible, rather than blanket sudo access, using
/etc/sudoers.d/entries - Remove or disable accounts no longer needed
Restricting sudo to Specific Commands
sudo visudo -f /etc/sudoers.d/deploy-restricted
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl restart myapp
This lets the deploy user restart specific services without a password, but not perform arbitrary root actions.
Applying Least Privilege to Application Processes
- Run web servers and applications as a dedicated non-root user (e.g.
www-data), never as root - For Docker, avoid running containers as root inside the container when the image supports an alternative — see Docker Security Best Practices for Production Servers
- Use systemd's built-in sandboxing directives to further restrict a service's filesystem/network access
Restricting a systemd Service's Access
[Service]
User=deploy
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/www/myapp/storage
These directives progressively restrict what the service can access on the filesystem, beyond just the running user's own permissions.
Applying Least Privilege to Databases
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp.* TO 'appuser'@'localhost';
Avoid GRANT ALL PRIVILEGES for application accounts — a compromised application shouldn't be able to drop tables or modify database users if it only needs standard CRUD operations.
Applying Least Privilege to File Permissions
chmod 640 /etc/myapp/config.yml
chown deploy:deploy /etc/myapp/config.yml
Sensitive configuration files should be readable only by the specific user/group that needs them, not world-readable.
Applying Least Privilege to Network Access
- Firewall rules allowing only necessary ports/sources — see How to Configure UFW Firewall on a Linux VPS
- Bind services to
127.0.0.1when they don't need external access, rather than0.0.0.0 - Restrict database access to specific application server IPs, not the entire internet
Applying Least Privilege to API Keys and Credentials
When creating API keys/tokens for third-party services, scope them to only the specific permissions the integration actually needs, rather than using broad "full access" tokens by default.
Auditing Current Privilege Levels
sudo -l -U username
Reviews exactly what a specific user is currently permitted to do via sudo.
Common Mistakes
- Granting broad access "temporarily" and forgetting to revoke it later
- Using the same database account with full privileges across every application on a server
- Running every service as root "because it's simpler"
Best Practices
- Default to minimal access, expand only when a specific, justified need arises
- Periodically review and revoke unused or overly broad permissions
- Document why any unusually broad privilege grant exists, for future review
Continue Reading
- How to Create a New User with Sudo Access on a Linux VPS
- Database Security Checklist: Protecting MySQL, PostgreSQL & MongoDB
- How to Set Up AppArmor for Application Sandboxing
Browse more articles in Advanced Security & Compliance.
