Skip to main content

Configuration reference

Hermeum is configured entirely through HERMEUM_* environment variables. The Hermeum reads them once at startup via a Zod schema (apps/app/src/server/libs/config.ts); invalid or missing required values fail fast with a parse error before the server binds a port.

The Helm chart maps these to secrets.* (sensitive) and config.* (non-sensitive) values — see Installation. Every variable below is optional unless marked required.

Environment variables​

Required variables must be set or the Hermeum pod refuses to start. All others fall back to the defaults listed here.

Core​

VariableDefaultDescription
HERMEUM_DATABASE_URL—Connection URL for the Hermeum database. For sqlite use file:/path/to/db.sqlite; for postgres use a postgres:// URL. See Database.
HERMEUM_DATABASE_DIALECTsqliteDatabase backend dialect. One of sqlite, postgres. Must match the scheme of HERMEUM_DATABASE_URL.
HERMEUM_KUBERNETES_NAMESPACEhermeumKubernetes namespace where HermesAgent custom resources are reconciled. Hermeum must have RBAC to read/write this namespace.
HERMEUM_CONFIG_PATH./config.yamlPath to the Hermeum instance config file. See Instance config for the schema.
HERMEUM_HERMES_DOCS_PATH./docsPath to the hermes docs directory, scanned recursively by the docs file adaptor.
HERMEUM_LOG_LEVELinfoLog verbosity. One of debug, info, warn, error.

Agent image​

The container image emitted into every HermesAgent CR's spec.image.

VariableDefaultDescription
HERMEUM_HERMES_IMAGE_REPOSITORYnousresearch/hermes-agentContainer image repository for the Hermes agent. Omit the registry host for Docker Hub, or include it (e.g. ghcr.io/hermeum/hermes-agent) for other registries.
HERMEUM_HERMES_IMAGE_TAGv2026.9.21Container image tag for the Hermes agent. Pin to a specific release for reproducible agent pods.

Agent-session telemetry​

