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.

Agent versions

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):

OSPinned CA for the primary server
WindowsC:\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:

SituationWhat the agent accepts
A CA is pinned for this serverOnly 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 = falseAny 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:

RequestReturns
GET /api/pki/ca/download?format=pemThe file athena-root-ca.crt (PEM). Use this for the MSI, the Linux tarball and HermesCLI.
GET /api/pki/ca/download?format=cerThe file athena-root-ca.cer (DER), for Windows Group Policy.
GET /api/pki/caJSON; 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 methodCA 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"
PropertyMeaning
SERVER_URLThe agent-port URL, https://<server>:8444. The other properties are applied only when this is set.
REGISTRATION_TOKENA registration token. It is kept out of the MSI log.
CA_CERTThe Athena Root CA: a file path, or the certificate's base64 (PEM or DER).
SERVER_NAMEName 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
OptionMeaning
--server URLThe agent-port URL. Asked for if omitted.
--token TOKENThe registration token. Asked for if omitted.
--ca-cert FILEThe Athena CA certificate, as a PEM file. Required, unless you pass the option below.
--insecure-skip-server-cert-checkInstall 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
OptionMeaning
--nameServer entry name (required).
--urlAgent-port URL (required).
--tokenRegistration token (optional).
--ca-certThe Athena CA: a file path (PEM or DER) or its base64. Saved as servers\<name>\ca.crt; also sets ValidateServerCertificate to true.
--replaceUpdate 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:

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.

SymptomCause 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 issuerThe 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 setThe 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.