Files
hermes-control-panel/README.md
T
2026-06-06 02:15:41 -06:00

8.3 KiB

Hermes Control Plane

A local operations console and authenticated AI API gateway for Hermes Agent. Includes admin authentication, per-user API key management, pre/post AI API gateways, and full audit logging.

What It Does

  • Admin-authenticated control plane at port 7843 (login required).
  • Per-user API key management: create, rotate, revoke, delete keys with rate limits and monthly token caps.
  • Pre-Hermes AI API gateway at port 8645 — authenticated proxy for requests sent before Hermes processing.
  • Post-Hermes AI API gateway at port 8646 — authenticated proxy for requests sent after Hermes processing.
  • Full audit logging of prompts and responses with 90-day retention and JSONL download.
  • Lists OAuth/API-key provider pools and account identity data from Codex, Claude, Gemini, and Hermes auth state.
  • Edits Hermes model/fallback configuration.
  • Provides panes for skills, plugins, bundles, MCP, cron, sessions, hooks, memory, kanban, webhooks, profiles, storage, config, tools, insights, security, and system status.

Prerequisites

  • Docker and Docker Compose, or Node.js >= 20 for local runs.
  • PostgreSQL database for admin auth, API key storage, and audit logging.

PostgreSQL Setup

Create the database and a least-privilege user:

CREATE DATABASE hermes_control_plane;
CREATE USER hermes_user WITH PASSWORD 'choose-a-strong-password';
GRANT ALL ON DATABASE hermes_control_plane TO hermes_user;

Migrations run automatically on startup. No manual schema setup is needed beyond creating the database and user.

Set the connection string in your environment:

DATABASE_URL=postgres://hermes_user:password@localhost:5432/hermes_control_plane

Run With Docker Compose

cp .env.example .env
# Edit .env with your values, then:
docker compose up --build -d
docker compose logs -f

Open:

Admin login:        http://127.0.0.1:7843/login
Control plane:      http://127.0.0.1:7843
Pre-Hermes AI API:  http://127.0.0.1:8645/v1/chat/completions
Post-Hermes AI API: http://127.0.0.1:8646/v1/chat/completions

Required environment variables for auth and gateway features:

DATABASE_URL                   PostgreSQL connection string
HERMES_ADMIN_USERNAME          Admin username (default: admin)
HERMES_ADMIN_PASSWORD          Admin password — minimum 16 characters
HERMES_ADMIN_SESSION_TTL_HOURS Session lifetime in hours (default: 8)
HERMES_LOG_RETENTION_DAYS      Audit log retention in days (default: 90)
HERMES_AUDIT_MAX_BYTES         Max bytes per logged request body (default: 65536)

Admin Login

Navigate to http://<host>:7843/login and sign in with HERMES_ADMIN_USERNAME and HERMES_ADMIN_PASSWORD.

The admin password must be at least 16 characters. Sessions expire after HERMES_ADMIN_SESSION_TTL_HOURS hours (default 8).

On first run, set your admin credentials in the environment before starting the container. There is no in-app registration flow.

API Access (Pre/Post)