Every agent managed by Hermeum automatically installs the hermeum plugin (via the operator's hermes plugins install), which forwards agent-session events to Hermeum's plugin-protocol endpoint. The install is pinned to a fixed Hermeum commit shipped with the app, so it does not drift with the repository's default branch. The endpoint URL is derived from the base URL below; it is injected as HERMEUM_PLUGIN_BASE_URL into the agent's workspace .env and always wins over a user-set agent env var of the same name. The endpoint is authenticated: at agent-create time Hermeum provisions each agent with a per-agent ingest token (injected as the sensitive HERMEUM_PLUGIN_TOKEN env var, its SHA-256 digest stored in the app database) and rejects every request — including the health probe — without a valid token. Archiving an agent revokes its token. Nothing here is operator-configurable; the token lifecycle is fully automatic.

VariableDefaultDescription
HERMEUM_PLUGIN_BASE_URLhttp://hermeum:3000Base URL agents use to reach the Hermeum app. The hermeum plugin posts events to <pluginBaseUrl>/plugin/trpc/agentSession.agentSessionEvents. The Helm chart defaults this to the app's in-cluster Service DNS (http://<release-name>:<config.port>); override for cross-namespace or proxied routes.
HERMEUM_AGENT_SESSION_RETENTION_DAYS90Retention window, in days, for agent-session telemetry. A scheduled job (six-hour cycle) deletes every session whose most recent event is older than the window, together with all of its events — sessions are pruned whole, never partially. Set 0 to disable retention and keep every session forever.

Auth​

Better Auth email/password, allowed email domains, and outgoing SMTP. Better Auth's own secret (BETTER_AUTH_SECRET) is provided via Helm secrets.* and is not a HERMEUM_* variable.

VariableDefaultDescription
HERMEUM_SMTP_URL—SMTP server URL for outgoing email (e.g. smtps://user:pass@smtp.example.com:465). Optional.
HERMEUM_SMTP_FROM—From address for outgoing email, e.g. Hermeum <no-reply@example.com>. Set it when HERMEUM_SMTP_URL is configured — most SMTP providers reject or spam-filter messages without a From header. Optional.
HERMEUM_ALLOWED_EMAIL_DOMAIN—Restrict sign-ups to this email domain (e.g. example.com). Optional; when unset, any domain is accepted.

AI config generator​

The AI config generator uses an OpenAI-compatible chat completion endpoint to draft agent config.yaml blocks from natural-language prompts.

VariableDefaultDescription
HERMEUM_OPENAI_MODELgpt-6.1-solModel id passed to the completion call. Must be a model the configured endpoint serves.
HERMEUM_OPENAI_BASE_URL—Override the OpenAI API base URL. Point this at any OpenAI-compatible gateway (vLLM, Ollama, Azure OpenAI, etc.). When unset, the OpenAI default is used.
HERMEUM_OPENAI_API_KEY—API key for the OpenAI-compatible endpoint. Required when targeting the hosted OpenAI API; may be unused for local gateways.

Per-agent ingress​

When HERMEUM_AGENT_INGRESS_BASE_HOSTNAME is set, Hermeum emits an Ingress per agent that routes each enabled HTTP platform on its own host <agent-id>.<platform-label>.<base hostname> (api-server → api, webhook → hooks, teams → teams) — or, with HERMEUM_AGENT_INGRESS_FLATTEN_HOSTS=true, <agent-id>-<platform-label>.<base hostname> — with each host mapped wholesale to the platform's Service port. When it is unset, no ingress is generated.

VariableDefaultDescription
HERMEUM_AGENT_INGRESS_BASE_HOSTNAME—Base hostname for per-agent ingresses; each HTTP platform is exposed at <agent-id>.<platform-label>.<base> (api / hooks / teams) — or <agent-id>-<platform-label>.<base> with HERMEUM_AGENT_INGRESS_FLATTEN_HOSTS=true. Unset = no ingress generated.
HERMEUM_AGENT_INGRESS_FLATTEN_HOSTSfalseFlatten agent ingress hosts to a single DNS level: <agent-id>-<platform-label>.<base> instead of <agent-id>.<platform-label>.<base>. One wildcard record/cert *.<base> then covers every agent and platform.
HERMEUM_AGENT_INGRESS_SCHEMEhttpPublic URL scheme advertised for agent ingresses. Display-only — it does not drive the emitted tls block; TLS is governed by HERMEUM_AGENT_INGRESS_TLS_SECRET_NAME.
HERMEUM_AGENT_INGRESS_CLASS_NAME—Ingress controller class name set on generated ingresses (spec.ingressClassName). Omitted from the CR when unset.
HERMEUM_AGENT_INGRESS_TLS_SECRET_NAME—TLS secret name for controller-terminated TLS. When set, the ingress emits a tls block with this secret; when unset, no tls block is emitted (covers plain HTTP and load-balancer-terminated TLS).

See Per-agent ingress and TLS for end-to-end TLS topologies.

Web server​

Hermeum's own HTTP(S) listener.

VariableDefaultDescription
HERMEUM_PORT3000Port the web server listens on.
HERMEUM_HMR_PORT3001Port used by Vite's HMR websocket in dev. Ignored in production.
HERMEUM_TLS_CERT_FILE—Path to the web TLS cert file (PEM). When set with HERMEUM_TLS_KEY_FILE, the web server serves HTTPS on HERMEUM_PORT.
HERMEUM_TLS_KEY_FILE—Path to the web TLS key file (PEM). Pair with HERMEUM_TLS_CERT_FILE.

Webhook​

The mutating admission webhook's HTTPS listener. It only starts when both HERMEUM_WEBHOOK_TLS_CERT_FILE and HERMEUM_WEBHOOK_TLS_KEY_FILE are set; otherwise the webhook is not served.

VariableDefaultDescription
HERMEUM_WEBHOOK_PORT8443HTTPS port for the mutating admission webhook. Only used when the webhook TLS cert and key are set.
HERMEUM_WEBHOOK_TLS_CERT_FILE—Path to the mutating webhook TLS cert file (PEM). Pair with HERMEUM_WEBHOOK_TLS_KEY_FILE to start the webhook listener.
HERMEUM_WEBHOOK_TLS_KEY_FILE—Path to the mutating webhook TLS key file (PEM). Pair with HERMEUM_WEBHOOK_TLS_CERT_FILE.

See Mutating webhook for how the webhook is wired into the cluster and how its caBundle gets populated.

Telemetry​

Hermeum's telemetry adaptor logs to the console and reports a lightweight deployment heartbeat (deployment.heartbeat event) to a Hermeum-owned PostHog project so the team can count running self-hosted servers and track version adoption. The heartbeat is captured as a PostHog event on startup and then hourly, and carries only anonymous deployment-level properties: the deployment id, hosting, the app version, and the database dialect. The heartbeat is always reported and is not governed by the log-mirroring toggle below.

Optionally, console log messages can also be mirrored to PostHog Logs via the official PostHog OpenTelemetry (OTLP) integration.

VariableDefaultDescription
HERMEUM_POSTHOG_API_KEYHermeum's project tokenPostHog project API key (phc_...), baked in as the default so heartbeats work out of the box. The token is public by design — override to report to a different PostHog project.
HERMEUM_POSTHOG_HOSThttps://us.i.posthog.comPostHog ingestion host.
HERMEUM_DEPLOYMENT_ID—Stable identifier for this deployment, used as the heartbeat's distinct id. When unset, a random id is generated per process boot — set this (e.g. to the Helm release name) for accurate server counts across restarts.
HERMEUM_TELEMETRY_DISABLEDfalseSet to true to disable log mirroring to PostHog Logs. Console output is always enabled; the deployment heartbeat event is not affected.

RBAC notes​

Hermeum runs as a Kubernetes controller for HermesAgent CRs inside HERMEUM_KUBERNETES_NAMESPACE. The chart's ServiceAccount grants the following scoped permissions:

  • hermesagents (custom resource): full CRUD within the configured namespace — Hermeum creates, patches, and finalizes agent CRs.
  • secrets: read/write within the namespace, used to materialize per-agent image-pull secrets and TLS material referenced by ingresses.
  • ingresses (networking.k8s.io): create/update/delete within the namespace when per-agent ingresses are enabled (HERMEUM_AGENT_INGRESS_BASE_HOSTNAME set).
  • pods / pods/log: read, for status display and log streaming from agent pods.

When per-agent ingress is disabled (no base hostname), the ingresses grant is unused in practice. If you deploy the chart into a namespace you do not own and instead grant a narrower Role manually, ensure the four resource groups above are still covered or the corresponding features will return RBAC forbidden errors at runtime.

The mutating admission webhook is served by the same pod but on a separate port (HERMEUM_WEBHOOK_PORT); it is authorized through the MutatingWebhookConfiguration's clientConfig.service path, not through the pod ServiceAccount.