SecuFocus
BriefAnnouncements

Hermes Agent 0.22.6: a browser workspace, with access to check

The 2 November stable release brings the Webapp, OS-keychain vault storage, skill locks and new job controls. Desktop update channels still differ.

Generated image: a laptop with a neutral screen, USB security key and blue notebook on a desk in window light.

Generated image · SecuFocus

At a glance

Key points

Hermes Agent 0.22.6 was published as a stable release on 2 November. Its most visible change is the Desktop workspace in a browser, served by your gateway. Before making it remotely reachable, check who can sign in: that browser acts on the gateway’s machine. The release also adds controls for the vault, skills, sessions and scheduled jobs, without enabling every option automatically.

A stable release, not an identical Desktop package everywhere

GitHub dates v0.22.6 to 2 November at 17:18 UTC and does not mark it as a prerelease. The note rolls up work since 0.22.5, while reserving the full cycle notes for 0.23.0. That announcement does not establish that 0.23.0 is available.

The CLI updates through hermes update, the Microsoft Store through the Store, and Docker and Hermes Cloud through the stable or latest image. The note explicitly leaves .exe and .dmg installer apps unchanged until the next bundled release. A stable tag does not mean every Desktop installation receives all features on the same day.

A browser that controls the gateway machine

hermes webapp opens the Desktop workspace in a browser and shares the conversation and execution queue with the same gateway’s other surfaces. Its local sign-in link works once within 60 seconds. Until used, it signs someone in as you: do not paste it into a public ticket or shared chat.

Network access is configured through Desktop Web Access with suitable authentication. The documentation separates local sign-in from account-based remote access. This is not an isolated multi-user service: admitted users on a self-hosted installation act with the machine owner’s authority.

Desktop plugins can load in the tab too, on the host serving the Webapp. Installing them still adds code; it is not an innocuous browser permission. Pinning the reviewed commit and refusing symbolic links or folders over 64 MB does not audit a plugin.

OS-keychain storage changes vault backups too

Keeping the encryption key in the OS keychain is optional. hermes vault key reports its location; migration verifies that the keychain copy opens the vault before removing the key file. File storage remains the default.

A profile backup may then lack what is needed to open the vault on another machine. The documentation calls for migrating the key back to file storage before moving machines. A cloned profile gets its own keychain entry; if the keychain cannot be reached, cloning is refused rather than sharing the original entry.

When a new keychain-mode vault is created on a host without a reachable keychain, it falls back to a file with a warning. Check the actual outcome and keep the key out of chat. This does not replace browser access restrictions or guarantee protection against every process under your account.

Locking a skill is different from pinning it

A per-profile lock prevents autonomous writes to a skill while keeping it readable and loadable. Set it in Desktop Capabilities or through hermes curator lock. Pinning serves curation and does not provide the same write refusal.

The documentation describes checks on editing tools and some commands, with limits for code or scripts that write indirectly. This is not a filesystem sandbox. It helps preserve an approved procedure; it does not turn an agent with terminal access into a process unable to write files.

Stop a run without deleting its schedule

hermes cron cancel targets the current execution; pause suppresses future starts. Cancellation is a request handled at a checkpoint, not a rollback of writes already made. Desktop’s Stop button shows the pending request and then the cancelled state.

Jobs can also pin a timezone and missed-run policy. An interval remains a duration; a cron expression follows a local clock. The ledger distinguishes missed slots and slots collapsed into one catch-up run. A manual fire before the scheduled slot adds a run without consuming that slot or its repeat count. Check the history before retrying an operation with external effects.

Keep the conversation while clearing a model choice

/model reset removes a session-specific model choice and returns to the configured model without discarding history. Refreshing stored prompts also keeps identity and conversation, but rebuilds the prompt on the next turn with a cache miss. These are different operations.

Prepared compaction, compression.prepare_ahead, is optional and off by default. It prepares a summary in the background; we measured neither its benefit nor its cost. For /compress, a selected plugin context engine remains responsible for compression rather than an implicit, interface-dependent path. The auxiliary call may be paid for even when its summary is unused; the option does not cover manual /compress or plugin context engines.

Stopping a reply does not necessarily stop background children

The turn’s Stop control and /stop have different scopes: stopping the turn does not cancel a top-level background delegation; /stop or closing its owning session ends its children. Work that must survive its owner process still needs a durable mechanism.

In messaging, delegation.gateway_mode can join children within the same turn when interim messages are disabled. A backend saved through /delegation normally applies to the next session; applying it immediately rebuilds tools and incurs one prompt-cache miss. None of these choices reduces a delegated profile’s authority.

Choosing an ElevenLabs voice can change the credit rate

The agent can search ElevenLabs voices and choose a voice_id for one call without rewriting the configured voice. It selects from descriptions rather than listening; preview listening is still your job.

