main
1_: {
2 ssh = {
3 # Keyed SSH registry. Each entry is `{ key; access; }` where
4 # `access.<account>.<host|default>` resolves to one of:
5 # "trusted" -> full unrestricted login
6 # { gated = "a"; } -> command="praetorian run a" restricted (see carthage)
7 # absent -> no access on that host/account
8 # Rendered via libx.authorizedKeysFor. Every entry MUST declare a non-empty
9 # `access` (eval-time throw otherwise) so a key can never be silently
10 # over-provisioned. Greppable unrestricted surface: `grep '"trusted"'`.
11 vincent = {
12 # Yubikeys (PIV - legacy, keep during transition)
13 # TODO: phase these out once FIDO2/TPM coverage is complete.
14 yubikey-piv-1 = {
15 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFT5Rx+4Wuvd8lMBkcHxb4oHdRhm/OTg+p5tvPzoIN9enSmgRw5Inm/SlS8ZzV87G1NESTgzDRi6hREvqDlKvxs=";
16 access = {
17 vincent.default = "trusted";
18 root.default = "trusted";
19 };
20 };
21 yubikey-piv-2 = {
22 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGHMa4rHuBbQQYv+8jvlkFCD2VYRGA4+5fnZAhLx8iDirzfEPqHB60UJWcDeixnJCUlpJjzFbS4crNOXhfCTCTE=";
23 access = {
24 vincent.default = "trusted";
25 root.default = "trusted";
26 };
27 };
28 yubikey-piv-3 = {
29 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBFzxC16VqwTgWDQfw2YCiOw2JzpH3z9XgHtKoHhBdHi2i9m9XUc7fIUeEIIf7P8ARRNd8q5bjvl8JY7LtPkNCU=";
30 access = {
31 vincent.default = "trusted";
32 root.default = "trusted";
33 };
34 };
35 # FIDO2 resident keys (touch is the gate -> unrestricted)
36 homelab-servers = {
37 key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIODTc5Exm59skgJdu6/rA3CpX4k4P1CFBqCFtelWGGmEAAAAC3NzaDpob21lbGFi homelab-servers";
38 access = {
39 vincent.default = "trusted";
40 root.default = "trusted";
41 };
42 };
43 critical-infra = {
44 key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIAGh5p44LvQrWjAMyC/5LjUnViqFl3ddVfiFnoiLgJb7AAAAEnNzaDpjcml0aWNhbC1pbmZyYQ== infra-touch-required";
45 access = {
46 vincent.default = "trusted";
47 root.default = "trusted";
48 };
49 };
50 okinawa-fido = {
51 key = "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIEefW7gStvkrO98v6UUawwa3yOu896Ei8USE/Sh2DjaUAAAABHNzaDo= vincent@okinawa";
52 access = {
53 vincent.default = "trusted";
54 root.default = "trusted";
55 };
56 };
57 # Passage sync keys (non-SK, automated git pull only)
58 # TODO: replace with the per-machine TPM approach.
59
60 # okinawa user key: TPM-sealed ecdsa via ssh-tpm-agent (machine-bound, no touch)
61 okinawa-tpm = {
62 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBODwU2/sE+S51ShfL8t+QA9IMcVuQL+VLYuENUc5VDVD4AVoVj97BggowbAhtqDW6hdc0S3XSVrZs+aOSd9ukbg= vincent@okinawa-tpm";
63 access = {
64 vincent.default = "trusted";
65 root.default = "trusted";
66 };
67 };
68 # aomi user key: TPM-sealed ecdsa via ssh-tpm-agent (machine-bound, no touch)
69 # Gated to git push+pull on carthage only.
70 aomi-tpm = {
71 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGEL1A++UUsFnGmnrIR8S6A8IUFkR5WyxDPol2bs02TY0O+sWOPJFJZIAKqcWVSUIkxRoktUBMRe0mMZyiHa3jw= vdemeest@aomi-tpm";
72 access.vincent = {
73 carthage = {
74 gated = "aomi-git";
75 };
76 kyushu = "trusted";
77 };
78 };
79 aomi-nagoya-builder = {
80 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIuiAFmNPzh+hpnLfjCauNQWIuQ4JRBT7cD/y/5zjmZK aomi-nagoya-builder";
81 access.vincent.nagoya = "trusted";
82 };
83 kyushu-nagoya-builder = {
84 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINkw0Oc5ZQWIOSAykMb37B1xqViH1Nt8Ol+bMhE/qzK8 kyushu-nagoya-builder";
85 access.vincent.nagoya = "trusted";
86 };
87 boox-moshi = {
88 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICuaKzLeP5TasvkLucaqM/SDxP07B3zqVetuFz5+ZXQS moshi";
89 access.vincent.aomi = "trusted";
90 };
91 kyushu-tpm = {
92 key = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBc8oKSsUPsgbOB+yrqLpxdI3lt0ONhlHhTwbnrobSgDat5J/w0ZOsHJUPNU/O2Hyqd9l0UXz3d7rnwfN1sO0tQ= vdemeest@kyushu-tpm";
93 access.vincent = {
94 carthage = {
95 gated = "kyushu-git";
96 };
97 aomi = "trusted";
98 };
99 };
100 # aion host key: has automation (restic backup to aix).
101 # TODO: scope to aix + gate restic instead of full trust everywhere.
102 aion-hostkey = {
103 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE3iD9Eaf5xglTyP+kIO9t8qQpF2H42rQ2AuUibs2hn7 vincent@aion";
104 access = {
105 vincent.default = "trusted";
106 root.default = "trusted";
107 };
108 };
109 # kyushu host key.
110 # TODO: work on removing this key entirely.
111 kyushu-hostkey = {
112 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJOJ/Kd3KGVbd2QoOC+FqKxmNHLmrAEkP6lH0yqx1nO Kyushu's ssh key";
113 access = {
114 vincent.default = "trusted";
115 root.default = "trusted";
116 };
117 };
118 # Termux phones: git pull only (src/home, passage, ... under ~/git).
119 osaka-termux = {
120 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICa0SyAspL7PBPudCjb7oCBG17WRmYnDQF7/BYkFwqDi oksaka-termux";
121 access.vincent.carthage = {
122 gated = "git-pull";
123 };
124 };
125 suzu-termux = {
126 key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0Q1oXzMMJG03n2VoxKKOGruyGBy8V8yanqgeeUYm+N suzu-termux";
127 access.vincent.carthage = {
128 gated = "git-pull";
129 };
130 };
131 };
132 };
133 syncthingFolders = {
134 sync = {
135 id = "7dshg-r8zr6";
136 path = "/home/vincent/sync";
137 };
138 documents = {
139 id = "oftdb-t5anv";
140 path = "/home/vincent/desktop/documents";
141 };
142 org = {
143 id = "sjpsr-xfwdu";
144 path = "/home/vincent/desktop/org";
145 versioning = {
146 type = "staggered";
147 params = {
148 cleanInterval = "3600"; # cleanup every hour
149 maxAge = "15768000"; # keep for ~6 months (182 days in seconds)
150 };
151 };
152 };
153 screenshots = {
154 id = "prpsz-azlz9";
155 path = "/home/vincent/desktop/pictures/screenshots";
156 };
157 wallpapers = {
158 id = "wpiah-ydwwx";
159 path = "/home/vincent/desktop/pictures/wallpapers";
160 };
161 claude-sync = {
162 id = "claude-sync"; # new consolidated folder
163 path = "/home/vincent/.local/share/claude-sync";
164 };
165 ai-sync = {
166 id = "ai-sync"; # unified AI agent storage (sessions, plans, learnings, research)
167 path = "/home/vincent/.local/share/ai-sync";
168 };
169 usage-metrics = {
170 id = "usage-metrics";
171 path = "/home/vincent/.local/share/usage-metrics";
172 };
173 paperless-media = {
174 id = "paperless-media";
175 path = "/neo/paperless/media";
176 versioning = {
177 type = "staggered";
178 params = {
179 cleanInterval = "3600"; # cleanup every hour
180 maxAge = "15768000"; # keep for ~6 months (182 days in seconds)
181 };
182 };
183 };
184 paperless-inbox = {
185 id = "paperless-inbox";
186 path = "/neo/paperless/consume";
187 # No versioning - temporary files get processed and deleted
188 };
189 };
190 net = {
191 dns = {
192 cacheNetworks = [
193 "192.168.1.0/24"
194 "10.100.0.0/24"
195 ];
196 };
197 vpn = {
198 endpoint = "46.224.100.116";
199 };
200 # Travel tunnel: lutece (Paris) as a full-tunnel exit node, used to get a
201 # French IP from abroad. Separate subnet and separate interface (wg1) from
202 # the 10.100.0.0/24 homelab mesh.
203 #
204 # Traffic from these peers is masqueraded on lutece, so the rest of the
205 # mesh sees 10.100.0.3 as the source and needs no route for 10.101.0.0/24.
206 travel = {
207 subnet = "10.101.0.0/24";
208 server = "lutece";
209 # Public key of /etc/wireguard/travel.key on lutece, for client configs.
210 pubkey = "d28ha+85FlP188kDkCDMX6I8iM20PtbTy6kj0sHvHwo=";
211 # name -> travel IP. Public keys are reused from the machine's mesh
212 # identity (globals.machines.<name>.net.vpn.pubkey); last octet mirrors
213 # the machine's VPN address for readability.
214 peers = {
215 hokkaido = "10.101.0.5";
216 osaka = "10.101.0.64";
217 suzu = "10.101.0.65";
218 houbeb-makcbook-pro = "10.101.0.71";
219 };
220 };
221 nfs = {
222 defaultHosts = {
223 rhea = {
224 server = "rhea.sbr.pm";
225 folders = [
226 "downloads"
227 "pictures"
228 "videos"
229 ];
230 };
231 zion = {
232 server = "rhea.sbr.pm";
233 rootPath = "/zion";
234 folders = [
235 "audiobooks"
236 "documents"
237 "ebooks"
238 "music"
239 ];
240 };
241 aion = {
242 server = "aion.sbr.pm";
243 folders = [
244 "audiobooks"
245 "music"
246 ];
247 };
248 };
249 };
250 };
251 machines = {
252 athena = {
253 net = {
254 ips = [ "192.168.1.183" ];
255 vpn = {
256 pubkey = "RWqH7RdIXg+YE9U1nlsNiOC7jH8eWjWQmikqBVDGSXU=";
257 ips = [ "10.100.0.83" ];
258 };
259 names = [
260 "athena.home"
261 "athena.vpn"
262 "athena.sbr.pm"
263 ];
264 };
265 ssh = {
266 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM/4KRP1rzOwyA2zP1Nf1WlLRHqAGutLtOHYWfH732xh";
267 # root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFQVlSrUKU0xlM9E+sJ8qgdgqCW6ePctEBD2Yf+OnyME root@aomiy";
268 # vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILJmTdMKYdgqpbQWBif58VBuwX+GqMGsMfB1ey1TKrM3 vincent@aomi";
269 };
270 # syncthing = {
271 # id = "N3AMUVI-FM2BAOD-U3OMZDJ-UHMQE6J-ACMM5B7-S7BTK6P-PSM36NR-DVZHLQF";
272 # folders = {
273 # sync = {
274 # type = "receiveonly";
275 # };
276 # };
277 # };
278 };
279 demeter = {
280 net = {
281 ips = [ "192.168.1.182" ];
282 vpn = {
283 pubkey = "/bBh4gvDty/AA2qIiHc7K0OHoOXWmj2SFFXdDq8nsUU=";
284 ips = [ "10.100.0.82" ];
285 };
286 names = [
287 "demeter.home"
288 "demeter.vpn"
289 "demeter.sbr.pm"
290 ];
291 };
292 ssh = {
293 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGqQfEyHyjIGglayB9FtCqL7bnYfNSQlBXks2IuyCPmd";
294 };
295 # syncthing = {
296 # id = "TXCV3TS-TUEOTH6-ETB3LBV-KCIHT4L-RCCOIE3-VPBCNJB-VHQEAYI-WOXK5A5";
297 # folders = {
298 # sync = {
299 # type = "receiveonly";
300 # };
301 # };
302 # };
303 };
304 nagoya = {
305 net = {
306 ips = [ "192.168.1.80" ];
307 vpn = {
308 pubkey = "NCj5pwShre/xyRCK800ybjso1zIYUZ08YvFA2qGzhAI=";
309 ips = [ "10.100.0.80" ];
310 };
311 names = [
312 "nagoya.home"
313 "nagoya.vpn"
314 "nagoya.sbr.pm"
315 ];
316 };
317 ssh = {
318 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIfep1SkMsAPHggXFLfEJNzZb7eoihtkqDeQruG+TbhF";
319 };
320 # syncthing = {
321 # id = "HZDLS5A-LKCEIYQ-DDMDYDF-DBTSRYH-HUNQSII-TVCDACT-DIYIO7V-G4K2EQV";
322 # folders = {
323 # sync = {
324 # type = "receiveonly";
325 # };
326 # };
327 # };
328 };
329 aix = {
330 net = {
331 vpn = {
332 pubkey = "D1HoBqrqBchHOOi8mjKpVg5vZtt+iFy8wj4o3kGYwkc=";
333 ips = [ "10.100.0.89" ];
334 };
335 names = [
336 "aix.vpn"
337 "aix.sbr.pm"
338 ];
339 };
340 syncthing = {
341 id = "GHE6XF4-YCKEMZS-JEZYXA6-ETJI3SS-BQFFOCS-ZJAWN4D-Q33IQ46-OYL7BQM";
342 folders = {
343 sync = {
344 type = "receiveonly";
345 };
346 };
347 };
348 ssh = {
349 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEoUicDySCGETPAgmI0P3UrgZEXXw3zNsyCIylUP0bML";
350 };
351 };
352 kyushu = {
353 user = "vdemeest";
354 net = {
355 ips = [
356 "192.168.1.36"
357 "192.168.1.68"
358 ];
359 vpn = {
360 pubkey = "KVRzoPUw8UTQblYtbs/NLYLIVmtQehrc4Hacbpf5Ugs=";
361 ips = [ "10.100.0.19" ];
362 };
363 names = [
364 "kyushu.home"
365 "kyushu.vpn"
366 "kyushu.sbr.pm"
367 ];
368 };
369 ssh = {
370 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAJOJ/Kd3KGVbd2QoOC+FqKxmNHLmrAEkP6lH0yqx1nO";
371 };
372 syncthing = {
373 id = "G6EVI7A-WFXEAI2-ZK3BI5C-7FZJNQH-PIPBHSC-57VZDKU-HN3WBCX-A757UQJ";
374 folders = {
375 org = { };
376 documents = { };
377 sync = { };
378 screenshots = { };
379 wallpapers = { };
380 claude-sync = { };
381 ai-sync = { };
382 usage-metrics = { };
383 paperless-media = {
384 type = "receiveonly";
385 path = "/home/vincent/desktop/paperless-media";
386 };
387 paperless-inbox = {
388 path = "/home/vincent/desktop/paperless-inbox";
389 };
390 # TODO: implement paused or filter theses
391 # photos = {
392 # type = "receiveonly";
393 # paused = true; # TODO: implement this, start as paused
394 # };
395 # music = {
396 # type = "receiveonly";
397 # paused = true; # TODO: implement this, start as paused
398 # };
399 };
400 };
401 };
402 aomi = {
403 user = "vdemeest";
404 net = {
405 ips = [ "192.168.1.23" ];
406 vpn = {
407 pubkey = "Pmu/0CjRaClmz+v25OV3SLd/V6Il8YLLavbtu8cYSGY=";
408 ips = [ "10.100.0.17" ];
409 };
410 names = [
411 "aomi.home"
412 "aomi.vpn"
413 "aomi.sbr.pm"
414 ];
415 };
416 ssh = {
417 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFL4OaoBtd/BzNeQvjB9AdYUiADk2PS0cKNmXu+PgkYY";
418 };
419 syncthing = {
420 id = "S6UM56N-TI2Z73H-IKO6F5Y-652ENJL-5BICIVD-JGFXED3-7JEJLZ2-XEIEXAL";
421 folders = {
422 sync = { };
423 org = { };
424 screenshots = { };
425 wallpapers = { };
426 claude-sync = { };
427 ai-sync = { };
428 usage-metrics = { };
429 };
430 };
431 };
432 shikoku = {
433 net = {
434 ips = [ "192.168.1.24" ];
435 vpn = {
436 pubkey = "foUoAvJXGyFV4pfEE6ISwivAgXpmYmHwpGq6X+HN+yA=";
437 ips = [ "10.100.0.2" ];
438 };
439 names = [
440 "shikoku.home"
441 "shikoku.vpn"
442 "shikoku.sbr.pm"
443 ];
444 };
445 ssh = {
446 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH18c6kcorVbK2TwCgdewL6nQf29Cd5BVTeq8nRYUigm";
447 vincent = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGxstR3xEf87leVVDS3GVPx8Ap9+eP+OfkSvM26V54XP vincent@shikoku";
448 };
449 };
450 # Scaleway Dedibox VPS (VPS-START-2-S, Paris) — see infra/lutece
451 # Mesh client on wg0 (10.100.0.3) and travel exit server on wg1
452 # (see globals.net.travel).
453 lutece = {
454 net = {
455 vpn = {
456 pubkey = "H7q7Qz7JqAKXlEbNMBW3quac2GDASAZ0SYvCvJ96NTo=";
457 ips = [ "10.100.0.3" ];
458 };
459 names = [
460 "lutece.vpn"
461 "lutece.sbr.pm"
462 ];
463 };
464 ssh = {
465 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII0QxlxWPQfd4t8IxqhLKFRXPVfrRSJBpUSXipIcKOVm"; # ssh-keyscan -q -t ed25519 64.31.63.130
466 };
467 };
468 # Hetzner Cloud VPS
469 # TODO: Update pubkey, hostKey, and syncthing id after provisioning
470 carthage = {
471 net = {
472 vpn = {
473 pubkey = "PQD1dtxhy9NMbmfy2OQPeLiQg0Alcfa1Mo4HVN5WqgA=";
474 ips = [ "10.100.0.1" ]; # VPN server
475 };
476 names = [
477 "carthage.vpn"
478 "carthage.sbr.pm"
479 ];
480 };
481 ssh = {
482 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHDurbEy1PiidOirbiPXz84ySdv3rwosPTAlCqacc73a";
483 };
484 # syncthing = {
485 # id = "PLACEHOLDER_UNTIL_INSTALL";
486 # folders = {
487 # sync = { };
488 # };
489 # };
490 };
491 sakhalin = {
492 net = {
493 ips = [ "192.168.1.70" ];
494 vpn = {
495 pubkey = "OAjw1l0z56F8kj++tqoasNHEMIWBEwis6iaWNAh1jlk=";
496 ips = [ "10.100.0.16" ];
497 };
498 names = [
499 "sakhalin.home"
500 "sakhalin.vpn"
501 "sakhalin.sbr.pm"
502 ];
503 };
504 ssh = {
505 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN/PMBThi4DhgZR8VywbRDzzMVh2Qp3T6NJAcPubfXz6";
506 };
507 syncthing = {
508 id = "3L2KCXM-D75XCVU-5JLMV6V-FKQID2K-LJA6GFB-R2G77LD-5WXFHJT-BB4B7Q5";
509 folders = {
510 org = { };
511 documents = { };
512 sync = { };
513 screenshots = { };
514 wallpapers = { };
515 # photos = {
516 # type = "receiveonly";
517 # paused = true; # TODO: implement this, start as paused
518 # };
519 };
520 };
521 };
522 rhea = {
523 net = {
524 ips = [ "192.168.1.50" ];
525 vpn = {
526 pubkey = "QBGdlPgtaLIh+WDLbuIWPL+Nr08mtfIqs6RwgVDAGjA=";
527 ips = [ "10.100.0.50" ];
528 };
529 names = [
530 "rhea.home"
531 "rhea.vpn"
532 "rhea.sbr.pm"
533 ];
534 };
535 ssh = {
536 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKFH3Lk4bRgNyFRK/Hzg1PvVbL/dpyI1SmLJFkb6VQDw";
537 };
538 syncthing = {
539 id = "73YP3XV-X3YLVBD-4KL77TS-DCFFXJ7-AYJDF3R-CJDRZNP-7YFPQNT-FKHJ7QW";
540 folders = {
541 org = { };
542 documents = { };
543 sync = { };
544 screenshots = {
545 path = "/neo/pictures/vincent/screenshots";
546 };
547 wallpapers = {
548 path = "/neo/pictures/vincent/wallpapers";
549 };
550 paperless-media = {
551 type = "receiveonly";
552 path = "/neo/paperless/media";
553 };
554 paperless-inbox = {
555 path = "/neo/paperless/consume";
556 };
557 };
558 };
559 };
560 aion = {
561 net = {
562 ips = [ "192.168.1.49" ];
563 vpn = {
564 pubkey = "Z145TsRbQTASEeAXsGkQR/PGvdI5rhHAXA5wllCKMGI=";
565 ips = [ "10.100.0.49" ];
566 };
567 names = [
568 "aion.home"
569 "aion.vpn"
570 "aion.sbr.pm"
571 ];
572 };
573 ssh = {
574 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAXDNi2KtoRU83y/V5OWnMbFWmxwBknPmrNWV4RChE7R";
575 };
576 syncthing = {
577 id = "YBQ6U6T-TMCZVUG-JNHGLRH-CZNZMHG-GQICVTK-LUXJR3H-KR2SXS7-CTNQCAU";
578 folders = {
579 org = { };
580 sync = { };
581 paperless-media = {
582 path = "/neo/paperless/media";
583 };
584 paperless-inbox = {
585 path = "/neo/paperless/consume";
586 };
587 };
588 };
589 };
590 synodine = {
591 net = {
592 ips = [ "192.168.1.20" ];
593 names = [
594 "synodine.home"
595 "synodine.sbr.pm"
596 ];
597 };
598 ssh = {
599 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDWdnPJg0Y4kd4lHPAGE4xgMAK2qvMg3oBxh0t+xO+7O";
600 };
601 };
602 wakasu = {
603 net = {
604 vpn = {
605 ips = [ "10.100.0.8" ];
606 };
607 names = [
608 "wakasu.vpn"
609 "wakasu.sbr.pm"
610 ];
611 };
612 # syncthing = {
613 # id = "WM23THJ-ECXRLXA-HE5TIKO-VPLSMRY-Y2EWZI7-Q7JMLPX-5Q5UNEN-QMB7ZQJ";
614 # folders = {
615 # org = { };
616 # documents = { };
617 # sync = { };
618 # screenshots = { };
619 # wallpapers = { };
620 # };
621 # };
622 };
623 # Home Assistant
624 hass = {
625 net = {
626 ips = [ "192.168.1.181" ];
627 vpn = {
628 ips = [ "10.100.0.81" ];
629 };
630 names = [
631 "hass.home"
632 "hass.vpn"
633 "hass.sbr.pm"
634 ];
635 };
636 };
637 okinawa = {
638 net = {
639 ips = [ "192.168.1.42" ];
640 vpn = {
641 pubkey = "SxH2pDYtAlK79s5K3YwplFm4hRn8lxnl4638IPRZnBk="; # From: sudo wg show wg0 public-key
642 ips = [ "10.100.0.14" ];
643 };
644 names = [
645 "okinawa.home"
646 "okinawa.vpn"
647 "okinawa.sbr.pm"
648 ];
649 };
650 ssh = {
651 hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM8vCZ0h6geJZt6i5k6chEDZBggoyq91Z+oNSjvVeSfW root@okinawa"; # From: cat /etc/ssh/ssh_host_ed25519_key.pub
652 };
653 syncthing = {
654 id = "BTDYRYQ-IOUC6IE-2BRMDDG-4CX6OUU-XCEUMSG-QF5O463-YFTNHTS-3NGRUQX"; # From Syncthing UI (http://localhost:8384)
655 folders = {
656 sync = { };
657 org = { };
658 documents = { };
659 screenshots = { };
660 wallpapers = { };
661 claude-sync = { };
662 ai-sync = { };
663 usage-metrics = { };
664 paperless-media = {
665 type = "receiveonly";
666 path = "/home/vincent/desktop/paperless-media";
667 };
668 paperless-inbox = {
669 path = "/home/vincent/desktop/paperless-inbox";
670 };
671 };
672 };
673 };
674 # iPhone
675 hokkaido = {
676 net = {
677 ips = [ "192.168.1.115" ];
678 vpn = {
679 pubkey = "rN5ekYI/k3Ymd76vudCZtcaNNu6HmMLzB61uRXakV0M=";
680 ips = [ "10.100.0.5" ];
681 };
682 names = [
683 "hokkaido.home"
684 "hokkaido.vpn"
685 "hokkaido.sbr.pm"
686 ];
687 };
688 syncthing = {
689 id = "XD4XYNZ-DT3PJEY-UJYBHWX-6OQPPUI-HTW752L-FYTX3TW-GVHDTKW-PT336QV";
690 folders = {
691 documents = { };
692 sync = { };
693 org = { };
694 };
695 };
696 };
697 # Light Phone
698 suzu = {
699 net = {
700 vpn = {
701 ips = [ "10.100.0.65" ];
702 pubkey = "ufKLXzLkmYx1z7/VZJs9Ix6aXL3rYzP5B73QQP2WNx8=";
703 };
704 names = [
705 # "suzu.home"
706 "suzu.vpn"
707 "suzu.sbr.pm"
708 ];
709 };
710 };
711 # Boox tablet
712 osaka = {
713 net = {
714 vpn = {
715 ips = [ "10.100.0.64" ];
716 pubkey = "IJkiyMdHnhwxN9hFpDNVFKzByyqEQKIyIFBpYst65x8=";
717 };
718 names = [
719 # "oksaka.home"
720 "osaka.vpn"
721 "osaka.sbr.pm"
722 ];
723 };
724 };
725 # Houbeb's iPhone
726 houbeb-iphone = {
727 net = {
728 vpn = {
729 ips = [ "10.100.0.44" ];
730 pubkey = "UdgP0UBPfIrzdUe8JNeom4qahtoBxSADI5gKwpoNYEs=";
731 };
732 names = [
733 "houbeb-iphone.vpn"
734 "houbeb-iphone.sbr.pm"
735 ];
736 };
737 };
738 # Houbeb's macbook pro 16
739 houbeb-makcbook-pro = {
740 net = {
741 vpn = {
742 ips = [ "10.100.0.71" ];
743 pubkey = "RANYR3ouf+3Bh+6kJVF1I0s5iglBGs7ucW6iRyv2cGc=";
744 };
745 names = [ ];
746 };
747 };
748 };
749 services = {
750 # Media services on rhea
751 immich = {
752 host = "rhea";
753 aliases = [ "photos" ];
754 };
755 jellyfin.host = "rhea";
756 jellyseerr.host = "rhea";
757 sonarr.host = "rhea";
758 radarr.host = "rhea";
759 lidarr.host = "rhea";
760 bazarr.host = "rhea";
761 prowlarr.host = "rhea";
762 transmission = {
763 host = "rhea";
764 aliases = [ "t" ];
765 };
766 transmission-music = {
767 host = "rhea";
768 aliases = [ "tm" ];
769 };
770 syncthing = {
771 host = "rhea";
772 aliases = [ "s" ];
773 };
774 homepage.host = "rhea";
775 # Wallabag read-it-later (runs on aion, proxied via rhea/Traefik)
776 wallabag = {
777 host = "rhea";
778 aliases = [ "read" ];
779 };
780 # Miniflux RSS reader (runs on aion, proxied via rhea/Traefik)
781 miniflux = {
782 host = "rhea";
783 aliases = [ "rss" ];
784 };
785 # Traefik dashboard
786 traefik.host = "rhea";
787 # Music streaming on aion (routed through rhea/traefik)
788 music.host = "rhea";
789 navidrome.host = "rhea";
790 # Podcast and audiobook management on aion (routed through rhea/traefik)
791 audiobookshelf.host = "rhea";
792 podcasts.host = "rhea";
793 # Ebook library and reading-position synchronization on rhea
794 liseur = {
795 host = "rhea";
796 aliases = [ "books" ];
797 };
798 # WebDAV on rhea
799 dav.host = "rhea";
800 # MQTT on demeter (routed through rhea/traefik)
801 mqtt.host = "rhea";
802 # Home Assistant on hass (routed through rhea/traefik)
803 home.host = "rhea";
804 # Services on sakhalin (routed through rhea/traefik)
805 paperless.host = "rhea";
806 grafana.host = "rhea";
807 # OpenCode web interface on okinawa (routed through rhea/traefik)
808 opencode.host = "rhea";
809 # Readwise Reader triage report on okinawa (routed through rhea/traefik)
810 reading.host = "rhea";
811 # XMPP messaging server on aion (VPN-only, direct access)
812 xmpp.host = "aion";
813 };
814}