How to Set Up a Deployment User with Restricted SSH Access

Automated deployment tools need SSH access to your VPS, but granting them full administrative access is unnecessary risk. This guide covers creating a deployment-specific account restricted to only what it needs.

Why a Dedicated Deployment User

  • If the deploy key is ever compromised, the blast radius is limited to what the deploy user can do
  • Clear audit trail — deployment actions are distinguishable from human administrative actions
  • Easier to revoke deployment access specifically without affecting other access

Step 1 — Create the Deployment User

sudo useradd -m -s /bin/bash deploy-bot

Step 2 — Generate a Dedicated SSH Key Pair for Deployment

On your local machine or CI system (not the VPS):

ssh-keygen -t ed25519 -f deploy_key -C "deployment-only" -N ""

Step 3 — Add the Public Key to the Deployment User

sudo mkdir -p /home/deploy-bot/.ssh
sudo nano /home/deploy-bot/.ssh/authorized_keys

Paste the public key content, then:

sudo chown -R deploy-bot:deploy-bot /home/deploy-bot/.ssh
sudo chmod 700 /home/deploy-bot/.ssh
sudo chmod 600 /home/deploy-bot/.ssh/authorized_keys

Step 4 — Restrict Sudo Access to Only Deployment-Related Commands

sudo visudo -f /etc/sudoers.d/deploy-bot
deploy-bot ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp, /usr/bin/systemctl reload nginx, /usr/local/bin/deploy.sh

This lets the deployment user run only these specific commands with elevated privileges — nothing else.

Step 5 — Restrict File System Access

sudo chown -R deploy-bot:deploy-bot /var/www/myapp

The deployment user only needs write access to the application directory it manages, not the entire filesystem.

Step 6 — Restrict the SSH Key to a Specific Command (Advanced, Stronger Isolation)

In authorized_keys, prefix the key with a command restriction so it can only ever run one specific script, regardless of what command is actually sent:

command="/usr/local/bin/deploy.sh",no-port-forwarding,no-X11-forwarding,no-agent-forwarding ssh-ed25519 AAAA...

This is the strongest form of restriction — even if the private key is compromised, an attacker can only trigger the deployment script, nothing else, regardless of what SSH command they attempt to run.

Step 7 — Test the Restricted Access

ssh -i deploy_key deploy-bot@YOUR_SERVER_IP "whoami"

If using the command restriction from Step 6, this will run deploy.sh regardless of the whoami command sent, confirming the restriction is active.

Step 8 — Disable Interactive Login for the Deployment User (Optional, Extra Hardening)

sudo usermod -s /usr/sbin/nologin deploy-bot

Combined with the command restriction, this ensures the account can only ever execute the deployment script via SSH, never an interactive shell.

Auditing Deployment Activity

sudo grep deploy-bot /var/log/auth.log

Combined with your deployment script's own logging (see How to Deploy Automatically on Git Push), gives a complete picture of when deployments ran and by what mechanism.

Common Errors

"This account is currently not available" when testing interactive login — expected if you set the shell to nologin; verify the actual deployment command still works via the command restriction.

Deployment fails with a permission error — verify the deployment user owns (or has explicit access to) every path the deployment script touches.

Best Practices

  • Use a dedicated deployment user, never a personal or shared administrative account
  • Restrict both sudo privileges and, ideally, the SSH key itself to only the specific deployment command
  • Regularly audit and rotate deployment credentials

Continue Reading

Browse more articles in DevOps & CI/CD.

  • deployment user, restricted ssh access, ssh command restriction, deployment security
  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

How to Set Up a Self-Hosted GitHub Actions Runner on a VPS

GitHub Actions' hosted runners work well for most projects, but a self-hosted runner on your own...

How to Deploy Automatically on Git Push (Webhook-Based Deployment)

Automating deployment whenever you push to a specific branch removes the manual "SSH in and pull"...

How to Set Up Blue-Green Deployment on a VPS

Blue-green deployment runs two identical production environments — only one live at a time...

How to Use Ansible for Server Configuration Management

Ansible automates server configuration through simple, human-readable YAML files — letting...

Infrastructure as Code Basics: Managing VPS Config with Terraform

Terraform lets you define infrastructure (VPS instances, networks, DNS records) as code, applied...