Files
homelab/hosts/mars/secrets.nix
darmanandClaude Sonnet 5 6f24ab69ad docs: condense comments across the repo
Comments had drifted into multi-paragraph narrative (git commit
lineage, debugging stories, restated code) in several hot spots
(scripts/deploy, hermes-agent.nix, flake.nix, gitea.nix, headscale.nix).
Trim every comment to its load-bearing "why" — gotchas, safety
warnings, and non-obvious rationale survive verbatim in substance,
just tightened to 1-2 sentences; historical narrative and anything
already covered in CLAUDE.md is cut. No code/logic changed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UJqEmY1y3AYX3JoX4Y6b21
2026-09-18 21:36:30 +02:00

76 lines
3.8 KiB
Nix

{ config, ... }:
# sops-nix wiring for mars. Encrypted values in ../../secrets/mars.yaml,
# decrypted with mars's own SSH host key (recipient in ../../.sops.yaml).
# The host key is pre-generated on the laptop and shipped at install
# (nixos-anywhere --extra-files -> /etc/ssh/ssh_host_ed25519_key).
{
sops.defaultSopsFile = ../../secrets/mars.yaml;
sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
sops.secrets.darman_password.neededForUsers = true;
users.users.darman.hashedPasswordFile = config.sops.secrets.darman_password.path;
sops.secrets.tailscale_authkey = { };
# Credentials file for the //jupiter/data cifs mount (see configuration.nix).
# Same value as jupiter's own samba_password (services/network/samba.nix) —
# mars authenticates as the same smb user, mirroring terra's setup.
sops.secrets.samba_password = { };
sops.templates."jupiter-smb.credentials".content = ''
username=darman
password=${config.sops.placeholder.samba_password}
'';
# Hermes Agent (hermes-agent.nix) — same Telegram bot token, opencode key,
# and Authentik OIDC client secret as it used before moving here from
# jupiter, so no new bot/app to provision.
sops.secrets.opencode_go_api_key = { };
sops.secrets.telegram_bot_token = { };
sops.secrets.hermes_dashboard_oidc_client_secret = { };
# Same value as secrets/jupiter.yaml (the sending side), stored WITHOUT a
# trailing newline — a stray newline would change the HMAC key and fail
# every delivery. Written host-side by hermes-agent-webhook-routes, so it
# no longer needs to sit in the container's env where luna could read it.
sops.secrets.gitea_hermes_webhook_secret = {
restartUnits = [ "hermes-agent-webhook-routes.service" ];
};
sops.templates."hermes-agent.env".content = ''
OPENCODE_GO_API_KEY=${config.sops.placeholder.opencode_go_api_key}
TELEGRAM_BOT_TOKEN=${config.sops.placeholder.telegram_bot_token}
TELEGRAM_HOME_CHANNEL=15151223
TELEGRAM_ALLOWED_USERS=15151223
WEBHOOK_ENABLED=true
WEBHOOK_PORT=8644
HERMES_DASHBOARD_OIDC_CLIENT_SECRET=${config.sops.placeholder.hermes_dashboard_oidc_client_secret}
'';
# luna's gitea push token (services/dev/gitea.nix provisions the account +
# PR-tier access), generated once via `gitea admin user generate-access-token
# --username luna --scopes write:repository,read:user` on jupiter — read:user
# is required or `tea logins add` fails. restartUnits re-provisions the git
# credential-store file and `tea` login on rotation, without a full deploy.
sops.secrets.gitea_luna_token.restartUnits = [ "hermes-agent-prepare-dirs.service" ];
# livesync-bridge (livesync-bridge.nix) — luna's Obsidian vault, mirrored
# from CouchDB on jupiter. Consumed only via the rendered config.json, so
# the sops default of root:root 0400 is fine here.
#
# ⚠️ couchdb_luna_password is jupiter's `obsidian` ADMIN password (same as
# secrets/jupiter.yaml's couchdb_admin_password) and obsidian_luna_passphrase
# reuses the personal vault's passphrase — reusing what already existed, but
# it means mars (running an autonomous agent) can decrypt and read EVERY
# vault database, not just luna's. To shrink that blast radius: give luna's
# vault its own passphrase, and/or scope a CouchDB account to her database
# via _security (README -> "Obsidian vaults"). Neither is required for the
# bridge to work.
sops.secrets.couchdb_luna_password = { };
# The E2EE passphrase for luna's vault, as entered in the Obsidian plugin.
# Vault passphrases otherwise never leave the clients (obsidian-livesync.nix)
# — this has to be here because mars IS a client, decrypting to write real
# markdown to disk. Also feeds the bridge's separate obfuscatePassphrase
# field, since the plugin derives path obfuscation from the same value.
sops.secrets.obsidian_luna_passphrase = { };
}