36 Commits

Author SHA1 Message Date
Zachariah K. Sharma f473be4033 feat: add authenticated URL-mode MCP servers from Control Panel
Add an optional auth-token (bearer) field and a custom-headers textarea to
the MCP 'Add server' pane. URL-mode servers are now registered by writing
hermes config directly via the venv's config helpers (save_env_value +
save_config) instead of shelling into the interactive, network-probing
'hermes mcp add --url' flow that hung/504'd on auth challenges.

- Token is stored in ~/.hermes/.env (mode 600) and referenced in config.yaml
  as 'Authorization: Bearer ${MCP_<NAME>_API_KEY}' — never plaintext config.
- Registration is non-blocking: no live probe, so a slow/unreachable server
  can't hang the request.
- Add a per-server 'Test' button (POST /api/mcp/test -> hermes mcp test).
- Contract tests for the new fields, payload, no-probe path, and test route.
2026-06-10 21:19:05 -06:00
Zachariah K. Sharma be9c9ae6d4 Fix API key creation, add expiration presets and defaults
- Fix payload field names (snake_case → camelCase) so creates/updates
  actually reach the server correctly
- Fix reveal dialog not opening after create/rotate (plain_key → plaintextKey)
- Add GET /api/admin/api-users/:id so the edit button loads existing data
- Show server errors inline in the dialog instead of silently succeeding
- Add 30d/90d/1y/Never expiration preset buttons
- Default new keys to pre+post access, 60 rpm, 1M monthly tokens
- Surface errors on revoke, reactivate, rotate, and delete actions
- Add client-side validation for required numeric fields
- Add contract tests covering all the above fixes
2026-06-10 00:05:32 -06:00
Zachariah K. Sharma e324b2237a Fix Codex default model 2026-06-09 00:59:20 -06:00
Zachariah K. Sharma c645027805 Route APIs through shared Hermes gateway 2026-06-08 20:47:15 -06:00
Zachariah K. Sharma ef7da651ac Support browserless Claude and Gemini OAuth 2026-06-08 11:59:45 -06:00
Zachariah K. Sharma 2154e8e534 Use native Codex device OAuth flow 2026-06-08 11:10:31 -06:00
Zachariah K. Sharma d5c86c71c9 Fix mounted auth deletion semantics 2026-06-08 09:36:13 -06:00
Zachariah K. Sharma 6bec286d4f Fix deleting mounted provider auth 2026-06-08 08:41:01 -06:00
Zachariah K. Sharma 0c84fa9e4f Fix mounted provider auth discovery 2026-06-08 00:42:47 -06:00
Zachariah K. Sharma 05da1532b6 Fix Portainer Hermes runtime deployment 2026-06-08 00:14:59 -06:00
Zachariah K. Sharma 74e276af92 fix: bind published ports to loopback and fix runHermes hang
- Ports now bind to HERMES_PUBLISHED_BIND_IP (default 127.0.0.1) so
  NPM on the same host proxies to 127.0.0.1:7843/8645/8646 and direct
  LAN/internet access is blocked without firewall rules
- runHermes: settle promise immediately on timeout (SIGKILL) instead of
  waiting for close event — prevents hanging when hermes spawns children
  that keep stdout/stderr open after the parent is killed
- Add HERMES_ADMIN_COOKIE_SECURE env var to set Secure flag on admin
  session cookie when the admin UI is served over HTTPS
