diff --git a/home/default.nix b/home/default.nix index 64f83e7..25e5bcd 100644 --- a/home/default.nix +++ b/home/default.nix @@ -43,8 +43,8 @@ enableNixpkgsReleaseCheck = false; stateVersion = "26.05"; sessionVariables = lib.mkIf (!isDarwin && !isServer) { - GROQ_API_KEY = config.sops.secrets.GROQ_API_KEY.path; - OPENWEATHER_API_KEY = config.sops.secrets.OPENWEATHER_API_KEY.path; + GROQ_API_KEY = config.sops.secrets."api_keys/groq".path; + OPENWEATHER_API_KEY = config.sops.secrets."api_keys/openweather".path; }; file = lib.mkIf (!isServer) { "Pictures/Avatar" = { @@ -67,13 +67,13 @@ else "/persist/secrets/age-key.txt"; secrets = { - GROQ_API_KEY = { }; - OPENWEATHER_API_KEY = { }; - ssh_private_key = { + "api_keys/groq" = { }; + "api_keys/openweather" = { }; + "ssh/private_key" = { path = if isDarwin then "/Users/${primaryUser}/.ssh/ssh" else "/home/${primaryUser}/.ssh/ssh"; mode = "0600"; }; - ssh_github_key = { + "ssh/github_key" = { path = if isDarwin then "/Users/${primaryUser}/.ssh/github" else "/home/${primaryUser}/.ssh/github"; mode = "0600"; }; diff --git a/home/desktop/waybar/common.nix b/home/desktop/waybar/common.nix index 7adb87c..2f7fc98 100644 --- a/home/desktop/waybar/common.nix +++ b/home/desktop/waybar/common.nix @@ -150,11 +150,11 @@ format = "{}"; return-type = "json"; exec = '' - curl -sf --max-time 10 "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$(cat ~/.config/sops-nix/secrets/OPENWEATHER_API_KEY)&units=metric&lang=en" | jq -c '{text: "\(.name) \(.main.temp)C°"}' + curl -sf --max-time 10 "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$(cat ~/.config/sops-nix/secrets/api_keys/openweather)&units=metric&lang=en" | jq -c '{text: "\(.name) \(.main.temp)C°"}' ''; interval = 120; on-click = '' - data=$(curl -sf --max-time 10 "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$(cat ~/.config/sops-nix/secrets/OPENWEATHER_API_KEY)&units=metric&lang=en") + data=$(curl -sf --max-time 10 "https://api.openweathermap.org/data/2.5/weather?lat=52.281311&lon=10.527029&appid=$(cat ~/.config/sops-nix/secrets/api_keys/openweather)&units=metric&lang=en") city=$(echo "$data" | jq -r '.name') temp=$(echo "$data" | jq -r '.main.temp') feels=$(echo "$data" | jq -r '.main.feels_like') diff --git a/home/neovim/avante.nix b/home/neovim/avante.nix index 40c9725..5acea28 100644 --- a/home/neovim/avante.nix +++ b/home/neovim/avante.nix @@ -1,5 +1,4 @@ { - # Avante: AI-powered coding assistant (Cursor-like experience in Neovim) programs.nixvim = { plugins = { markdown-preview.enable = true; @@ -13,7 +12,7 @@ providers = { groq = { __inherited_from = "openai"; - api_key_name = "cmd:cat /home/phil/.config/sops-nix/secrets/GROQ_API_KEY"; + api_key_name = "cmd:cat /home/phil/.config/sops-nix/secrets/api_keys/groq"; endpoint = "https://api.groq.com/openai/v1/"; model = "qwen/qwen3-32b"; system_promt = "You are a helpful coding assistant. Always respond in plain markdown format without using tool calls or JSON structures."; @@ -29,9 +28,9 @@ ollama = { endpoint = "http://10.10.0.2:11434"; - model = "qwen2.5:3b"; # swap for "llama3.2:3b" or "deepseek-r1:1.5b" - timeout = 60000; # local + small model can be slow on first load - disable_tools = true; # these small models aren't reliable at tool calling + model = "qwen2.5:3b"; + timeout = 60000; + disable_tools = true; is_env_set.__raw = ''require("avante.providers.ollama").check_endpoint_alive''; extra_request_body = { options = { diff --git a/hosts/cyper-controller/smb.nix b/hosts/cyper-controller/smb.nix index 9cbb4d9..9613cf7 100644 --- a/hosts/cyper-controller/smb.nix +++ b/hosts/cyper-controller/smb.nix @@ -1,11 +1,12 @@ { pkgs, primaryUser, + config, ... }: { - sops.secrets.smb_passwd = { }; + sops.secrets."network/smb_passwd" = { }; users.users.${primaryUser}.extraGroups = [ "sambashare" ]; @@ -93,7 +94,7 @@ sleep 1 done - PASSWORD=$(cat /run/secrets/smb_passwd) + PASSWORD=$(cat ${config.sops.secrets."network/smb_passwd".path}) (echo "$PASSWORD"; echo "$PASSWORD") | ${pkgs.samba}/bin/smbpasswd -a -s ${primaryUser} || \ (echo "$PASSWORD"; echo "$PASSWORD") | ${pkgs.samba}/bin/smbpasswd -s ${primaryUser} ''; diff --git a/hosts/cyper-desktop/hardware-configuration.nix b/hosts/cyper-desktop/hardware-configuration.nix index a69f267..441a83b 100644 --- a/hosts/cyper-desktop/hardware-configuration.nix +++ b/hosts/cyper-desktop/hardware-configuration.nix @@ -34,12 +34,11 @@ }; sops = { - secrets.smb_passwd = { }; - + secrets."network/smb_passwd" = { }; templates.smb_credentials = { content = '' username=${primaryUser} - password=${config.sops.placeholder.smb_passwd} + password=${config.sops.placeholder."network/smb_passwd"} ''; }; }; diff --git a/nixos/default.nix b/nixos/default.nix index f8eb434..df79f08 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -23,9 +23,11 @@ ./catppuccin.nix ]; - sops.secrets."nix_cache_priv_key" = { - - mode = "0400"; + sops.secrets = { + "nix/cache_priv_key" = { + mode = "0400"; + }; + "nix/cachix_auth_token" = { }; }; nix = { @@ -48,7 +50,7 @@ "https://nix-community.cachix.org" "https://cyper-cache.cachix.org" ]; - secret-key-files = [ config.sops.secrets."nix_cache_priv_key".path ]; + secret-key-files = [ config.sops.secrets."nix/cache_priv_key".path ]; trusted-public-keys = [ "cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=" "hyprland.cachix.org-1:a7pgxzMz7+chwVL3/pzj6jIBMioiJM7ypFP8PwtkuGc=" @@ -113,8 +115,6 @@ }; }; - sops.secrets.cachix_auth_token = { }; - systemd.services.cachix-push = { description = "Push new store paths to Cachix"; after = [ "multi-user.target" ]; @@ -122,7 +122,11 @@ serviceConfig = { Type = "oneshot"; RemainAfterExit = true; - ExecStart = "${pkgs.bash}/bin/bash -c 'CACHIX_AUTH_TOKEN=$(cat ${config.sops.secrets.cachix_auth_token.path}) ${pkgs.nix}/bin/nix path-info --recursive /run/current-system | CACHIX_AUTH_TOKEN=$(cat ${config.sops.secrets.cachix_auth_token.path}) ${pkgs.cachix}/bin/cachix push cyper-cache'"; + ExecStart = "${pkgs.bash}/bin/bash -c 'CACHIX_AUTH_TOKEN=$(cat ${ + config.sops.secrets."nix/cachix_auth_token".path + }) ${pkgs.nix}/bin/nix path-info --recursive /run/current-system | CACHIX_AUTH_TOKEN=$(cat ${ + config.sops.secrets."nix/cachix_auth_token".path + }) ${pkgs.cachix}/bin/cachix push cyper-cache'"; }; }; diff --git a/nixos/roles/frontpage/frontpage.nix b/nixos/roles/frontpage/frontpage.nix index 9af8cf1..dd25cfd 100644 --- a/nixos/roles/frontpage/frontpage.nix +++ b/nixos/roles/frontpage/frontpage.nix @@ -13,7 +13,7 @@ let "/var/lib/flame-${name}:/app/data" ] ++ extraVolumes; - environmentFiles = [ config.sops.secrets."flame_${name}_password".path ]; + environmentFiles = [ config.sops.secrets."services/flame/${name}_password".path ]; }; instances = [ @@ -57,7 +57,7 @@ in ]; sops.secrets = lib.listToAttrs ( - map ({ name, ... }: lib.nameValuePair "flame_${name}_password" { }) instances + map ({ name, ... }: lib.nameValuePair "services/flame/${name}_password" { }) instances ); virtualisation = { diff --git a/nixos/roles/gitea.nix b/nixos/roles/gitea.nix index f94bb17..9814d83 100644 --- a/nixos/roles/gitea.nix +++ b/nixos/roles/gitea.nix @@ -2,7 +2,6 @@ pkgs, lib, config, - primaryUser, ... }: @@ -20,27 +19,27 @@ let in { sops.secrets = { - "gitea/dbPassword" = { + "services/gitea/db_password" = { owner = "gitea"; group = "gitea"; mode = "0444"; }; - "gitea/internalToken" = { + "services/gitea/internal_token" = { owner = "gitea"; group = "gitea"; }; - "gitea/lfsJwtSecret" = { + "services/gitea/lfs_jwt_secret" = { owner = "gitea"; group = "gitea"; }; - "gitea/mailerPassword" = { + "services/gitea/mailer_password" = { owner = "gitea"; group = "gitea"; }; - "gitea/runnerToken" = { + "services/gitea/runner_token" = { mode = "0444"; }; - "kanidm_gitea_secret" = { + "kanidm/gitea_secret" = { owner = "gitea"; group = "gitea"; mode = "0444"; @@ -75,7 +74,7 @@ in RemainAfterExit = true; }; script = '' - pass=$(cat ${config.sops.secrets."gitea/dbPassword".path}) + pass=$(cat ${config.sops.secrets."services/gitea/db_password".path}) ${pkgs.postgresql_14}/bin/psql -c \ "ALTER USER gitea WITH PASSWORD '$pass';" ''; @@ -126,7 +125,7 @@ in port = 5432; name = "gitea"; user = "gitea"; - passwordFile = config.sops.secrets."gitea/dbPassword".path; + passwordFile = config.sops.secrets."services/gitea/db_password".path; }; settings = { @@ -222,7 +221,7 @@ in gitea-actions-runner.instances."cyper_nix" = { enable = true; url = "https://git.cyperpunk.de"; - tokenFile = config.sops.secrets."gitea/runnerToken".path; + tokenFile = config.sops.secrets."services/gitea/runner_token".path; name = "cyper-controller"; labels = [ "nix:host" ]; diff --git a/nixos/roles/matrix/coturn.nix b/nixos/roles/matrix/coturn.nix index 8c630ad..dd3101f 100644 --- a/nixos/roles/matrix/coturn.nix +++ b/nixos/roles/matrix/coturn.nix @@ -1,15 +1,14 @@ { config, lib, ... }: { sops.secrets = { - coturn_static_auth_secret = { + "matrix/coturn_static_auth_secret" = { owner = "turnserver"; group = "turnserver"; }; - coturn_static_auth_secret_synapse = { owner = "matrix-synapse"; group = "matrix-synapse"; - key = "coturn_static_auth_secret"; + key = "matrix/coturn_static_auth_secret"; }; }; @@ -21,7 +20,7 @@ min-port = 49000; max-port = 50000; use-auth-secret = true; - static-auth-secret-file = config.sops.secrets.coturn_static_auth_secret.path; + static-auth-secret-file = config.sops.secrets."matrix/coturn_static_auth_secret".path; realm = "turn.cyperpunk.de"; cert = "${config.security.acme.certs.${realm}.directory}/full.pem"; pkey = "${config.security.acme.certs.${realm}.directory}/key.pem"; diff --git a/nixos/roles/matrix/discord-bridge.nix b/nixos/roles/matrix/discord-bridge.nix index a3c6fc4..39bc845 100644 --- a/nixos/roles/matrix/discord-bridge.nix +++ b/nixos/roles/matrix/discord-bridge.nix @@ -1,15 +1,15 @@ { config, lib, ... }: { sops.secrets = { - discord_bot_token = { + "matrix/bridges/discord/bot_token" = { owner = "mautrix-discord"; group = "mautrix-discord"; }; - discord_client_id = { + "matrix/bridges/discord/client_id" = { owner = "mautrix-discord"; group = "mautrix-discord"; }; - discord_pickle_key = { + "matrix/bridges/discord/pickle_key" = { owner = "mautrix-discord"; group = "mautrix-discord"; }; @@ -35,9 +35,15 @@ }; script = '' mkdir -p /run/mautrix-discord - echo "DISCORD_BOT_TOKEN=$(cat ${config.sops.secrets.discord_bot_token.path})" > /run/mautrix-discord/env - echo "DISCORD_CLIENT_ID=$(cat ${config.sops.secrets.discord_client_id.path})" >> /run/mautrix-discord/env - echo "DISCORD_PICKLE_KEY=$(cat ${config.sops.secrets.discord_pickle_key.path})" >> /run/mautrix-discord/env + echo "DISCORD_BOT_TOKEN=$(cat ${ + config.sops.secrets."matrix/bridges/discord/bot_token".path + })" > /run/mautrix-discord/env + echo "DISCORD_CLIENT_ID=$(cat ${ + config.sops.secrets."matrix/bridges/discord/client_id".path + })" >> /run/mautrix-discord/env + echo "DISCORD_PICKLE_KEY=$(cat ${ + config.sops.secrets."matrix/bridges/discord/pickle_key".path + })" >> /run/mautrix-discord/env chmod 600 /run/mautrix-discord/env chown mautrix-discord:mautrix-discord /run/mautrix-discord/env ''; diff --git a/nixos/roles/matrix/draupnir.nix b/nixos/roles/matrix/draupnir.nix index a5735fa..5b0d735 100644 --- a/nixos/roles/matrix/draupnir.nix +++ b/nixos/roles/matrix/draupnir.nix @@ -1,6 +1,6 @@ { config, ... }: { - sops.secrets.draupnir_access_token = { }; + sops.secrets."matrix/draupnir_access_token" = { }; environment.persistence."/persist".directories = [ { @@ -13,7 +13,7 @@ services.draupnir = { enable = true; - secrets.accessToken = config.sops.secrets.draupnir_access_token.path; + secrets.accessToken = config.sops.secrets."matrix/draupnir_access_token".path; settings = { homeserverUrl = "https://matrix.cyperpunk.de"; managementRoom = "!eErCimyDjLSebHjpJA:cyperpunk.de"; diff --git a/nixos/roles/matrix/livekit.nix b/nixos/roles/matrix/livekit.nix index 9460a95..ce7e191 100644 --- a/nixos/roles/matrix/livekit.nix +++ b/nixos/roles/matrix/livekit.nix @@ -1,18 +1,20 @@ { config, ... }: { - sops.secrets.livekit_key_file = { }; + sops.secrets."matrix/livekit_key_file" = { }; - services.livekit = { - enable = true; - openFirewall = true; - settings.room.auto_create = false; - keyFile = config.sops.secrets.livekit_key_file.path; - }; + services = { + livekit = { + enable = true; + openFirewall = true; + settings.room.auto_create = false; + keyFile = config.sops.secrets."matrix/livekit_key_file".path; + }; - services.lk-jwt-service = { - enable = true; - livekitUrl = "wss://cyperpunk.de/livekit/sfu"; - keyFile = config.sops.secrets.livekit_key_file.path; + lk-jwt-service = { + enable = true; + livekitUrl = "wss://cyperpunk.de/livekit/sfu"; + keyFile = config.sops.secrets."matrix/livekit_key_file".path; + }; }; systemd.services.lk-jwt-service.environment.LIVEKIT_FULL_ACCESS_HOMESERVERS = "cyperpunk.de"; diff --git a/nixos/roles/matrix/meta-bridge.nix b/nixos/roles/matrix/meta-bridge.nix index 7f8f70e..0c2f0e6 100644 --- a/nixos/roles/matrix/meta-bridge.nix +++ b/nixos/roles/matrix/meta-bridge.nix @@ -1,19 +1,19 @@ { config, lib, ... }: { sops.secrets = { - meta_as_token = { + "matrix/bridges/meta/as_token" = { owner = "mautrix-meta-facebook"; group = "mautrix-meta"; }; - meta_hs_token = { + "matrix/bridges/meta/hs_token" = { owner = "mautrix-meta-facebook"; group = "mautrix-meta"; }; - instagram_as_token = { + "matrix/bridges/instagram/as_token" = { owner = "mautrix-meta-instagram"; group = "mautrix-meta"; }; - instagram_hs_token = { + "matrix/bridges/instagram/hs_token" = { owner = "mautrix-meta-instagram"; group = "mautrix-meta"; }; @@ -44,8 +44,12 @@ }; script = '' mkdir -p /run/mautrix-meta-facebook - echo "META_AS_TOKEN=$(cat ${config.sops.secrets.meta_as_token.path})" > /run/mautrix-meta-facebook/env - echo "META_HS_TOKEN=$(cat ${config.sops.secrets.meta_hs_token.path})" >> /run/mautrix-meta-facebook/env + echo "META_AS_TOKEN=$(cat ${ + config.sops.secrets."matrix/bridges/meta/as_token".path + })" > /run/mautrix-meta-facebook/env + echo "META_HS_TOKEN=$(cat ${ + config.sops.secrets."matrix/bridges/meta/hs_token".path + })" >> /run/mautrix-meta-facebook/env chmod 600 /run/mautrix-meta-facebook/env chown mautrix-meta-facebook:mautrix-meta /run/mautrix-meta-facebook/env ''; @@ -60,8 +64,12 @@ }; script = '' mkdir -p /run/mautrix-meta-instagram - echo "INSTAGRAM_AS_TOKEN=$(cat ${config.sops.secrets.instagram_as_token.path})" > /run/mautrix-meta-instagram/env - echo "INSTAGRAM_HS_TOKEN=$(cat ${config.sops.secrets.instagram_hs_token.path})" >> /run/mautrix-meta-instagram/env + echo "INSTAGRAM_AS_TOKEN=$(cat ${ + config.sops.secrets."matrix/bridges/instagram/as_token".path + })" > /run/mautrix-meta-instagram/env + echo "INSTAGRAM_HS_TOKEN=$(cat ${ + config.sops.secrets."matrix/bridges/instagram/hs_token".path + })" >> /run/mautrix-meta-instagram/env chmod 600 /run/mautrix-meta-instagram/env chown mautrix-meta-instagram:mautrix-meta /run/mautrix-meta-instagram/env ''; diff --git a/nixos/roles/matrix/postgres-backup.nix b/nixos/roles/matrix/postgres-backup.nix index 96677ad..745f816 100644 --- a/nixos/roles/matrix/postgres-backup.nix +++ b/nixos/roles/matrix/postgres-backup.nix @@ -5,7 +5,7 @@ }: { sops.secrets = { - pg_replication_password = { + "postgres/replication_password" = { owner = "root"; group = "root"; }; @@ -17,12 +17,10 @@ description = "PostgreSQL WAL streaming replica (Docker)"; requires = [ "docker.service" - "tailscaled.service" "network-online.target" ]; after = [ "docker.service" - "tailscaled.service" "network-online.target" ]; wantedBy = [ "multi-user.target" ]; @@ -35,61 +33,49 @@ }; preStart = '' - DATADIR="/storage/backup/postgresql-replica" - PG_PASS=$(cat ${config.sops.secrets.pg_replication_password.path}) - - ${pkgs.docker}/bin/docker pull postgres:17 - - if [ ! -f "$DATADIR/PG_VERSION" ]; then - echo "No data dir found — running pg_basebackup..." - rm -rf "$DATADIR" - - ${pkgs.docker}/bin/docker run --rm \ - -e PGPASSWORD="$PG_PASS" \ - -v "/storage/backup:/out" \ - --network host \ - postgres:17 \ - pg_basebackup \ - --host=10.10.0.1 \ - --port=5432 \ - --username=replicator \ - --pgdata=/out/postgresql-replica \ - --wal-method=stream \ - --checkpoint=fast \ - --progress \ - --verbose - - # standby signal - touch "$DATADIR/standby.signal" - - # primary conninfo - cat > "$DATADIR/postgresql.auto.conf" < "$DATADIR/postgresql.auto.conf" < "$DATADIR/postgresql.conf" < "$DATADIR/postgresql.conf" < "$DATADIR/postgresql.conf" < "$DATADIR/postgresql.conf" <