Agent Binaries & Updates

Athena keeps a library of agent binaries on the server and lets you decide which version each operating system runs. You upload a new agent build, mark it active for its OS, then push that version to whichever agents you choose. The server streams the signed binary to each connected agent over the same connection it already uses — no download server, no internet, and every push is written to the audit log. It is the fleet-wide "client version management" a System Center admin expects, kept entirely inside your network.

This page covers keeping already-enrolled agents up to date. For getting the agent onto a fresh host in the first place — installer one-liners, ZIP bundles, and certificates — see Agent Enrollment.

The binary library#

Each uploaded build is stored as an agent binary record. Binaries are keyed by Os and Version, and each OS has at most one active version at a time. Every record tracks:

FieldMeaning
idUnique identifier (GUID).
versionVersion string, e.g. 1.2.42. Rejected if it contains path characters (.., /, \, :).
osTarget operating system — Windows or Linux.
fileNameOriginal filename of the uploaded build.
fileHashSHA-256 hash of the binary, computed by the server on upload.
fileSizeSize in bytes.
signatureServer signature over the hash (see Signing). null only for legacy builds uploaded before signing existed.
releaseNotesOptional free-text notes.
isActivetrue when this is the current version for its OS.
downloadCountHow many times the binary has been served.
uploadedBy / uploadedAtWho uploaded the build and when.

Uploading & signing#