- Document NPM deployment shapes in README

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 21:01:10 -06:00
Zachariah K. Sharma 8920e746f4 fix: add pg pool timeouts to prevent hanging requests
Without timeouts, a postgres connection or query that hangs causes the
entire authenticated request to hang indefinitely, making the reverse
proxy return 502. Now fails fast at 5s connect / 10s query.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 20:15:49 -06:00
Zachariah K. Sharma fa94a9f081 fix: reduce hermes command timeout from 30s to 5s
Prevents /api/status from holding a response for 30s when the hermes
binary is absent or stalling, which caused reverse proxies to 502.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 01:50:13 -06:00
Zachariah K. Sharma 0444772c9e fix: discover all auth*.json files in .codex dynamically
The hardcoded file list missed any file not named authEmma/authMom.
Now reads the directory and derives hints from the filename suffix
(authZach.json → hint "zach"; auth.json → ["main","default"]) so
the hints-based matching still wins over Hermes auth label matching.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 00:52:36 -06:00
Zachariah K. Sharma 226edeb8d6 fix: serve login.html for GET /login route
serveStatic looked for a file literally named "login" — adding the same
extensionless → .html mapping that / → index.html already has.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-07 00:10:30 -06:00
Zachariah K. Sharma 10346d178f fix: increase postgres healthcheck start_period for first-boot init
On first deploy postgres must initialize the data directory before it
can accept connections. 10s start_period was too tight; bumped to 30s
with 10 retries to give it enough runway on slower hosts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 03:40:58 -06:00
Zachariah K. Sharma e03aa8e889 fix: rename node user to hermes instead of creating duplicate uid 1000
node:20-bookworm-slim ships with a node user at UID 1000; useradd fails
with exit 4 when the UID is already taken. Use usermod/groupmod to
rename the existing node user/group to hermes instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 03:33:49 -06:00
Zachariah K. Sharma e703a84a72 feat: self-contain postgres in docker compose
Embed a postgres:16-alpine service so operators don't need an external
database. DATABASE_URL is now constructed internally via a YAML anchor
from POSTGRES_PASSWORD (default: hermes-change-me). Removed the manual
PostgreSQL setup section from README and updated backup instructions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:40:47 -06:00
Zachariah K. Sharma f4dca8ca73 fix: destroy client socket on upstream mid-stream error
Prevents hanging connections when the upstream response stream errors
after headers have already been sent to the client.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:19:46 -06:00
Zachariah K. Sharma 2e3e5e5e59 docs: document managed hermes api access
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:15:41 -06:00
Zachariah K. Sharma dd5318368e feat: route public api traffic through managed gateway
Replace the 3-service compose with a 5-service architecture that puts
api-gateway.cjs (hermes-pre-api, hermes-post-api) in front of internal
upstream services (hermes-pre-upstream, hermes-post-upstream), ensuring
all public API traffic passes through the auth/audit layer. Update
Dockerfile, .env.example, .dockerignore, and add a compose contract test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:12:05 -06:00
Zachariah K. Sharma c86254667b feat: add api user management interface
Adds §21 API Users pane with full CRUD, key rotation, log download, revoke/reactivate, and one-time key reveal dialog. Includes static UI contract test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:07:35 -06:00
Zachariah K. Sharma e657e20b6f feat: add protected jsonl audit downloads
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 02:02:36 -06:00
Zachariah K. Sharma fd6666ae4a feat: add authenticated pre and post api gateway
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:59:00 -06:00
Zachariah K. Sharma 143f5df049 feat: add authenticated pre and post api gateway
Implements api-gateway.cjs — a standalone HTTP server that authenticates
API keys, enforces rate/token limits, records usage events, and proxies
requests to an internal upstream (pre or post route). Adds integration
tests covering auth failures, rate limiting, non-streaming, SSE streaming,
and upstream connection errors.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:57:25 -06:00
Zachariah K. Sharma ffee4a52cc feat: add api usage limits and audit storage
Implements authorizeUsage (rate limit + monthly token limit with FOR UPDATE locking), beginUsageEvent, completeUsageEvent, failUsageEvent, streamJsonlLogs, and cleanupExpiredMessageLogs in lib/audit-store.cjs, with integration tests in test/audit.integration.test.cjs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:52:47 -06:00
Zachariah K. Sharma de6b466df7 feat: add managed api users and keys
Implements lib/api-users-store.cjs with full CRUD + auth, 7 admin REST
endpoints in server.cjs, and integration tests for all store functions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:47:54 -06:00
Zachariah K. Sharma 678b5ae6b8 feat: protect control plane with admin login
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:43:13 -06:00
Zachariah K. Sharma 76e9774c65 feat: protect control plane with admin login
Adds optional admin auth (enabled when DATABASE_URL is set) with
session-cookie login, logout, requireAdmin middleware, login UI,
and a skippable integration test (TEST_DATABASE_URL required).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:41:09 -06:00
Zachariah K. Sharma ac865ba725 feat: add admin and api key security primitives
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:34:52 -06:00
Zachariah K. Sharma c0ee7cf922 feat: add postgres schema and migration runner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:32:33 -06:00
Zachariah K. Sharma 8da610a895 feat: add postgres schema and migration runner
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-06 01:30:28 -06:00
Zachariah K. Sharma ea4746f023 docs: plan admin auth and api user management 2026-06-06 00:53:08 -06:00
Zachariah K. Sharma fbd4e231ca docs: design admin auth and api user management 2026-06-06 00:49:00 -06:00
Zachariah K. Sharma 6acec6bd2f Deployment 2026-06-06 00:01:28 -06:00
Zachariah K. Sharma b78b25a5a5 Initial Commit 2026-06-05 23:22:08 -06:00