API keys start with hms_. Each key is scoped to allow the pre gateway, the post gateway, or both.

  • Pre API (http://<host>:8645/v1/chat/completions) — for requests sent before Hermes processing.
  • Post API (http://<host>:8646/v1/chat/completions) — for requests sent after Hermes processing.

Send requests with a Bearer token:

POST /v1/chat/completions
Authorization: Bearer hms_...
Content-Type: application/json

A key not authorized for a gateway returns 403 Forbidden. A revoked or rotated key returns 410 Gone.

API Key Management

From the admin UI, navigate to API Users to:

  • Create a new API user with a display name, gateway access (pre/post), requests-per-minute limit, and monthly token cap.
  • Rotate a key — the old key is immediately invalidated and a new hms_ key is issued.
  • Revoke a key — sets the key inactive without deleting the user record.
  • Delete a user — removes the user and their key permanently.

The plaintext key is shown only once at creation or rotation. Store it immediately.

Audit Logs

Every request proxied through the pre or post gateway is logged, including the full request body and upstream response body. Logs are retained for HERMES_LOG_RETENTION_DAYS days (default 90). Per-entry body size is capped at HERMES_AUDIT_MAX_BYTES bytes (default 64 KB).

Download logs as JSONL from the admin UI or directly:

GET /api/admin/logs/download?api_user_id=<id>
Cookie: hermes_session=...

Response content-type is application/x-ndjson. Each line is a JSON object with request metadata, prompt, and response.

Security Operations

  • Admin password minimum: 16 characters.
  • Session TTL: configurable via HERMES_ADMIN_SESSION_TTL_HOURS (default 8 hours).
  • Rotate API keys regularly. Old keys are invalidated immediately on rotation.
  • Revoke keys for users who no longer need access.
  • Monitor audit logs for unexpected usage patterns.

Deploy With Portainer Git Stack

Use Portainer's Git-backed Stack flow:

  1. Push this repo to Git.
  2. In Portainer, create a Stack from a Git repository.
  3. Set the Compose path to docker-compose.yml.
  4. Add the environment variables from .env.example, adjusted for your server. Include all required variables listed in the Run With Docker Compose section above.
  5. Enable Portainer's auto-update option, either polling or webhook.

Portainer pulls the latest Git version when it redeploys the Stack. A normal Docker container restart does not pull Git or rebuild the image, so use Portainer's webhook/polling redeploy for updates.

HERMES_CONTAINER_USER defaults to 0:0 so the container can write credentials/config into Portainer-created bind directories. If you pre-create the host directories and chown them to UID/GID 1000:1000, set HERMES_CONTAINER_USER=1000:1000.

Recommended persistent host layout on the Portainer host:

/opt/hermes-control-plane/hermes
/opt/hermes-control-plane/codex
/opt/hermes-control-plane/claude
/opt/hermes-control-plane/gemini

The pre/post AI API services both use Hermes' native OpenAI-compatible proxy:

hermes proxy start --provider <provider> --host 0.0.0.0 --port <port>

Set these in Portainer if you want different ports or providers:

HERMES_PRE_AI_API_PORT=8645
HERMES_PRE_AI_PROVIDER=nous
HERMES_POST_AI_API_PORT=8646
HERMES_POST_AI_PROVIDER=nous

Run hermes proxy providers in the Hermes environment to see supported provider names. This Hermes build reports nous and xai.

Backup

PostgreSQL

Back up the control plane database regularly with pg_dump:

pg_dump -U hermes_user hermes_control_plane > hermes_control_plane_$(date +%Y%m%d).sql

This captures all admin sessions, API user records, and audit logs. Restore with psql.

Hermes / Codex / Claude / Gemini State

Back up the bind-mounted directories on the host:

/opt/hermes-control-plane/hermes
/opt/hermes-control-plane/codex
/opt/hermes-control-plane/claude
/opt/hermes-control-plane/gemini

These contain OAuth tokens, auth state, and agent configuration. Archive or snapshot them with your preferred backup method.

Warning: Privacy

Full request prompts and upstream responses are stored in the audit log for up to 90 days. This includes all content sent to and received from the AI provider through the pre and post gateways.

Operators must inform users that their prompts and responses are logged. Do not deploy this system for users who have not been notified of and consented to this logging.

Runtime Requirements

The container is Linux. It can only execute a Linux-compatible Hermes install at:

/home/hermes/.hermes/hermes-agent/venv/bin/hermes

If you are on macOS, your local ~/.hermes venv contains a macOS Python binary and cannot run inside this Linux container. Use a Linux Hermes home, or run the compose bundle on the Linux Hermes host/LXC.

The default .env.example mounts:

  • Hermes state from /opt/hermes-control-plane/hermes
  • Codex auth/config from /opt/hermes-control-plane/codex to /home/hermes/.codex
  • Claude auth/config from /opt/hermes-control-plane/claude to /home/hermes/.claude
  • Gemini auth/config from /opt/hermes-control-plane/gemini to /home/hermes/.gemini

Local Node Run

If Hermes is installed directly on the same OS as Node:

node server.cjs

The default local URL is:

http://127.0.0.1:7843

Useful Commands

npm run check
npm test
docker compose config
docker compose down