Install Hermes as an Unprivileged Service User
Hermes supports installation under a dedicated account that has no sudo access. This is a good fit for an always-on gateway or other managed workload because the agent's files, configuration, sessions, and credentials remain owned by a non-root identity. The official installer already understands this case: it detects that privilege escalation is unavailable, installs user-space components locally, and skips only the operating-system package step it cannot perform.
The important design choice is to split administrator work from service-user work. An administrator handles the small set of machine-wide prerequisites. The service account owns the Hermes checkout, virtual environment, data directory, provider setup, and normal runtime.
Decide whether browser automation is required
On Debian and Ubuntu, Playwright's shared Chromium libraries are the one installer step that genuinely needs root. If the service will use browser automation, an administrator should install those libraries once:
sudo npx playwright install-deps chromiumThe command can run from any directory; npx fetches Playwright for the dependency check. After that, the unprivileged account can install its own Chromium binary in its Playwright cache.
If this deployment will not use browser automation, skip the Playwright installation entirely. That avoids an unnecessary browser download and removes the only root-dependent branch from the Hermes install:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash -s -- --skip-browserDo not choose --skip-browser merely because the machine has no desktop. Headless browser automation still needs Chromium. Use the flag only when browser tools are intentionally out of scope.
Prepare the service account
Use an existing dedicated account with a writable home directory. On Linux, make sure the documented installer prerequisites are present: Git, plus curl and xz-utils. The administrator can install those machine-wide before handing control to the service user.
Open a login shell as the target service account using the host's normal administrative procedure. Run the installer from that shell, not from a root shell and not by prefixing the installer with sudo:
curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bashA per-user installation places the source checkout under ~/.hermes/hermes-agent/, keeps agent data under ~/.hermes/, and writes the launcher at ~/.local/bin/hermes. Those locations are relative to the service account's own home. This is different from the root-mode FHS installation and is the intended layout for an unprivileged identity.
The installer supplies Python through uv, Node.js, ripgrep, ffmpeg, the virtual environment, and the Hermes launcher. When it cannot run Playwright's operating-system dependency command, it degrades gracefully and prints the administrator command that remains.
Put the correct launcher on PATH
System accounts often start with a minimal PATH. Add the per-user launcher directory to the service account's shell environment:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrcA service manager may not read .bashrc. Give the unit an equivalent PATH explicitly, or have an administrator create a system-visible symlink to the virtual-environment launcher. Whichever method you use, target the installed venv launcher—not the repository's source-level hermes file.
That distinction matters. If hermes doctor fails with ModuleNotFoundError: No module named 'dotenv', the shell is probably executing ~/.hermes/hermes-agent/hermes with system Python rather than ~/.hermes/hermes-agent/venv/bin/hermes. Correct the PATH or symlink instead of installing random Python packages globally.
Configure Hermes as the same identity
Run initial configuration while logged in as the service account so credentials and state land in the same Hermes home the service will use:
hermes model
hermes tools
hermes config check
hermes doctorConfigure only the providers and tools the service needs. If it will expose a messaging gateway, prove ordinary CLI chat works first, then run hermes gateway setup. Installing Hermes does not by itself define a systemd unit, choose messaging adapters, authorize users, or establish a restart policy; those are separate deployment decisions.
Keep ownership consistent. Avoid running later Hermes setup commands as root, because root-owned files inside the service account's state can cause subtle read or write failures. The service manager should launch Hermes as the same account that performed the per-user install.
Pitfalls
- Running the entire installer as root when the goal is a least-privilege service account.
- Asking the service user to install Playwright system libraries it cannot install.
- Using
--skip-browserand later expecting Chromium-backed browser automation to work. - Updating
.bashrcbut forgetting that a non-interactive service unit may use a different PATH. - Symlinking the repository wrapper instead of the virtual-environment launcher.
- Mixing root-owned configuration with files created by the unprivileged account.
- Treating a successful install as proof that the eventual gateway service, provider, or messaging channel is healthy.
Verification checklist
- Verify
git --versionworks in the service account's login shell. - Verify
command -v hermesresolves to the per-user launcher or the installed virtual-environment launcher. - Verify
hermes doctorcompletes without thedotenvlauncher error or missing prerequisite findings. - Verify a normal
hermeschat can reach the configured model before adding a gateway or scheduler. - Verify browser automation with a harmless page only when Chromium support is part of the deployment.
- Verify the service manager uses the same operating-system user, home, PATH, and Hermes state as the interactive checks.
- Verify Hermes-owned files remain writable by the service account and were not recreated by root.
