Security
Built so you can check it, and honest about its limits.
Hermes Fleet connects directly to infrastructure you choose. It is not a credential relay and needs no shared AIowa account. This page describes the behavior in the app’s source, and the places where the work is not finished.
Approvals
The approval flow is the product’s sharpest edge.
- Origin header. Each card names the gateway, bot, working folder, and session it came from. These values come from the client’s own conversation context, never the wire payload, and read “unknown” when unknown.
- Mandatory full-command review. The inline preview shows at most 4 lines or 240 characters from the end of the command, with an explicit “N more lines” marker. A longer command keeps Approve disabled until you open the full redacted text and finish the review. Deny is never gated.
- Presence check. Approve, sudo-password entry, and secret entry all use one check: Face ID first, then the device passcode when Face ID is unavailable, locked out, or not enrolled. A device with no passcode cannot verify, so those actions stay blocked and the app says to set one.
- Sensitive actions re-check. Enabling YOLO for a session, choosing “Approve always”, and turning App Lock off each require a fresh check with their own prompt. Deny, turning YOLO off, and turning App Lock on never ask.
- Untrusted text is labelled. Reason text supplied by the gateway appears in a block marked “untrusted text”.
- Secrets stay out of the transcript. Sudo and secret entry use a secure field, are marked privacy-sensitive, and are never cached, persisted, logged, or placed in the conversation. Decline sends an empty value.

Your data on the phone
Credentials in the Keychain. Caches that hold nothing secret.
Credentials
Gateway credentials and short-lived connection tokens are stored in the iOS Keychain, not in the app’s ordinary cache or in source files.
Caches and drafts
Cached snapshots are non-secret and stored separately from credentials. Unsent drafts are written with complete file protection, excluded from backup, and bounded to 50 drafts, 20,000 characters each, and 30 days.
Removal and recovery
Removing a gateway purges its cached transcripts, snapshots, drafts, and bridged rooms. If the cache store cannot open, it is quarantined and rebuilt, and saved gateways are salvaged when readable.
App Lock & transport
Reduce casual access. Prefer TLS.
App Lock protects the app with Face ID or your passcode. When App Lock is on and the app becomes inactive, Fleet covers its window with a blank branded screen so conversations stay out of the iOS app-switcher preview. No content is captured or stored for this. Turning App Lock off also turns the cover off.
Endpoints are normalized at the registry boundary, and sensitive URL material is rejected or redacted. TLS-protected endpoints are preferred, especially outside trusted local networks, and Fleet supports trust pins for gateways.
Local biometric or passcode protection reduces casual access. It does not replace device security, gateway authentication and authorization, or transport security. Unsupported or malformed security-sensitive states fail closed instead of falling back to something permissive.
- Approval responses are not cryptographically signed. Gateway-verifiable, request-bound signatures are a tracked upstream proposal (#151), with a device-key design under consideration (#129).
- File protection for the local database’s sidecar files, the store directory, and some staging areas is still in progress (#82).
- Room promotion does not fence the previous authority. You confirm it can no longer commit.
- Cross-gateway rooms are text-only, and cross-gateway @Bot DM delivery is not guaranteed by Fleet.
- The current QR pairing payload carries a scoped gateway credential, so treat the code like a password. Short-lived, certificate-bound pairing is under consideration (#123).
Reporting
Found a vulnerability? Tell us privately.
Do not disclose a suspected vulnerability in a public issue, pull request, screenshot, or log. Use GitHub’s private vulnerability reporting for the repository when available. Never send live credentials, tokens, private endpoints, or personal device data. If a credential is ever exposed, rotate or revoke it first.