flake-update-20260201
  1_: {
  2  ssh = {
  3    vincent = [
  4      # Yubikeys (PIV - legacy, keep during transition)
  5      "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFT5Rx+4Wuvd8lMBkcHxb4oHdRhm/OTg+p5tvPzoIN9enSmgRw5Inm/SlS8ZzV87G1NESTgzDRi6hREvqDlKvxs="
  6      "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGHMa4rHuBbQQYv+8jvlkFCD2VYRGA4+5fnZAhLx8iDirzfEPqHB60UJWcDeixnJCUlpJjzFbS4crNOXhfCTCTE="
  7      "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBFzxC16VqwTgWDQfw2YCiOw2JzpH3z9XgHtKoHhBdHi2i9m9XUc7fIUeEIIf7P8ARRNd8q5bjvl8JY7LtPkNCU="
  8      # FIDO2 resident keys (homelab)
  9      "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIODTc5Exm59skgJdu6/rA3CpX4k4P1CFBqCFtelWGGmEAAAAC3NzaDpob21lbGFi homelab-servers"
 10      "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAGh5p44LvQrWjAMyC/5LjUnViqFl3ddVfiFnoiLgJb7AAAAEnNzaDpjcml0aWNhbC1pbmZyYQ== infra-touch-required"
 11      # Host keys (trusted machines)
 12      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJmTdMKYdgqpbQWBif58VBuwX+GqMGsMfB1ey1TKrM3 vincent@aomi"
 13      "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGThdcaPfIaB7d+K5uODqEusLKGI5ZCye0aNOCaMoInO Kyushu's ssh key"
 14    ];
 15  };
 16  syncthingFolders = {
 17    sync = {
 18      id = "7dshg-r8zr6";
 19      path = "/home/vincent/sync";
 20    };
 21    documents = {
 22      id = "oftdb-t5anv";
 23      path = "/home/vincent/desktop/documents";
 24    };
 25    org = {
 26      id = "sjpsr-xfwdu";
 27      path = "/home/vincent/desktop/org";
 28      versioning = {
 29        type = "staggered";
 30        params = {
 31          cleanInterval = "3600"; # cleanup every hour
 32          maxAge = "15768000"; # keep for ~6 months (182 days in seconds)
 33        };
 34      };
 35    };
 36    screenshots = {
 37      id = "prpsz-azlz9";
 38      path = "/home/vincent/desktop/pictures/screenshots";
 39    };
 40    wallpapers = {
 41      id = "wpiah-ydwwx";
 42      path = "/home/vincent/desktop/pictures/wallpapers";
 43    };
 44    claude-sync = {
 45      id = "claude-sync"; # new consolidated folder
 46      path = "/home/vincent/.local/share/claude-sync";
 47    };
 48  };
 49  net = {
 50    dns = {
 51      cacheNetworks = [
 52        "192.168.1.0/24"
 53        "10.100.0.0/24"
 54      ];
 55    };
 56    vpn = {
 57      endpoint = "167.99.17.238";
 58    };
 59  };
 60  machines = {
 61    athena = {
 62      net = {
 63        ips = [ "192.168.1.183" ];
 64        vpn = {
 65          pubkey = "RWqH7RdIXg+YE9U1nlsNiOC7jH8eWjWQmikqBVDGSXU=";
 66          ips = [ "10.100.0.83" ];
 67        };
 68        names = [
 69          "athena.home"
 70          "athena.vpn"
 71          "athena.sbr.pm"
 72        ];
 73      };
 74      ssh = {
 75        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/4KRP1rzOwyA2zP1Nf1WlLRHqAGutLtOHYWfH732xh";
 76        # root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQVlSrUKU0xlM9E+sJ8qgdgqCW6ePctEBD2Yf+OnyME root@aomiy";
 77        # vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJmTdMKYdgqpbQWBif58VBuwX+GqMGsMfB1ey1TKrM3 vincent@aomi";
 78      };
 79      syncthing = {
 80        id = "N3AMUVI-FM2BAOD-U3OMZDJ-UHMQE6J-ACMM5B7-S7BTK6P-PSM36NR-DVZHLQF";
 81        folders = {
 82          sync = {
 83            type = "receiveonly";
 84          };
 85        };
 86      };
 87    };
 88    demeter = {
 89      net = {
 90        ips = [ "192.168.1.182" ];
 91        vpn = {
 92          pubkey = "/bBh4gvDty/AA2qIiHc7K0OHoOXWmj2SFFXdDq8nsUU=";
 93          ips = [ "10.100.0.82" ];
 94        };
 95        names = [
 96          "demeter.home"
 97          "demeter.vpn"
 98          "demeter.sbr.pm"
 99        ];
100      };
101      ssh = {
102        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqQfEyHyjIGglayB9FtCqL7bnYfNSQlBXks2IuyCPmd";
103      };
104      syncthing = {
105        id = "TXCV3TS-TUEOTH6-ETB3LBV-KCIHT4L-RCCOIE3-VPBCNJB-VHQEAYI-WOXK5A5";
106        folders = {
107          sync = {
108            type = "receiveonly";
109          };
110        };
111      };
112    };
113    nagoya = {
114      net = {
115        ips = [ "192.168.1.80" ];
116        vpn = {
117          pubkey = "NCj5pwShre/xyRCK800ybjso1zIYUZ08YvFA2qGzhAI=";
118          ips = [ "10.100.0.80" ];
119        };
120        names = [
121          "nagoya.home"
122          "nagoya.vpn"
123          "nagoya.sbr.pm"
124        ];
125      };
126      ssh = {
127        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIfep1SkMsAPHggXFLfEJNzZb7eoihtkqDeQruG+TbhF";
128      };
129      # syncthing = {
130      #   id = "HZDLS5A-LKCEIYQ-DDMDYDF-DBTSRYH-HUNQSII-TVCDACT-DIYIO7V-G4K2EQV";
131      #   folders = {
132      #     sync = {
133      #       type = "receiveonly";
134      #     };
135      #   };
136      # };
137    };
138    aix = {
139      net = {
140        vpn = {
141          pubkey = "D1HoBqrqBchHOOi8mjKpVg5vZtt+iFy8wj4o3kGYwkc=";
142          ips = [ "10.100.0.89" ];
143        };
144        names = [
145          "aix.vpn"
146          "aix.sbr.pm"
147        ];
148      };
149      syncthing = {
150        id = "GHE6XF4-YCKEMZS-JEZYXA6-ETJI3SS-BQFFOCS-ZJAWN4D-Q33IQ46-OYL7BQM";
151        folders = {
152          sync = {
153            type = "receiveonly";
154          };
155        };
156      };
157      ssh = {
158        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEoUicDySCGETPAgmI0P3UrgZEXXw3zNsyCIylUP0bML";
159      };
160    };
161    kyushu = {
162      net = {
163        ips = [
164          "192.168.1.36"
165          "192.168.1.68"
166        ];
167        vpn = {
168          pubkey = "KVRzoPUw8UTQblYtbs/NLYLIVmtQehrc4Hacbpf5Ugs=";
169          ips = [ "10.100.0.19" ];
170        };
171        names = [
172          "kyushu.home"
173          "kyushu.vpn"
174          "kyushu.sbr.pm"
175        ];
176      };
177      ssh = {
178        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINd795m+P54GlGJdMaGci9pQ9N942VUz8ri2F14+LWxg";
179      };
180      syncthing = {
181        id = "SBLRZF4-NOMC7QO-S6UW7OH-VK7KHQS-LZCESY6-USBJ5Z5-RIVIRII-XS7DGQS";
182        folders = {
183          org = { };
184          documents = { };
185          sync = { };
186          screenshots = { };
187          wallpapers = { };
188          claude-sync = { };
189          # TODO: implement paused or filter theses
190          # photos = {
191          #   type = "receiveonly";
192          #   paused = true; # TODO: implement this, start as paused
193          # };
194          # music = {
195          #   type = "receiveonly";
196          #   paused = true; # TODO: implement this, start as paused
197          # };
198        };
199      };
200    };
201    aomi = {
202      net = {
203        ips = [ "192.168.1.23" ];
204        vpn = {
205          pubkey = "XT4D9YLeVHwMb9R4mhBLSWHYF8iBO/UOT86MQL1jnA4=";
206          ips = [ "10.100.0.17" ];
207        };
208        names = [
209          "aomi.home"
210          "aomi.vpn"
211          "aomi.sbr.pm"
212        ];
213      };
214      ssh = {
215        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQVlSrUKU0xlM9E+sJ8qgdgqCW6ePctEBD2Yf+OnyME";
216      };
217      syncthing = {
218        id = "CN5P3MV-EJ65J4I-OHB7OBI-LD7JBWT-7SZCZD3-Z6NAASI-UCMKOAU-X2TNNAP";
219        folders = {
220          org = { };
221          documents = { };
222          sync = { };
223          screenshots = { };
224          wallpapers = { };
225          claude-sync = { };
226          # photos = {
227          #   type = "receiveonly";
228          #   paused = true; # TODO: implement this, start as paused
229          # };
230        };
231      };
232    };
233    shikoku = {
234      net = {
235        ips = [ "192.168.1.24" ];
236        vpn = {
237          pubkey = "foUoAvJXGyFV4pfEE6ISwivAgXpmYmHwpGq6X+HN+yA=";
238          ips = [ "10.100.0.2" ];
239        };
240        names = [
241          "shikoku.home"
242          "shikoku.vpn"
243          "shikoku.sbr.pm"
244        ];
245      };
246      ssh = {
247        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH18c6kcorVbK2TwCgdewL6nQf29Cd5BVTeq8nRYUigm";
248      };
249      # syncthing = {
250      #   id = "ZKUNKBI-N2K2LTG-AWLDAEX-NE6NALQ-DLFO6YV-FU4A7IE-KCF5ZCD-IEYSKAH";
251      #   folders = {
252      #     org = { };
253      #     documents = { };
254      #     sync = { };
255      #     screenshots = { };
256      #     wallpapers = { };
257      #   };
258      # };
259      ssh = {
260        vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGxstR3xEf87leVVDS3GVPx8Ap9+eP+OfkSvM26V54XP vincent@shikoku";
261      };
262    };
263    kerkouane = {
264      net = {
265        vpn = {
266          pubkey = "+H3fxErP9HoFUrPgU19ra9+GDLQw+VwvLWx3lMct7QI=";
267          ips = [ "10.100.0.1" ];
268        };
269        names = [
270          "kerkouane.vpn"
271          "kerkouane.sbr.pm"
272        ];
273      };
274      ssh = {
275        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJguVoQYObRLyNxELFc3ai2yDJ25+naiM3tKrBGuxwwA";
276      };
277      syncthing = {
278        id = "QGD6ICB-EPSGCEN-IQWKN77-BCRWE67-56HX5IA-E4IDBCI-WE46DK3-EC63DQ7";
279        folders = {
280          sync = { };
281        };
282      };
283    };
284    sakhalin = {
285      net = {
286        ips = [ "192.168.1.70" ];
287        vpn = {
288          pubkey = "OAjw1l0z56F8kj++tqoasNHEMIWBEwis6iaWNAh1jlk=";
289          ips = [ "10.100.0.16" ];
290        };
291        names = [
292          "sakhalin.home"
293          "sakhalin.vpn"
294          "sakhalin.sbr.pm"
295        ];
296      };
297      ssh = {
298        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/PMBThi4DhgZR8VywbRDzzMVh2Qp3T6NJAcPubfXz6";
299      };
300      syncthing = {
301        id = "3L2KCXM-D75XCVU-5JLMV6V-FKQID2K-LJA6GFB-R2G77LD-5WXFHJT-BB4B7Q5";
302        folders = {
303          org = { };
304          documents = { };
305          sync = { };
306          screenshots = { };
307          wallpapers = { };
308          # photos = {
309          #   type = "receiveonly";
310          #   paused = true; # TODO: implement this, start as paused
311          # };
312        };
313      };
314    };
315    kobe = {
316      net = {
317        ips = [ "192.168.1.77" ];
318        vpn = {
319          pubkey = "B9jLGtXGZEfvBrgyEKrFRrsCsTsarfpFeyXqqq1NOWg=";
320          ips = [ "10.100.0.77" ];
321        };
322        names = [
323          "kobe.home"
324          "kobe.vpn"
325          "kobe.sbr.pm"
326        ];
327      };
328      ssh = {
329        # hostKey = "";
330      };
331      # syncthing = {
332      #   id = "";
333      #   folders = {
334      #     org = { };
335      #     documents = { };
336      #     sync = { };
337      #   };
338      # };
339    };
340    rhea = {
341      net = {
342        ips = [ "192.168.1.50" ];
343        vpn = {
344          pubkey = "QBGdlPgtaLIh+WDLbuIWPL+Nr08mtfIqs6RwgVDAGjA=";
345          ips = [ "10.100.0.50" ];
346        };
347        names = [
348          "rhea.home"
349          "rhea.vpn"
350          "rhea.sbr.pm"
351        ];
352      };
353      ssh = {
354        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKFH3Lk4bRgNyFRK/Hzg1PvVbL/dpyI1SmLJFkb6VQDw";
355      };
356      syncthing = {
357        id = "73YP3XV-X3YLVBD-4KL77TS-DCFFXJ7-AYJDF3R-CJDRZNP-7YFPQNT-FKHJ7QW";
358        folders = {
359          org = { };
360          documents = { };
361          sync = { };
362          screenshots = {
363            path = "/neo/pictures/vincent/screenshots";
364          };
365          wallpapers = {
366            path = "/neo/pictures/vincent/wallpapers";
367          };
368        };
369      };
370    };
371    aion = {
372      net = {
373        ips = [ "192.168.1.49" ];
374        vpn = {
375          pubkey = "USTpNYlBri+ebsbg63ohDilFF/cbHytjI0W9t13VVng=";
376          ips = [ "10.100.0.49" ];
377        };
378        names = [
379          "aion.home"
380          "aion.vpn"
381          "aion.sbr.pm"
382        ];
383      };
384      ssh = {
385        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXDNi2KtoRU83y/V5OWnMbFWmxwBknPmrNWV4RChE7R";
386      };
387      syncthing = {
388        id = "YBQ6U6T-TMCZVUG-JNHGLRH-CZNZMHG-GQICVTK-LUXJR3H-KR2SXS7-CTNQCAU";
389        folders = {
390          org = { };
391          sync = { };
392        };
393      };
394    };
395    synodine = {
396      net = {
397        ips = [ "192.168.1.20" ];
398        names = [
399          "synodine.home"
400          "synodine.sbr.pm"
401        ];
402      };
403      ssh = {
404        hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDWdnPJg0Y4kd4lHPAGE4xgMAK2qvMg3oBxh0t+xO+7O";
405      };
406    };
407    wakasu = {
408      net = {
409        vpn = {
410          ips = [ "10.100.0.8" ];
411        };
412        names = [
413          "wakasu.vpn"
414          "wakasu.sbr.pm"
415        ];
416      };
417      # syncthing = {
418      #   id = "WM23THJ-ECXRLXA-HE5TIKO-VPLSMRY-Y2EWZI7-Q7JMLPX-5Q5UNEN-QMB7ZQJ";
419      #   folders = {
420      #     org = { };
421      #     documents = { };
422      #     sync = { };
423      #     screenshots = { };
424      #     wallpapers = { };
425      #   };
426      # };
427    };
428    # Home Assistant
429    hass = {
430      net = {
431        ips = [ "192.168.1.181" ];
432        vpn = {
433          ips = [ "10.100.0.81" ];
434        };
435        names = [
436          "hass.home"
437          "hass.vpn"
438          "hass.sbr.pm"
439        ];
440      };
441    };
442    okinawa = {
443      net = {
444        ips = [ "192.168.1.19" ];
445        vpn = {
446          # pubkey = "";
447          ips = [ "10.100.0.14" ];
448        };
449        names = [
450          "okinawa.home"
451          "okinawa.vpn"
452          "okinawa.sbr.pm"
453        ];
454      };
455      # syncthing = {
456      #   id = "2RWT47Z-UGSH4QO-G4W6XN7-3XY722R-ZKGDN5U-4MDGHMA-6SM26QM-7VCQIAZ";
457      #   folders = {
458      #     sync = { };
459      #     org = { };
460      #   };
461      # };
462    };
463    # iPhone
464    hokkaido = {
465      net = {
466        ips = [ "192.168.1.115" ];
467        vpn = {
468          pubkey = "rN5ekYI/k3Ymd76vudCZtcaNNu6HmMLzB61uRXakV0M=";
469          ips = [ "10.100.0.5" ];
470        };
471        names = [
472          "hokkaido.home"
473          "hokkaido.vpn"
474          "hokkaido.sbr.pm"
475        ];
476      };
477      syncthing = {
478        id = "XD4XYNZ-DT3PJEY-UJYBHWX-6OQPPUI-HTW752L-FYTX3TW-GVHDTKW-PT336QV";
479        folders = {
480          documents = { };
481          sync = { };
482          org = { };
483        };
484      };
485    };
486    # Light Phone
487    suzu = {
488      net = {
489        vpn = {
490          ips = [ "10.100.0.65" ];
491          pubkey = "ufKLXzLkmYx1z7/VZJs9Ix6aXL3rYzP5B73QQP2WNx8=";
492        };
493        names = [
494          # "suzu.home"
495          "suzu.vpn"
496          "suzu.sbr.pm"
497        ];
498      };
499    };
500    # Boox tablet
501    osaka = {
502      net = {
503        vpn = {
504          ips = [ "10.100.0.64" ];
505          pubkey = "C12Ch3LasZ9Dvc1+X+IMSmKdip0l1n/aNNPvmQzzPFY=";
506        };
507        names = [
508          # "oksaka.home"
509          "osaka.vpn"
510          "osaka.sbr.pm"
511        ];
512      };
513    };
514  };
515  services = {
516    # Media services on rhea
517    immich = {
518      host = "rhea";
519      aliases = [ "photos" ];
520    };
521    jellyfin.host = "rhea";
522    jellyseerr.host = "rhea";
523    sonarr.host = "rhea";
524    radarr.host = "rhea";
525    lidarr.host = "rhea";
526    bazarr.host = "rhea";
527    prowlarr.host = "rhea";
528    transmission = {
529      host = "rhea";
530      aliases = [ "t" ];
531    };
532    transmission-music = {
533      host = "rhea";
534      aliases = [ "tm" ];
535    };
536    syncthing = {
537      host = "rhea";
538      aliases = [ "s" ];
539    };
540    homepage.host = "rhea";
541    # Linkwarden bookmark manager (runs on sakhalin, proxied via rhea/Traefik)
542    linkwarden = {
543      host = "rhea";
544      aliases = [ "links" ];
545    };
546    # Traefik dashboard
547    traefik.host = "rhea";
548    # Music streaming on aion (routed through rhea/traefik)
549    music.host = "rhea";
550    navidrome.host = "rhea";
551    # Podcast and audiobook management on aion (routed through rhea/traefik)
552    audiobookshelf.host = "rhea";
553    podcasts.host = "rhea";
554    # Ebook library management on rhea
555    calibre.host = "rhea";
556    books.host = "rhea";
557    # WebDAV on rhea
558    dav.host = "rhea";
559    # MQTT on demeter (routed through rhea/traefik)
560    mqtt.host = "rhea";
561    # Home Assistant on hass (routed through rhea/traefik)
562    home.host = "rhea";
563    # Services on sakhalin (routed through rhea/traefik)
564    kiwix.host = "rhea";
565    n8n.host = "rhea";
566    paperless.host = "rhea";
567    grafana.host = "rhea";
568    # Ollama LLM service on aomi (routed through rhea/traefik)
569    ollama = {
570      host = "rhea";
571      aliases = [ "llm" ];
572    };
573    # XMPP messaging server on aion (VPN-only, direct access)
574    xmpp.host = "aion";
575  };
576}