@hivemagnus/magnus-server
v2.3.7
Published
Magnus server: the fleet control plane API (Hono, PostgreSQL, Redis) for nodes running magnus-agent, with optional Hive IAM, Hive Router, HiveMem, Hermes Agent and external security console integrations.
Maintainers
Readme
@hivemagnus/magnus-server
The Magnus server is the control plane of a Magnus fleet. It is a Hono API
server backed by PostgreSQL and Redis that Linux hosts running
@hivemagnus/magnus-agent report to, and that the
Magnus dashboard talks to.
It keeps the fleet inventory and desired state, ingests agent heartbeats, health snapshots and logs, dispatches signed commands, cron jobs, file syncs and skill installs through a durable queue, and records every change in an append-only audit log. Optional modules add anomaly detection and remediation plans, rollouts, webhooks, an AI fleet assistant, Hermes Agent and Ardent management, and Security Fusion.
Requirements
- Node.js
^24.22.1 || ^26.13.0 - PostgreSQL 15 or later
- Redis 7 or later
- A TLS certificate for production (cleartext HTTP is a loopback-only development opt-in)
Install
npm install -g @hivemagnus/magnus-server
magnus-server --helpThe package ships compiled JavaScript, the generated Prisma client, the Prisma schema and every migration, so it needs no install-time code generation.
Configure
All configuration comes from environment variables. Start from the documented example:
mkdir -p ~/.magnus && cp "$(npm root -g)/@hivemagnus/magnus-server/.env.example" ~/.magnus/server.env
chmod 600 ~/.magnus/server.env
# fill in DATABASE_URL, REDIS_URL, TLS paths and the required secrets
# (one `openssl rand -hex 32` each; every secret must be different)magnus-server env-schema --format table lists every documented variable and
magnus-server env-schema prints the same list as JSON.
Required: DATABASE_URL (in production), REDIS_URL, API_SECRET,
JWT_SECRET (unless Hive IAM is configured), NODE_MANAGER_SECRET,
AUDIT_HMAC_SECRET, RESULT_SIGNING_SECRET, LOG_INGEST_SIGNING_SECRET,
CREDENTIAL_ROTATION_KEY, METRICS_TOKEN, WEBHOOK_ENCRYPTION_KEY, and in
production TLS_CERT_PATH / TLS_KEY_PATH. The server refuses to start while
any is missing; there are no fallback secret values.
Webhooks are refused until WEBHOOK_ALLOWED_ORIGINS lists the exact HTTPS origins
they may target, as a comma-separated list.
Local data (audit logs, credential rotation state, uploaded backups) lives
under MAGNUS_HOME, default ~/.magnus.
Run
magnus-server check --env-file ~/.magnus/server.env # validate env, reach PostgreSQL and Redis, list integrations
magnus-server migrate --env-file ~/.magnus/server.env # apply migrations and base data
magnus-server start --env-file ~/.magnus/server.env # MAGNUS_AUTO_MIGRATE=true: back up and migrate first| Command | Purpose |
| --- | --- |
| start (default) | Start the API server. With MAGNUS_AUTO_MIGRATE=true it first dumps the database and applies pending migrations under an advisory lock. --migrate applies them without a dump. |
| check | Validate configuration, connect to PostgreSQL and Redis, report pending migrations, available updates and enabled integrations (--format json for tooling). Exits non-zero on a problem. |
| migrate | Run prisma migrate deploy with the packaged schema and migrations, then create the base rows (system actor, sentinel nodes, starter library). Idempotent. |
| migrations | List applied and pending migrations with their impact (fast, slow, one-way). |
| backup | Dump PostgreSQL (pg_dump -Fc) into MAGNUS_BACKUP_DIR and print the restore command. |
| upgrade, rollback | Upgrade or roll back the magnus init project this server was installed into (runs magnus upgrade; see UPGRADING.md). |
| agents upgrade | Upgrade agents to the version this server ships (--to, --nodes, --dry-run). |
| env-schema | Print the documented environment variables (--format json or table). |
| version, help | Print the version or usage. |
--env-file <path> may be repeated. Variables already set in the process
environment take precedence, and empty values count as unset.
The API is served under /api/v1, interactive documentation at /api/docs
(OpenAPI 3.1 JSON at /api/docs/openapi.json), and Prometheus metrics at
/metrics (bearer METRICS_TOKEN).
Docker Compose
docker/compose.yml runs magnus-server with PostgreSQL
and Redis. The image is built from the monorepo root with
Dockerfile: it builds and npm packs the server and its
workspace dependencies, then installs those tarballs exactly as an npm user
would.
cp services/control-api/.env.example services/control-api/docker/.env # set POSTGRES_PASSWORD, REDIS_PASSWORD and the secrets
docker compose -f services/control-api/docker/compose.yml --env-file services/control-api/docker/.env up -d --buildCompose refuses to start while a required secret is missing. The server
listens on https://127.0.0.1:4000; without a mounted certificate it
generates a self-signed one for MAGNUS_TLS_HOSTNAMES (default localhost)
in its data volume, which is meant for evaluation only. To use a real
certificate, mount it and set TLS_CERT_PATH and TLS_KEY_PATH.
bash services/control-api/scripts/check-compose.sh brings the stack up with
throwaway secrets, checks it end to end and removes it again.
Optional integrations
Every integration is off until it is configured; the server starts and runs
without any of them. magnus-server check prints which are on.
| Integration | What it adds | Environment |
| --- | --- | --- |
| Hive IAM | RS256 access tokens issued by Hive IAM replace locally issued JWTs | IAM_CORE_URL, IAM_TOKEN_ISSUER, IAM_TOKEN_AUDIENCE |
| Fleet gateway | The browser web terminal, through a separate service that holds the SSH key; also answers console drain challenges | FLEET_GATEWAY_URL, FLEET_GATEWAY_TOKEN_SHA256, RESOURCE_ENROLLMENT_DASHBOARD_PARTICIPANT |
| Hive Router | OpenAI-compatible model routing for managed Hermes Agents | MAGNUS_ROUTER_URL (alias HIVE_ROUTER_URL), MAGNUS_ROUTER_MODEL, MAGNUS_ROUTER_API_KEY, HIVE_ROUTER_HEALTH_URL |
| HiveMem | Shared agent memory for Hermes Agents and operational lessons | HIVEMEM_URL, HIVEMEM_TOKEN, MAGNUS_LESSONS_HIVEMEM_URL, MAGNUS_LESSONS_HIVEMEM_TOKEN |
| Ardent skill install | Installs HiveSkills catalog releases onto Ardent profiles, checked against the catalog digest (docs) | MAGNUS_ARDENT_HIVESKILLS_URL |
| Ardent New Agent | Per-agent HiveMem credentials for new and existing Ardent profiles, and Emberpath model aliases (docs) | MAGNUS_ARDENT_HIVEMEM_URL with MAGNUS_ARDENT_HIVEMEM_CLIENT_ID, _CLIENT_SECRET, _TOKEN_URL (or MAGNUS_ARDENT_HIVEMEM_ENROLLMENT_TOKEN and MAGNUS_ARDENT_HIVEMEM_WORKSPACE_ID), optional MAGNUS_ARDENT_HIVEMEM_SCOPE, MAGNUS_ARDENT_HIVEMEM_WORKSPACE_ID, MAGNUS_ARDENT_HIVEMEM_AGENT_URL, MAGNUS_ARDENT_HIVEMEM_CREDENTIAL_HOURS, MAGNUS_ARDENT_EMBERPATH_URL |
| Security Fusion (local) | Security cases, evidence and signed receipts in this server | SECURITY_FUSION_MODE=local, SECURITY_FUSION_RECEIPT_SIGNING_KEY, optional SECURITY_FUSION_EVIDENCE_DIR, SECURITY_FUSION_CONTAINMENT_COMMAND, SECURITY_FUSION_MATTERMOST_* |
| External security console | Exports observations to an external console; local Security Fusion routes answer 410 with the console URL | SECURITY_FUSION_MODE=remote, MAGNUS_SECURITY_CONSOLE_URL, SECURITY_FUSION_API_URL, SECURITY_EXPORT_ENABLED, SECURITY_EXPORT_SECRET, SECURITY_SUMMARY_TOKEN, SECURITY_INVENTORY_TOKEN_SHA256, SECURITY_BACKUP_TOKEN_SHA256 |
| Hermes Agent plugin API | Endpoint-scoped plugin credentials (read, operator) and the signed approval bridge | MAGNUS_PLUGIN_API_ENABLED=true, MAGNUS_PLUGIN_READ_TOKEN_DIGESTS_JSON, MAGNUS_PLUGIN_OPERATOR_TOKEN_SHA256, optional MAGNUS_APPROVAL_BRIDGE_CONSUMER, APPROVAL_SIGNER_PUBLIC_KEY_*, APPROVAL_*_ACTOR_SHA256 |
| Hermes registry sync | Imports the bundled skill catalogue and tracks plugin sources; staged deployments to named hosts | MAGNUS_HERMES_REGISTRY_ENABLED=true, MAGNUS_REGISTRY_DEPLOY_HOSTS, MAGNUS_REGISTRY_SUBMIT_ONLY_HOSTS |
| Observability collector | Read-only credential for an external collector | MAGNUS_COLLECTOR_TOKEN_SHA256 |
| AI fleet assistant | Ollama, llama.cpp, OpenAI, OpenRouter or Anthropic model profiles | OLLAMA_URL, LLAMACPP_URL, OPENAI_API_KEY, OPENROUTER_API_KEY, ANTHROPIC_API_KEY |
| Agent discovery | Agents self-register | ENABLE_AGENT_DISCOVERY=true, AGENT_DISCOVERY_SECRET |
| Resource leases | Durable node and shared-resource lease coordination | MAGNUS_RESOURCE_LEASES_ENABLED=true |
For an isolated restore, set HIVE_REHEARSAL=true and
MAGNUS_AUTO_MIGRATE=false. The API keeps read access but holds mutations,
terminal WebSockets, queue activation, host contact, collectors, retention,
reconciliation, updates and catalogue imports. Existing queued work remains
dormant. Run explicitly reviewed migrations separately before starting the
candidate. magnus-server verify-migrations verifies the exact packaged,
completed migration checksums using read-only queries; pending, failed, missing,
unknown or changed migrations fail. It does not initialize or repair the database.
Credentials for services that call Magnus are stored only as SHA-256 digests.
SSH helpers require SSH_HOST_KEY_PINS_FILE before they open a connection.
Set it to an operator-owned JSON file mapping lowercase hostname:port keys
to arrays of OpenSSH SHA-256 fingerprints, for example:
{"node-1.example.com:22": ["SHA256:AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"]}Replace the example with fingerprints verified through a trusted channel. Unknown destinations and changed keys fail before authentication. Multiple pins permit a reviewed host-key rotation; remove the old pin afterward. This setting does not enable the retired browser deployment routes.
Interoperating with older components
Every switch below is off or set to current behaviour by default. Set them only while older clients, signers or scripts still talk to this server.
| Variable | Default | Purpose |
| --- | --- | --- |
| MAGNUS_APPROVAL_ASSERTION_DOMAINS | magnus.approval-assertion | Comma-separated signature domain prefixes accepted for signed approval decisions (the signed message starts with <prefix>.v<N>). Add a legacy signer domain, for example magnus.approval-assertion,legacy.approval. The first entry is preferred. Allowed characters: a-z, 0-9, . and -. |
| MAGNUS_ROUTE_ALIASES_JSON | unset | JSON object mapping legacy /api/v1 path prefixes to current ones, for example {"/api/v1/resource-leases/old-name/admission": "/api/v1/resource-leases/admission"}. Requests are rewritten before routing, so authentication, endpoint scopes, rate limits and audit see the current path. Aliases cannot chain or contain ./.. segments. |
| MAGNUS_WEBHOOK_TYPE_ALIASES | unset | Comma-separated legacy=format pairs, for example legacy-chat=mattermost, so webhook endpoints stored or submitted under an older type name keep their delivery format. New and edited endpoints store the current format. |
Older Hermes Agent plugins also need MAGNUS_PLUGIN_API_ENABLED=true, and an
older approval bridge needs MAGNUS_APPROVAL_BRIDGE_CONSUMER. See the
changelog for renamed variables.
Develop
From the repository root:
npm ci
npm --workspace @hivemagnus/magnus-contracts run build
npm --workspace @hivemagnus/magnus-skills run build
npm --workspace @hivemagnus/magnus-server run db:generate
npm --workspace @hivemagnus/magnus-server run typecheck
npm --workspace @hivemagnus/magnus-server test # unit tests
npm --workspace @hivemagnus/magnus-server run buildnpm run dev (in this directory) runs the server with tsx watch. Without
DATABASE_URL, development connects to postgresql://[email protected]:5432/magnus
(role magnus, no password); production always requires DATABASE_URL. Set
ALLOW_INSECURE_HTTP=true to serve cleartext HTTP on loopback while
developing.
Integration tests need a disposable PostgreSQL database whose name starts with
magnus_ideas_ and a Redis server:
export TEST_DATABASE_URL=postgresql://magnus:<password>@127.0.0.1:5432/magnus_ideas_test
export DATABASE_URL=$TEST_DATABASE_URL REDIS_URL=redis://127.0.0.1:6379
npm --workspace @hivemagnus/magnus-server run db:migrate:deploy
npm --workspace @hivemagnus/magnus-server run test:integrationSchema changes go in a new Prisma migration (npm run db:migrate); applied
migrations are never edited.
License
Apache-2.0. See LICENSE.
Cindertrace
Embedded Security Fusion is retired. See migration and response configuration. CINDERTRACE_RESPONSE_SECRET, CINDERTRACE_RESTART_ALLOWLIST, and CINDERTRACE_PROTECTED_TARGET_IDS configure the optional managed response adapter.
HiveSkills execution bridge
MAGNUS_HIVESKILLS_DEPLOYMENTS_JSON maps each registry to a dedicated token SHA-256
and exact logical-target bindings (nodeId, agentTarget). This optional integration
accepts only POST/GET /api/v1/hiveskills/jobs/:id, with exact publication digests
and a durable registry-owned UUID. It cannot submit general commands. Nodes must
already have completed managed resource enrollment. Repeated requests inspect the
original signed receipt; they never dispatch an admitted job again. Unknown outcomes
retain their node ownership for explicit reconciliation.
Each node explicitly configures MAGNUS_AGENT_HIVESKILLS_TARGETS_JSON: registry ID,
registry target, owner, home, Hermes profile directory, protected environment-file
path, root-owned pinned sync script, Node executable and optional caFile trust bundle. The trust bundle is passed at Node startup; target bearer credentials remain in the protected environment file. The owner-scoped native
handler runs that fixed product client as the configured owner, with sanitized
environment and bounded output. No infrastructure or native target credential is
sent by the browser or included in a job body. The client receives the frozen
approved publication and independently checks archive origin, digest and local
Hermes compatibility. A non-root agent may synchronize its own explicit profile. Changing owner or running as root requires privileged mode. No SSH or Docker socket is used by this path.
