From 5930ea925d8de3bbc3b9e2f7ec7cd970aabe7f16 Mon Sep 17 00:00:00 2001 From: Ciphercat <78522797+0xrsydn@users.noreply.github.com> Date: Mon, 16 Mar 2026 00:36:12 +0000 Subject: [PATCH] feat: add authFile option + sops-nix documentation - authFile option for declarative OAuth token management - sops-nix integration examples in README - Plain file secrets example in README --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ module.nix | 15 +++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/README.md b/README.md index d7191b4..70e2e48 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,55 @@ Everything is configured in Nix. Config, documents, secrets, service — one `ni } ``` +### Secrets Management + +#### Plain files approach + +```nix +services.hermes-agent = { + environmentFiles = [ "/run/secrets/hermes-env" ]; + authFile = "/run/secrets/hermes-auth.json"; # optional, for OAuth tokens +}; +``` + +#### sops-nix approach + +```nix +sops.secrets."hermes/env" = { + sopsFile = ./secrets/hermes.yaml; + owner = "hermes"; + group = "hermes"; +}; + +sops.secrets."hermes/auth" = { + sopsFile = ./secrets/hermes.yaml; + owner = "hermes"; + group = "hermes"; +}; + +services.hermes-agent = { + enable = true; + environmentFiles = [ config.sops.secrets."hermes/env".path ]; + authFile = config.sops.secrets."hermes/auth".path; + config.model = { + default = "anthropic/claude-opus-4.6"; + provider = "openrouter"; + }; +}; +``` + +#### Example secrets file structure + +```yaml +hermes/env: | + OPENROUTER_API_KEY=sk-or-... + ANTHROPIC_API_KEY=sk-ant-... + TELEGRAM_TOKEN=123456:ABC... + GLM_API_KEY=... +hermes/auth: | + {"nous": {"token": "...", "refresh": "..."}, "codex": {"token": "..."}} +``` + ### 3. Create secrets file ```bash @@ -162,6 +211,7 @@ You (Telegram/Discord/WhatsApp/Slack) → Gateway → Tools → Machine does thi | `documents` | attrset | `{}` | Workspace files (string or path values) | | `environmentFiles` | list | `[]` | Secret env files (systemd EnvironmentFile) | | `environment` | attrset | `{}` | Non-secret env vars | +| `authFile` | path | `null` | OAuth credentials file (auth.json) | | `mcpServers` | attrset | `{}` | MCP server configs (merged into config) | | `user` | string | `"hermes"` | Service user | | `group` | string | `"hermes"` | Service group | diff --git a/module.nix b/module.nix index b336e1e..64a2441 100644 --- a/module.nix +++ b/module.nix @@ -162,6 +162,16 @@ in ''; }; + authFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + Path to an auth.json file containing OAuth credentials (Nous Portal, Codex, Anthropic OAuth). + Use with sops-nix to manage OAuth tokens declaratively. + If null, auth.json is managed at runtime via `hermes model`. + ''; + }; + # ── Documents (SOUL.md, AGENTS.md, etc.) ───────────────────────────── documents = mkOption { type = types.attrsOf (types.either types.str types.path); @@ -272,6 +282,11 @@ in # Link config file install -o ${cfg.user} -g ${cfg.group} -m 0640 -D ${configFile} ${cfg.stateDir}/.hermes/cli-config.yaml + # Link auth file if provided + ${lib.optionalString (cfg.authFile != null) '' + install -o ${cfg.user} -g ${cfg.group} -m 0600 ${cfg.authFile} ${cfg.stateDir}/.hermes/auth.json + ''} + # Link documents into workspace ${lib.concatStringsSep "\n" (lib.mapAttrsToList (name: _value: '' install -o ${cfg.user} -g ${cfg.group} -m 0644 ${documentDerivation}/${name} ${cfg.workingDirectory}/${name}