Hermes Agent
Overview
Hermes Agent is an open source, MIT-licensed AI agent runtime. It holds a conversation with you and uses tools (a terminal, file editing, web search and fetch, code execution and many more) to get work done on the machine it runs on. It remembers what it learns across sessions, writes its own reusable skills and runs scheduled jobs. You can reach it from a browser, a terminal, chat apps or any OpenAI-compatible client.
This guide covers deploying and operating Hermes Agent on Ubuntu 24.04 on Azure, using the SecureAnyCloud image from the Azure Marketplace. The image gives you the whole product, ready to use on a VM you control.
No password, key or certificate is baked into the image. First boot generates the dashboard password, the session signing secret, the API key and a TLS certificate, uniquely on each VM. The services refuse to start until it has done so. Before it marks the VM ready, first boot proves that an anonymous caller and a wrong password are refused.
You bring the model. Hermes Agent works with the provider of your choice: OpenRouter, Anthropic, OpenAI, Nous Portal, or your own OpenAI-compatible endpoint (vLLM, llama.cpp, Ollama) serving a model with at least a 64K context window. No model ships in the image, and nothing is sent anywhere until you connect one.
Hermes Agent is developed by Nous Research and is licensed under the MIT license. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by or sponsored by Nous Research. It ships the free and open source software from an upstream release. The names are used here solely to identify the software this image contains.
What you get:
- The web dashboard, served over HTTPS by nginx, with its own sign-in page and a per-VM admin password. It manages configuration, API keys, sessions, skills, MCP servers, cron jobs, messaging channels and logs. Its Chat tab runs the full Hermes terminal interface in your browser
- The messaging gateway, running as a service. It carries the OpenAI-compatible API server at
https://<vm-ip>/v1, protected by a per-VM bearer key, and connects Telegram, Discord, Slack and other channels when you configure them - The
hermescommand for SSH sessions, running as the dedicatedhermesservice account - Hermes Agent 0.22.2, installed by the upstream installer from the
release/0.22.2branch at commitd923a5eb. Everything that installer would otherwise download at run time is baked in: a pinned Python 3.14, a pinned Node.js 26, the locked Python environment, the terminal UI and the web dashboard build - A dedicated
hermesservice account with a locked password and no SSH keys. The terminal tool of the agent runs as this account, not as root - nginx terminating HTTPS on
443with a per-VM certificate, and redirecting80to HTTPS - The dashboard on
127.0.0.1:9119and the API server on127.0.0.1:8642, reachable only through nginx - Unattended security upgrades left on for the operating system
- 24/7 SecureAnyCloud support
Prerequisites
- An Azure subscription with permission to create VMs
- An account with a model provider (for example an OpenRouter, Anthropic or OpenAI API key), or your own OpenAI-compatible model server
- A
Standard_B4msVM (4 vCPU, 16 GiB) or larger is recommended.Standard_B2msworks for light use with a hosted provider - Inbound TCP
443(and80for the redirect) open only to the networks you connect from, plus22for SSH administration. The dashboard can run commands on this VM through the agent, so treat access to it like SSH access - An SSH key pair for administrative access
Deploy from the Azure Portal
- In the Azure Portal, search the Marketplace for Hermes Agent on Ubuntu 24.04 LTS by SecureAnyCloud and select Create.
- Choose your subscription, resource group and region.
- Set the VM size to Standard_B4ms or larger.
- Under Administrator account, select SSH public key and supply your own key.
- Under Inbound port rules, allow HTTPS (443), HTTP (80) and SSH (22). Then restrict all three to your own address ranges on the networking blade.
- Click Review + create, then Create.
Deploy from the Azure CLI
az vm image terms accept --urn sac1647283583153:hermes-agent-ubuntu-24-04:default:latest
az vm create \
--resource-group my-resource-group \
--name my-hermes-agent \
--image sac1647283583153:hermes-agent-ubuntu-24-04:default:latest \
--size Standard_B4ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_rsa.pub \
--public-ip-sku Standard
# Open HTTPS (and the HTTP redirect) to YOUR network only. MY_CIDR="203.0.113.0/24"
# replace with your own range
az network nsg rule create \
--resource-group my-resource-group \
--nsg-name my-hermes-agentNSG \
--name allow-https-from-office --priority 1010 \
--source-address-prefixes "${MY_CIDR}" \
--destination-port-ranges 80 443 --protocol Tcp --access AllowConnect to your VM
SSH to the VM as azureuser:
ssh azureuser@<vm-ip>Confirm the services are running
First boot takes about a minute. It generates the secrets and certificate for this VM, starts the services and proves the sign-in gate before it finishes. Check the services:
# All three report "active". The firstboot unit is a oneshot that stays active (exited).
systemctl is-active hermes-agent-firstboot.service hermes-dashboard.service nginx.service
# The messaging gateway (which also serves the API) runs as a systemd user service
# of the hermes account, so it starts at boot without anyone logging in.
sudo hermes gateway status 2>&1 | grep -E 'running|linger'
# Hermes listens on loopback only; nginx is the only public listener.
sudo ss -lntp | grep -E ':(80|443|9119|8642)\b'The expected output shows Hermes on 127.0.0.1 and nginx on 0.0.0.0:
active active active ✓ User gateway service is running ✓ Systemd linger is enabled (service survives logout) LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",...)) LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",...)) LISTEN 0 2048 127.0.0.1:8642 0.0.0.0:* users:(("hermes",...)) LISTEN 0 2048 127.0.0.1:9119 0.0.0.0:* users:(("hermes",...))Read this VM's credentials
Everything in the credentials file was generated on this VM at first boot. Read it:
sudo cat /root/hermes-agent-credentials.txt# Hermes Agent - per-VM credentials generated on first boot (...).
# Keep this file private. Change the dashboard password with:
sudo hermes-dashboard-password DASHBOARD_URL=https://<vm-ip>/ DASHBOARD_USERNAME=admin DASHBOARD_PASSWORD=<DASHBOARD_PASSWORD> API_BASE_URL=https://<vm-ip>/v1 API_SERVER_KEY=<API_SERVER_KEY>Sign in to the dashboard
- Open
DASHBOARD_URLfrom the credentials file in your browser. The certificate is self-signed and generated for this VM, so your browser warns you the first time. Accept it for this address, or follow Step 12 to use your own domain and a trusted certificate. - Sign in as
adminwithDASHBOARD_PASSWORD.
After you sign in, you land on the dashboard. The sidebar shows the gateway running, along with the pages for chat, sessions, files, models, logs, cron, skills, plugins, MCP servers, channels, webhooks, pairing, profiles, configuration, keys and system administration.
The first time you sign in, Hermes asks whether you want to share anonymous usage metrics with Nous Research. Collection and sending are off until you choose, and you can answer No thanks.
Understand the access model
- Dashboard. Hermes runs its web server on
127.0.0.1:9119only. Hermes enables its own sign-in gate when it is told the external address it is published at. First boot therefore declareshttps://<vm-ip>, together with a per-VMadminpassword hash and session secret, in/etc/hermes-agent/dashboard.env(readable by root only). Every page and API route except the public status endpoint needs a signed-in session, and requests addressed to any other host name are rejected. - API. The OpenAI-compatible API server listens on
127.0.0.1:8642, and nginx publishes it at/v1/. Every request needs the per-VM bearer key,API_SERVER_KEY. - TLS. nginx serves both on port
443with a certificate generated for this VM. Port80only redirects to HTTPS. - Brute force. Hermes limits password sign-ins to ten a minute per client, and nginx applies its own limit to the sign-in endpoint.
You can check all of this from the VM itself:
code() { curl -sk -o /dev/null -w '%{http_code}' "$@"; }
# Anonymous callers are refused (401), the public status says the gate is on.
curl -sk https://127.0.0.1/api/status | python3 -c 'import sys,json;d=json.load(sys.stdin);print("auth_required:",d["auth_required"],"providers:",d["auth_providers"])' echo "anonymous /api/config : $(code https://127.0.0.1/api/config)"
# A wrong password is refused (401), this VM's password is accepted (200).
echo "wrong password : $(code -H 'Content-Type: application/json' -d '{"provider":"basic","username":"admin","password":"wrong-password-123"}' https://127.0.0.1/auth/password-login)"
echo "per-VM password : $(code -H 'Content-Type: application/json' -d '{"provider":"basic","username":"admin","password":"<DASHBOARD_PASSWORD>"}' https://127.0.0.1/auth/password-login)"
# The API refuses a missing key (401) and accepts this VM's key (200). echo "API without key : $(code https://127.0.0.1/v1/models)" echo "API with key : $(code -H 'Authorization: Bearer <API_SERVER_KEY>' https://127.0.0.1/v1/models)"Connect a model provider
Hermes needs a model before it can answer. Until you add one, the chat and the API reply that Hermes is not connected to an AI provider yet.
From the dashboard. Open Keys, find your provider (for example OPENROUTER_API_KEY or ANTHROPIC_API_KEY), paste the key and save. Then open Models, choose Change next to the main model and pick a model from that provider. Restart the gateway from the sidebar, so the API and messaging channels pick up the change.
From SSH. sudo hermes model runs the interactive provider and model picker. To point Hermes at your own OpenAI-compatible server instead, set the endpoint directly:
sudo hermes config set model.provider custom
sudo hermes config set model.base_url http://10.0.0.5:8000/v1
sudo hermes config set model.default YOUR_MODEL_NAME
sudo hermes gateway restartKeys you add are written to /var/lib/hermes/.hermes/.env, which only the hermes account can read.
Chat with the agent
In the browser. The Chat tab runs the real Hermes terminal interface in the page, with a session list and model picker beside it. Sessions are saved, and you can resume them from Sessions.
Over SSH. The hermes command runs as the hermes account, whoever calls it. sudo hermes therefore opens the same agent, with the same configuration, sessions and memory:
# Version and install details of the agent on this VM.
sudo hermes --versionHermes Agent v0.22.2 (2026.9.24) · stable · local d923a5eb487a Install directory: /var/lib/hermes/.hermes/hermes-agent Install method: git Python: 3.14.7Start an interactive chat with sudo hermes, or ask a single question with sudo hermes -z "summarise the files in this directory". The working directory of the agent is /var/lib/hermes/workspace.
What the agent can do. By default, the tools of the agent act on this VM as the hermes account. It can read and write files in its home and workspace, and it can run commands without root. Dangerous commands ask for approval. Review Config > approvals before you give it more access.
Use the OpenAI-compatible API
Any OpenAI-compatible client can talk to the agent. Point the client at API_BASE_URL, with API_SERVER_KEY as the API key and hermes-agent as the model. First, list the model that the API serves:
# List the model the API serves.
curl -skf https://127.0.0.1/v1/models -H "Authorization: Bearer <API_SERVER_KEY>"Once a provider is connected, send a chat completion from your workstation:
curl https://<vm-ip>/v1/chat/completions \
--cacert hermes-agent.crt \
-H "Authorization: Bearer YOUR_API_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"hermes-agent","messages":[{"role":"user","content":"What can you do?"}]}'For --cacert, copy the certificate of the VM from /etc/hermes-agent/tls/hermes-agent.crt to your workstation, or use your own certificate (Step 12). The API also offers streaming, the Responses API (/v1/responses) with server-side conversation state, and a runs API. See the upstream API server documentation.
Connect messaging channels
Open Channels in the dashboard to connect Telegram, Discord, Slack, Matrix, Mattermost, WhatsApp, Signal, email and others. Each form asks for exactly what that platform needs (a bot token, an allow list) and links to the setup guide of the platform.
Save the form, enable the channel and choose Restart gateway. Approve new users under Pairing.
Use your own domain and certificate
Hermes only answers requests addressed to the external URL it was given, which first boot set to https://<vm-ip>. To serve the dashboard under a DNS name:
- Create a DNS record for your name that points at the public IP of the VM.
- Declare the new URL. This restarts the dashboard:
sudo hermes-dashboard-url https://agent.example.com- Replace the self-signed certificate with a trusted one. For example, use Let's Encrypt, with port 80 open to the internet while it issues the certificate:
sudo apt-get install -y certbot
sudo certbot certonly --webroot -w /var/www/html -d agent.example.com
sudo ln -sf /etc/letsencrypt/live/agent.example.com/fullchain.pem /etc/hermes-agent/tls/hermes-agent.crt
sudo ln -sf /etc/letsencrypt/live/agent.example.com/privkey.pem /etc/hermes-agent/tls/hermes-agent.key
sudo systemctl reload nginxDay-2 operations
Change the dashboard password. The command prompts for the new password, so it is never typed on the command line, and only its hash is stored:
sudo hermes-dashboard-passwordService control. Check the services:
# The dashboard and nginx are system services.
sudo systemctl status hermes-dashboard.service --no-pager | head -5
# The gateway (API server and channels) is restarted through hermes itself.
sudo hermes gateway status 2>&1 | grep -E 'running|stopped'Logs. The Logs page shows the agent, gateway and error logs. You can also read them over SSH:
sudo ls /var/lib/hermes/.hermes/logs/
sudo journalctl -u hermes-dashboard.service -n 20 --no-pagerUpdates. The operating system patches itself through unattended upgrades. Update Hermes Agent from the dashboard (System > Update now) or with sudo hermes update, which also restarts the gateway.
Backups. Everything the agent owns (configuration, keys, sessions, memories, skills) lives under /var/lib/hermes/.hermes. sudo hermes backup writes an archive that you can copy off the VM, and Azure disk snapshots capture the whole VM.
Files and locations.
- /root/hermes-agent-credentials.txt: the dashboard password and API key of this VM
- /etc/hermes-agent/dashboard.env: the dashboard URL, admin password hash and session secret (root only)
- /etc/hermes-agent/tls/: the TLS certificate and key of the VM
- /var/lib/hermes/.hermes/config.yaml: the Hermes configuration
- /var/lib/hermes/.hermes/.env: provider keys and API server settings
- /var/lib/hermes/workspace: the default working directory of the agent
- /etc/nginx/sites-available/hermes-agent: the HTTPS front door
Troubleshooting
- The browser shows "400 Bad Request" or "Invalid host". You reached the VM by a name or address other than the one Hermes was told about. Use
DASHBOARD_URL, or declare the new one withsudo hermes-dashboard-url(Step 12). - "Too many login attempts". Wait a minute. Sign-ins are limited per client.
- Chat or the API replies that Hermes is not connected to an AI provider. Add a provider key and pick a model (Step 8), then restart the gateway.
- A local model is rejected for its context window. Hermes needs a model served with at least a 64K context. CPU-only VMs are too slow for a useful local model, so use a hosted provider or a GPU server.
- Nothing answers on 443. Check
systemctl status hermes-agent-firstboot.serviceand/var/log/hermes-agent-firstboot.log.
Support
SecureAnyCloud provides 24/7 support for this image. Contact sales@secureanycloud.com with the region of your VM and the output of sudo hermes --version. For Hermes Agent itself, see the upstream documentation at hermes-agent.nousresearch.com.
Deploy on Azure
Launch Hermes Agent on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com