You upload a build with POST api/agent-binaries as a multipart form (file, os, version, and optional releaseNotes). Uploads are Admin-only and capped at 500 MB. As it streams the file to disk the server:

  1. Computes the SHA-256 hash of the binary.
  2. Signs that hash with the CA private key — an RSA / SHA-256 (PKCS#1) signature, stored Base64 in the signature field.
  3. Records the metadata and marks the new binary isActive = true for its OS.

Because the signature is produced by your server's own certificate authority, an agent can verify the build it receives is genuine before applying it. Binaries are written to disk under the folder set by AgentUpdate:BinariesPath (see Configuration).

OS casing matters

The os value must be exactly Windows or Linux — the binary table is matched on that casing. Anything else is rejected with 400.

The active version#

Exactly one binary per OS is the active version. A freshly uploaded build becomes active automatically, but you can promote any earlier build with POST api/agent-binaries/{id}/activate — that deactivates every other binary for the same OS and flips the chosen one on. Activation is Admin-only.

The active version is what push updates and the agent installer use when no explicit version is given. GET api/agent-binaries/latest/{os} returns the current active binary for an OS (404 if none has been uploaded yet), and the bootstrap installer for an OS is blocked until at least one binary exists for it.

Pushing updates#

To move agents onto a version, push it to a chosen set of agents with POST api/agent-updates/push (Admin-only). The body lists the target agents and, optionally, the version and a force flag:

# Update three agents to the latest active version for their OS
POST api/agent-updates/push
{
  "agentIds": ["a1…", "b2…", "c3…"],
  "targetVersion": null,
  "force": false
}
FieldMeaning
agentIdsAgents to update. At least one is required, or the call returns 400.
targetVersionVersion to install. null (or omitted) means the latest active version for each agent's OS.
forceWhen true, the agent applies the update even if it is already on that version.

The server processes each agent independently:

  1. Looks up the agent to learn its OS and current version, then resolves the correct binary — the named version, or the OS's latest active build when targetVersion is null.
  2. Writes an update-history record and sends the agent an update notification (target version, hash, size, signature, and the force flag) over its existing connection.
  3. Streams the signed binary to the agent over that connection — there is no separate download step for connected agents.
  4. Writes an audit event for the push (see the callout below).

The response summarises the batch: successCount, failedCount, a per-agent results map, and an updateIds map linking each agent to its history record. An agent that is not currently connected can't be reached, so its history row is marked Failed with "Agent not connected" and it is counted as failed — reconnect the agent (or wait for it) and push again.

Pushing an update is treated as remote code execution and is always audited — both successful and failed pushes record the agent, hostname, target version, and who initiated it. See Audit & SIEM.

Automatic updates#

Instead of pushing every release by hand, you can let the server keep agents on the active version. Open Settings → Agents → Updates. The Auto Update section has a check box, Enable auto update for agents. It saves as soon as you tick or clear it, with no restart.

While it is ticked, the server pushes the active version for each OS by itself, at two moments:

There is no timer that sweeps the fleet. Nothing is pushed between those two events.

An automatic push is the same as a manual push to the latest active version, without force. It creates the same update-history record and the same audit event. The user shown is System (auto-update), so you can tell automatic pushes from manual ones in Update History and the audit log.

Which agents are updated#

The retry window#

Under the check box is Retry a failed or stuck auto-update after (minutes). It takes a whole number from 5 to 1440 minutes (one day). The default is 30. The box is greyed out while auto-update is off. A change applies straight away, with no restart.

The window applies only to automatic pushes. A manual push is never blocked. To retry one agent at once, push the update to it by hand.

Activating a build updates the fleet right away

With auto-update on and staging off, uploading or activating a build installs it on every online agent of that OS at once. Each install restarts the agent service. Turn on staged rollout to send a new build to a canary group first, then the rest in waves. The rollout stops on its own if a wave fails too often.

How a Windows agent applies an update#

Once the binary has arrived, a Windows agent checks its SHA-256 hash and, if the binary is signed, the server's signature before it does anything else. If a check fails, the update is reported as failed and nothing on the machine changes. If both pass, the agent hands the install to a Windows scheduled task called HermesUpdate. The agent can't replace its own running executable, so the task does the swap:

  1. The agent registers HermesUpdate to run as SYSTEM with highest privileges and starts it straight away. As a fallback, the task also has a trigger about two minutes later, and Run task as soon as possible after a scheduled start is missed is on. The agent also writes an Information event (ID 101, source Hermes.Agent) to the Windows Application log with the old and new versions.
  2. The task stops the HermesAgent service. It keeps retrying for up to 120 seconds, then ends any Hermes.Agent process that is still running.
  3. It backs up the current Hermes.Agent.exe to updates\backup\ under the agent data directory. The two most recent backups are kept.
  4. It copies in the new files and retries each copy up to five times. When the update is a bundle, this also replaces the remote-screen helper (Hermes.RemoteHelper.exe). If only the helper can't be replaced, the agent is still updated and the helper problem is logged as a warning.
  5. It starts the HermesAgent service on the new version, then deletes itself.

The task has these settings so that it runs on any kind of machine:

Task settingValueWhy it matters
Start only if the computer is on AC powerOffLaptops and tablets on battery still update.
Stop if the computer switches to battery powerOffUnplugging mid-update doesn't stop the install.
If the task is already runningDo not start a new instanceOnly one install runs at a time.
Stop the task if it runs longer than30 minutesA stuck install can't run forever.

What protects the endpoint#

Upgrading older Windows agents (1.2.98 and earlier)

Windows agents at version 1.2.98 or earlier use an older install routine, which service recovery could get in the way of. When you push an update to one of these agents, the server does the pause for you. It saves the agent's HermesAgent recovery settings, sets them to Take No Action, and then sends the update. It restores the saved settings when the update completes, fails, rolls back or times out. The saved settings survive a server restart. If the agent is offline when the server tries to restore them, the server logs an error and doesn't try again. Check that machine's service recovery settings on the Remote Services page.

Update history & status#

Every push creates an update-history record you can review per agent or fleet-wide. Each record tracks the agent, fromVersion → toVersion, who initiated it, timestamps, and a status:

StatusMeaning
PendingUpdate recorded, not yet started.
DownloadingAgent is receiving the new binary.
InstallingAgent is applying the update.
CompletedAgent is confirmed running the target version.
FailedThe update did not complete. For example, the agent was not connected, verification failed, or the update stalled.
RolledBackThe agent reverted to its previous version.

The agent itself confirms completion. Every heartbeat reports the agent's running version. When that version matches an update that is still in flight (Pending, Downloading, or Installing), the server marks the record Completed. Versions are compared by number, so a Windows agent that reports 1.2.98.0 matches an update to 1.2.98. Read history with GET api/agent-updates/history (optionally filtered by agentId, default limit 50); history reads are available to Operator or Admin.

In the console, the Update History table at the bottom of Settings → Agents → Updates updates live. A new push shows up as Pending, and the row moves through Downloading, Installing, Completed or Failed without a page reload. Automatic pushes show System (auto-update) in the Initiated By column.

Updates that never land#

Sometimes an update is still in flight 15 minutes after it was sent, while the agent keeps sending heartbeats on a different version. The server then marks the record Failed with a message like this:

Update not applied: agent is still running 1.2.97 15 minutes after the update to 1.2.98 was sent

A healthy update restarts the agent within a minute or two, so this means the install was lost on the endpoint. The record doesn't stay at Installing forever. The check runs on heartbeats, so it only applies to agents that are online.

Troubleshooting a Windows update#

If a Windows agent's update shows Failed or never changes version, check these on the endpoint:

Where to lookWhat it tells you
C:\ProgramData\Hermes\Logs\HermesUpdate_<yyyyMMdd_HHmmss>.logA full transcript of each install attempt: the service stop, backup, each copy attempt, and any UPDATE FAILED: reason, such as Service did not stop in time or Could not replace Hermes.Agent.exe.
Agent log (C:\ProgramData\Hermes\Logs\hermes-*.log)Hash and signature verification results, and each startup's decision about a waiting update: kept, scheduled again (attempt N of 3), abandoned, or cleaned up.
Task Scheduler → HermesUpdateWhether the install task is waiting, running, or has finished. It is removed after a successful update.
Event Viewer → Windows Logs → Application (source Hermes.Agent, ID 101)When the update was handed to the install task, and which versions were involved.

These paths assume the default agent data directory. See Windows Agent. You can also follow the agent log live from the console with Agent Logs. After you fix the cause, push the update again.

Configuration#

SettingDefaultPurpose
AgentUpdate:BinariesPath<Storage:DataRoot>/AgentBinaries (/data/storage/AgentBinaries on the virtual appliance)Where uploaded agent binaries are stored on the server. Set this only to move this one folder away from the shared storage root. See Data Directories & Backup.
AgentUpdate:AutoUpdateEnabledtrue in the shipped appsettings.json. Treated as false (off) if the key is missing.Turns automatic updates on or off. Same as the Enable auto update for agents check box under Settings → Agents → Updates.
AgentUpdate:AutoUpdateRetryMinutes30The retry window in minutes, from 5 to 1440. A missing or out-of-range value means 30. Same as the Retry a failed or stuck auto-update after (minutes) box.

A manual push works whether auto-update is on or off. Both auto-update values are copied to other servers by Settings Sync along with the other agent settings. See Configuration for how to change these settings.

Replacing AutoUpdateRetryBackoffHours

An earlier setting, AgentUpdate:AutoUpdateRetryBackoffHours, has been deprecated. If only that key is set, the server converts it to minutes (hours × 60) and writes a warning to the server log. The next time the agent settings are saved, the server writes AutoUpdateRetryMinutes and removes the old key.

Roles#

The permission split follows the risk of each action:

ActionRequired role
List / view binaries, view latest, read update historyOperator or Admin
Upload, activate, delete a binaryAdmin
Push an update to agentsAdmin
View the auto-update settingsThe settings.view permission
Turn auto-update on or off, change the retry windowThe settings.manage permission

Callers without the required role receive 403; unauthenticated callers receive 401. See Roles & Permissions.

REST API#

Method & pathPurpose
GET api/agent-binariesList binaries (optional os filter).
GET api/agent-binaries/{id}Get one binary's metadata.
GET api/agent-binaries/latest/{os}Latest active binary for an OS.
POST api/agent-binariesUpload a binary (multipart; server signs it). Admin.
POST api/agent-binaries/{id}/activateMake this binary the active version for its OS. Admin.
DELETE api/agent-binaries/{id}Delete a binary. Admin.
POST api/agent-updates/pushPush an update to selected agents. Admin.
GET api/agent-updates/historyUpdate history (optional agentId, limit).
GET api/agent-updates/history/{agentId}Update history for one agent.
GET api/agent-updates/history/record/{id}A single update-history record.
GET api/settings/agentAgent settings, including autoUpdateEnabled and autoUpdateRetryMinutes. Needs settings.view.
PUT api/settings/agentSave agent settings, including the two auto-update fields. Needs settings.manage.

PUT api/settings/agent replaces the whole agent settings block. Read it with GET, change only the fields you need, and send the whole object back. Secrets that the GET masks are kept as they are. A retry value outside 5–1440 is rejected with 400 and the message AutoUpdateRetryMinutes must be a whole number from 5 to 1440.

The installer-facing endpoints of api/agent-binaries (download, install-script, and ZIP bundle) are covered under Agent Enrollment.

PowerShell#

The Athena module ships cmdlets for the whole binary-and-update lifecycle:

CmdletPurpose
Get-AthenaAgentBinaryList binaries, get one by -Id, filter by -Os (Windows/Linux), or fetch the -Latest active build. Operator or Admin.
Send-AthenaAgentBinaryUpload a build: -Path, -Os (Windows/Linux), -Version, optional -ReleaseNotes. Server signs it. Admin.
Enable-AthenaAgentBinaryMake a binary the active version for its OS, by -Id. Admin.
Remove-AthenaAgentBinaryPermanently delete a binary by -Id. Admin.
Send-AthenaAgentUpdatePush an update: -AgentId (accepts the pipeline), optional -TargetVersion and -Force. Aliased Push-AthenaAgentUpdate. Admin.
Get-AthenaAgentUpdateHistoryRead update history, optionally for one -AgentId, with -Limit (1–500, default 50). Operator or Admin.
Get-AthenaAgentUpdateSettingShow the auto-update settings: AutoUpdateEnabled and RetryMinutes.
Set-AthenaAgentUpdateSettingChange -AutoUpdateEnabled ($true/$false) and/or -RetryMinutes (5–1440). Changes only the values you pass and leaves the other agent settings as they are. Supports -WhatIf. Needs settings.manage. -RetryMinutes needs module 2.12.1 or later.
# Publish a new Windows build and make it the active version
$bin = Send-AthenaAgentBinary -Path "C:\Build\Hermes.Agent.exe" -Os Windows -Version "1.2.42" -ReleaseNotes "Bug fixes"
Enable-AthenaAgentBinary -Id $bin.Id

# Roll it out to every online agent, then review the results
Get-AthenaAgent -Online | Send-AthenaAgentUpdate
Get-AthenaAgentUpdateHistory -Limit 20

# Let the server keep agents current, retrying a stuck update after an hour
Set-AthenaAgentUpdateSetting -AutoUpdateEnabled $true -RetryMinutes 60
Get-AthenaAgentUpdateSetting

See the PowerShell Module reference for full cmdlet details.

Air-gapped by design

Agent versioning never reaches out to the internet. You bring a new build onto the isolated network, upload it to your server, and the server streams it straight to your agents over the connections they already hold. The whole update path stays inside your perimeter. See Air-Gapped Operation.