Search needs Voices: Read, while synthesis needs Text to Speech. Public Voice Library voices require a paid API plan and some carry a higher credit_rate. A search result therefore establishes neither free use nor validated voice quality.

A pre-inference veto and an output filter have different limits

pre_llm_call can veto a turn before inference. An exception or timeout in that callback is skipped, however: it is not a privacy filter that automatically fails closed.

A separate path, transform_llm_output with hold_stream=True, holds the reply for rewriting and withholds the original if rewriting fails. This happens after inference, so it does not take back data already sent to the provider. Reasoning and tool progress have separate controls.

Migrate a bot without duplicating its routines

hermes migrate and setup add Grok Bot and OpenBot paths. The importer plugin remains separate from core. Routines arrive paused and the source installation remains: check jobs, destinations and access before disabling the old copy and enabling its replacement.

Updates also retry some plugins disabled by download or build failures, depending on the cause and dependency changes. The selected memory provider is preserved. Read the receipt rather than treating a zero exit code as proof that every profile and plugin works.

Check terminal hosts and shared preferences

Each terminal tab retains its gateway even when Sessions switches to another. For URL or cloud connections without a remote shell, an opened terminal runs on This device and says so. Check that indicator before a destructive command: selecting a remote chat does not move an already-open terminal.

Visual preferences are shared by windows and Webapp tabs served by the same machine; credentials, permission grants and drafts do not enter that shared file. Desktop groups add renaming, disbanding, mentions and attachment paste, while each profile appears as its own sidebar section.

Operational changes to check after updating

With persistent Docker and workspace mounting off, a profile’s sessions share its sandbox. Earlier per-workspace directories are retained but no longer used automatically: recover needed files before cleanup. With mounting enabled, workspace-specific separation remains.

Remote configuration is intended for fleets: it replaces config.yaml, fails startup when the configuration plane cannot be read, and supports administrator-locked keys. A personal machine does not need this migration.

The package manager adds resumable downloads and documents damaged dependency-cache recovery. On glibc Linux, servers also limit malloc arenas; that limit does not extend to commands or MCP servers they launch. We infer no measured RAM saving.

Messaging changes are platform-specific too

The note includes Telegram video notes and Slack emoji reactions in thread context. The documentation also describes WhatsApp delivery, read, played and error receipts in logs: a status line is not a new user reply.

Platform permissions still apply. A Telegram group question may also remain unanswered when it is not addressed to the agent; silence alone is not proof of a failure. We sent no messages and tested none of these platforms for this reading.

A local browser can still reach the local network

The tagged documentation explains that disabling security.allow_private_urls does not close every route to a private host. With a local terminal backend, local Chromium can still open localhost or the LAN. Default hybrid routing can also send a private URL to an auxiliary browser on the Hermes host. A tool setting is therefore not network isolation for the machine.

For cloud metadata, the documented refusal checks recognised literal URLs in code or CDP requests that fetch them. It covers neither a URL assembled at runtime, subsequent page redirects or requests, nor the terminal. CDP parameters that fetch nothing, such as typed text or a cookie scope, do not pass through this check. On a cloud server, the documentation also calls for network-level restrictions: the setting alone is not a complete boundary.

On Ubuntu 23.10 and later with AppArmor’s user-namespace restriction, the launcher prefers the root-owned chrome-sandbox helper. If that setup also fails, it can start without the Chromium sandbox and prints a notice. Installing an AppArmor profile for a code path your account can modify widens that path’s rights; it is not a neutral repair to apply blindly. These instructions concern the documented build-and-launch route, not availability in every .exe or .dmg installer.

A shared dashboard token carries its full authority

The bundled session-token provider can authenticate dashboard REST and WebSocket access when a deployment token is provisioned. It does not add an interactive browser login. Anyone holding that token receives full dashboard access, with no individual identity behind the shared secret.

Keep it in a secret manager and rotate it through deployment: saved client copies become invalid and must be replaced. For shared or internet-facing services, the documentation recommends Nous-account or OIDC authentication instead. We compared the document and the tagged module; we did not provision a token or test authentication.

An automatically ended session remains resumable

A local CLI, TUI or Desktop session whose last client disappears can be marked ended after a default 300-second grace period. After a restart, the documented path waits at least six hours since its last activity. An active turn keeps running; a session with a pending interrupted turn stays open. Ending does not delete the conversation: the next message can reopen it with the same identifier.

Storage optimization also keeps watching for other processes holding the database and yields between chunks so their writes can proceed, making the operation slower. That does not make --force harmless. Follow the holder diagnostics and keep recovery files; do not delete state.db-wal to speed up maintenance.

Discord buttons and macOS permissions: identify the right process

On Discord, the interactive-button timeout is separate from the command-approval wait. The former defaults to 300 seconds, with a 30-second minimum. A card retires when its own request is answered, cancelled or expires; extending the view does not extend that request. Missing buttons alone therefore do not prove that the underlying wait has ended.

