Agent Server Trust (CA Pinning)
Every Hermes agent checks that it is talking to your Athena server before it sends a registration token, inventory, or accepts a command. It does that by pinning your server's Root CA: once an agent holds that CA, it accepts the agent-port (8444) certificate only if it was issued by that exact CA. This page explains how the CA gets onto an agent, how to supply it when you install from the release MSI or Linux tarball, what the agent refuses, and how to fix an agent that will not connect. It all works offline, on an air-gapped network.
The behaviour on this page applies to Windows agent 1.2.155, Linux agent 1.2.137, macOS agent 1.2.144 and HermesCLI 1.2.28 or later. Agents pick it up through a normal agent update; nothing has to be reinstalled.
What the agent checks#
The pinned CA is stored per server, as servers\<name>\ca.crt in the agent's data folder
(<name> is the server entry's name, primary for a normal install):
| OS | Pinned CA for the primary server |
|---|---|
| Windows | C:\ProgramData\Hermes\servers\primary\ca.crt |
| Linux | /var/lib/hermes/servers/primary/ca.crt |
| macOS | /Library/Application Support/Hermes/servers/primary/ca.crt |
When the agent connects to the agent port (8444), it decides like this:
| Situation | What the agent accepts |
|---|---|
| A CA is pinned for this server | Only a certificate whose chain ends in that exact CA. A certificate the operating system trusts from any other issuer (for example your corporate AD CS) is refused, because the agent port is always served by a certificate from the Athena CA. This applies whatever ValidateServerCertificate says. |
Nothing pinned, ValidateServerCertificate = true (the shipped default) | A certificate the operating system trusts. A self-signed Athena server is refused unless its CA is in the machine's trust store. |
Nothing pinned, ValidateServerCertificate = false | Any certificate, for first contact only. After it registers, the agent holds the server's CA and enforces it from then on. |
In every case, a certificate issued for a different host name than the one in the server URL is refused. Revocation is not checked against the Athena CA, because it publishes no revocation list and agents may be offline.
When an agent registers, the server's answer includes its CA. If no CA is pinned yet, the agent saves it. If one is pinned and the answer carries a different CA, the agent refuses the answer and saves nothing (see When the CA changes).
Getting your server's CA certificate#
The Root CA certificate is public (it holds no key), and the server hands it out without signing in:
| Request | Returns |
|---|---|
GET /api/pki/ca/download?format=pem | The file athena-root-ca.crt (PEM). Use this for the MSI, the Linux tarball and HermesCLI. |
GET /api/pki/ca/download?format=cer | The file athena-root-ca.cer (DER), for Windows Group Policy. |
GET /api/pki/ca | JSON; the PEM text is in data. |
curl -k -o athena-root-ca.crt "https://<server>:8443/api/pki/ca/download?format=pem"
Fetch it once from a machine you trust and copy the file to where you install, rather than downloading it on
each endpoint with certificate checks off. With PowerShell, Save-AthenaCACertificate does the same
(see Certificates & PKI).
Which install methods pin the CA for you#
| Install method | CA pinned? |
|---|---|
| One-line installers from the Agents page (Windows, Linux, macOS) | Yes, automatically. The script carries your server's CA and writes it as the agent's ca.crt before the agent first starts. See Agent Enrollment. |
| Agent install bundle (Windows ZIP) | Yes, automatically. The ZIP includes ca.crt. |
Release MSI (Hermes.Agent-<version>-windows-x64.msi) | Only if you pass CA_CERT. The release packages are the same for every customer, so they cannot carry your CA. See below. |
Release Linux tarball (Hermes.Agent-<version>-linux-x64.tar.gz) | Only if you pass --ca-cert to its install.sh. See below. |
Install-AthenaAgent (push over WinRM) | No. The agent pins the CA when it registers. Without -SkipCertificateCheck, first contact needs the Athena CA in the machine's trust store; with it, first contact accepts any certificate. |
Silent MSI install with the CA#
From an elevated prompt:
msiexec /i Hermes.Agent-<version>-windows-x64.msi /quiet ^
SERVER_URL="https://<server>:8444" ^
REGISTRATION_TOKEN="<registration-token>" ^
CA_CERT="C:\path\athena-root-ca.crt"
| Property | Meaning |
|---|---|
SERVER_URL | The agent-port URL, https://<server>:8444. The other properties are applied only when this is set. |
REGISTRATION_TOKEN | A registration token. It is kept out of the MSI log. |
CA_CERT | The Athena Root CA: a file path, or the certificate's base64 (PEM or DER). |
SERVER_NAME | Name of the server entry. Default primary. |
During the install, before the service first starts, the MSI runs HermesCLI to write the server entry into
the agent's appsettings.json, save the CA as servers\<SERVER_NAME>\ca.crt and set
ValidateServerCertificate to true. So the very first connection is already checked
against your CA. If CA_CERT is not a CA certificate, the install fails and rolls
back instead of leaving an agent that trusts the wrong thing.
Linux tarball install with the CA#
The release tarball includes install.sh. Extract it and run, as root:
sudo ./install.sh --server https://<server>:8444 --token <registration-token> --ca-cert ./athena-root-ca.crt
| Option | Meaning |
|---|---|
--server URL | The agent-port URL. Asked for if omitted. |
--token TOKEN | The registration token. Asked for if omitted. |
--ca-cert FILE | The Athena CA certificate, as a PEM file. Required, unless you pass the option below. |
--insecure-skip-server-cert-check | Install without a CA and with ValidateServerCertificate = false. For lab use only. |
The script installs to /opt/hermes, saves the CA as
/var/lib/hermes/servers/primary/ca.crt and writes the server as primary.
Pinning the CA on an installed agent#
Use HermesCLI from an elevated prompt (or as root) to set or update a server entry and pin its CA, then restart the agent:
hermescli config server add --name primary --url https://<server>:8444 --ca-cert C:\path\athena-root-ca.crt --replace
hermescli service restart
| Option | Meaning |
|---|---|
--name | Server entry name (required). |
--url | Agent-port URL (required). |
--token | Registration token (optional). |
--ca-cert | The Athena CA: a file path (PEM or DER) or its base64. Saved as servers\<name>\ca.crt; also sets ValidateServerCertificate to true. |
--replace | Update the entry if one with this name already exists. Without it, an existing name is an error. |
On success the output lists the entry and a line CA: with the CA's thumbprint, followed by "(pinned; server certificate validation on)". Compare that thumbprint with the one shown in Settings → Security → Certificate on your server.
When the CA changes#
The pinned CA is also what the agent uses to check signed agent updates and uninstall codes, so the agent never lets a server swap it:
- A registration answer that carries a different CA is refused, and nothing is saved.
- A server migration in
Mintmode keeps the same CA: the new address must present a certificate from the CA the agent already trusts. A migration inPastemode adds a new server entry, which gets its own pinned CA when it registers. - If you regenerate your server's CA, agents that pinned
the old CA refuse the server's new certificate and stop connecting. Pin the new CA on each one with
config server add … --ca-cert … --replace(or reinstall with a one-line installer), and re-enrol them. Prefer Extend over Regenerate: extending keeps the same CA.
Agents installed with validation off#
Older release packages shipped with ValidateServerCertificate set to false, and an
agent update replaces only the program, not appsettings.json. You do not need to change those
agents: once they are on the versions above, any agent that already registered holds its server's CA and
enforces it, whatever its appsettings.json says. Only an agent that has never registered still
accepts any certificate on first contact.
Package and update downloads (Windows)#
Windows agents download deployment packages, agent updates and Windows Update files from the web port (8443). That port may legitimately use a certificate from your own PKI or a public CA (see Server TLS Certificate), so for these downloads the agent accepts a certificate that chains to any pinned Athena CA or one the operating system trusts. It never accepts any certificate, and never one issued for another host name. A deployment package is also checked against the SHA-256 the server sends over the pinned agent channel; a package without that hash fails instead of running.
Troubleshooting#
Agent messages appear in the agent log.
| Symptom | Cause and fix |
|---|---|
| Agent log: "Server certificate rejected (policy errors: …). Refusing to connect" | The 8444 certificate does not chain to the pinned CA, is for another host name, or (nothing pinned) is not trusted by the OS. Check that the server URL uses a name on the server's certificate, and that ca.crt is your current CA. A fresh install from the release MSI without CA_CERT against a self-signed server also ends here: pin the CA with HermesCLI. |
| Agent log: "Refusing a server response whose CA (…) is not the pinned Athena CA (…); nothing was saved" | The server answering has a different CA than the one this agent pinned: a different Athena server, or your CA was regenerated. If the server is genuinely yours, pin its current CA (When the CA changes). |
| Agent connected before, stopped after the agent update, and your agent port is served through a certificate from another issuer | The agent port must present the certificate issued by the Athena CA. A certificate from another PKI, even one the OS trusts, is refused once a CA is pinned. Custom certificates are for the web port (8443) only. |
| HermesCLI: "The certificate … is not a CA certificate; pass the Athena Root CA." | You passed the server's certificate, not its CA. Download athena-root-ca.crt (above). |
| HermesCLI: "--ca-cert must be a CA certificate file (PEM or DER) or its base64." | The path does not exist, or the value is not valid base64. |
MSI install fails and rolls back when CA_CERT is set | The same two checks as HermesCLI: the file must exist and be the CA certificate. |
install.sh: "--ca-cert is required: the agent validates the server certificate against the Athena CA." | Pass --ca-cert. For a lab only, --insecure-skip-server-cert-check. |
install.sh: "--ca-cert must point at the Athena CA certificate (PEM)" | The file is missing or is DER. Download it with format=pem. |
Related#
- Certificates & PKI: the Root CA, agent certificates, extend vs. regenerate.
- Agent Enrollment: one-line installers that pin the CA for you.
- Agent CLI (HermesCLI): all
config servercommands. - Agent Configuration File:
ValidateServerCertificateand the server list. - Agent Server Migration: moving agents to a new address or server.
- Network Ports & Firewall: ports 8443 and 8444.