On macOS, a gateway started without an installed service can use a one-off launchd job to retain LAN access after its launching application exits. That job is neither installed for the next login nor automatically restarted. File-access prompts can then name osascript rather than Hermes. Match the prompt to the process you launched; do not approve an unexpected dialog on its displayed name alone.

Recovery can repeat an effect that already happened

In Kanban, an uncertain admission retains its fence while its bound interpreter may still be running. But an attempt whose execution is established to have ended can return to the queue for another attempt. The tagged documentation says to inspect effects, then complete or block the card before resolving an unknown admission if repetition must be avoided. Unblock only when another attempt is intended: a missing report does not prove no write occurred.

Bot Screen has a different stop condition: an unused screen closes after 30 minutes by default, even if the gateway that started it never returns. Human takeover is retained while the viewer shows activity. With no use for four idle windows, and at least ten minutes, the screen can be stopped and control handed back to the agent. A disconnected viewer therefore does not reserve it indefinitely. The window is configurable; it does not describe stopping every bot task.

A secret cache is not a diagnostic attachment

The tagged documents place Bitwarden and 1Password caches and Photon state at the relevant Hermes home’s root, not its cache or runtime subdirectories. Protect bws_cache.json, bws_cache.enc.json, op_cache.json and photon-sidecar.json. The 1Password cache contains resolved secret values; the Photon file contains the sidecar’s port and token. Do not attach them to a support ticket to troubleshoot startup.

Bitwarden’s encrypted cache remains optional and off by default. Any permitted stale-cache fallback is limited to network failures or timeouts within the configured age; authentication failure does not use it. For 1Password, setting cache_ttl_seconds to 0 disables cache reads and writes. These controls are neither an audit of your installed files nor permission to delete earlier copies without checking their role.

Ignoring an unreadable .env has a specific prerequisite

The managed path treats an existing but unreadable profile .env as absent, with a warning, only when managed configuration pins a non-empty terminal.backend. Without that condition, the read error still stops Hermes. This covers cases such as a sandbox launcher passing keys through the environment; it is not a reason to make the file readable by everyone to silence the error.

Do not confuse this rule with a vault: the documented managed .env in /etc/hermes is readable by local users. The documentation therefore reserves it for shared, non-sensitive values. Check permissions and the managed path; this management feature is not a sandbox the agent can never escape.

Configuration: recognise a changed file and the plugin reading a key

The 0.22.6 tag’s code and documentation add a content digest to configuration-cache signatures for recent writes. Rapid rewrites of equally sized files should no longer be distinguished only by their timestamp. The check also considers ctime when a copy preserved an older mtime. This concerns configuration reloading, not proof that a provider accepted a rotated key; check the connection separately and never attach secret files to a diagnostic report.

An active plugin can declare the precise Hermes configuration paths it reads through config_keys. Those paths become recognised by hermes config get/set, including for the selected memory provider. Declarations require at least two segments and do not override keys already defined by core. They neither open an entire section to arbitrary keys nor activate a disabled plugin. These rules were read in the tag and code; SecuFocus tested no installation or key rotation.

Nix, dependency cleanup and Bedrock timeouts

With Nix, extraDependencyGroups adds dependency groups to those shipped by the selected package; it does not replace them. A smaller installation requires a smaller package or an explicit change to defaultDependencyGroups. Dependencies are resolved at build time, not installed later into the read-only Nix store. The development shell also supplies a self-contained editable Python environment without relying on the calling terminal’s PYTHONPATH.

Cleanup can reclaim dependency state for a checkout that is missing outside the data root and worktree directories after 14 days without use by default. worktrees.install_state_retention_days is read from the root profile because profiles share these installations; 0 disables this expiry. A held install lock or generation lease protects the state. This does not replace a backup of your work, and SecuFocus has not run cleanup.

On AWS Bedrock, the timeout resolved for the active model applies to socket reads in Converse or the AnthropicBedrock client. A model switch or fallback uses the new model’s timeout; connection timeouts remain separate. This setting therefore does not bound the total duration of a call. We compared these documents with the stable tag’s code, without building Nix or making a billed Bedrock request.

What was checked for this reading

We compared release notes with documentation in the tagged commit rather than assigning every current main-branch document to 0.22.6. The live documentation remains the reference for the latest behaviour and can move ahead after publication.

SecuFocus installed neither the release nor its plugins and tested no vault migration, remote sign-in, billing or real-device compatibility. Before restoring consequential writes, check the update channel, receipt, active gateway and a task with non-sensitive data.

Check and explore

Sources for this article

Numbers connect each reference to the passages that use it. Dates show when the documentation was consulted.

This article draws on the sources above. The exercises are for you to try on your devices; SecuFocus does not present them as tests carried out by its editorial team. Interfaces and features can change. Method and corrections.

Cite this article

Keep this reference with the article when you save or share it.