feat(clan): data-mesher + dm-pull-deploy wiring 🌊

Stage 4e-a of the clan migration. Set up signed-file gossip
(data-mesher, experimental, clan-core) and pull-based NixOS deploy
(dm-pull-deploy, experimental, clan-community) across both servers.

- sunken-ship is the data-mesher bootstrap node + dm-pull-deploy push
  role; phantom-ship joins via /dns/sunken-ship.clan/tcp/7946/... — the
  hostname resolves via /etc/hosts (clanHostsModule) to sunken-ship's
  ZT IPv6 since we don't run a DNS server for the clan domain.
- Both machines run the dm-pull-deploy default role with
  action="switch": they watch /var/lib/data-mesher/files/home/
  dm_pull_deploy/target and nixos-rebuild switch against the pushed
  git+…?rev=…&narHash=… flake ref on each change.
- Signing keys (shared + per-host status) generated via clan vars
  generate, ran on sunken-ship because data-mesher isn't packaged for
  aarch64-darwin.

The legacy dotfiles-rebuild timer stays installed as a fallback until
dm-pull-deploy is proven; a smart push timer on sunken-ship (calls
dm-send-deploy only when origin/main moves) comes next.
This commit is contained in:
DannyDannyDanny 2026-04-20 11:38:01 +02:00
parent 41b3d217f8
commit 6846faa5f1
34 changed files with 334 additions and 20 deletions

View file

@ -14,11 +14,31 @@ let
import ../lib/home-manager-user.nix {
inherit lib user homeDirectory stateVersion userImports;
};
# ZT IPv6 addresses of the two clan machines. Clan publishes these as
# generated vars at vars/per-machine/<host>/zerotier/zerotier-ip/value,
# duplicated here for /etc/hosts use (clan's var values aren't trivially
# readable at module-eval time on the consuming host).
sunkenShipZTv6 = "fdd5:53a2:de33:d269:6499:93d5:53a2:de33";
phantomShipZTv6 = "fdd5:53a2:de33:d269:6499:936c:48a:bbdc";
# Shared across both servers: /etc/hosts entries so data-mesher's
# libp2p /dns/<machine>.clan/... multiaddrs resolve over ZT.
clanHostsModule = {
networking.hosts = {
"${sunkenShipZTv6}" = [ "sunken-ship.clan" ];
"${phantomShipZTv6}" = [ "phantom-ship.clan" ];
};
};
in {
imports = [ inputs.clan-core.flakeModules.default ];
clan = {
meta.name = "homelab";
# data-mesher uses `<machine>.${domain}` as a libp2p /dns/ multiaddr.
# We don't run a DNS server for it; per-machine networking.hosts entries
# (set below via machineCommon) map "<host>.clan" → the host's ZT IPv6.
meta.domain = "clan";
# Inventory machines — required for `inventory.instances` role bindings
# to resolve. Host-specific NixOS config lives under `machines.<name>`
@ -37,6 +57,36 @@ in {
roles.peer.machines.sunken-ship = { };
};
# data-mesher — signed-file gossip protocol over libp2p (port 7946).
# Underpins dm-pull-deploy below. Files are registered + their allowed
# signers managed automatically via clan service exports.
# sunken-ship is the bootstrap node; phantom-ship joins via its
# /dns/sunken-ship.clan/... multiaddr (resolved via /etc/hosts on each
# machine — see machineCommon below).
inventory.instances.data-mesher = {
module.name = "data-mesher";
module.input = "clan-core";
roles.default.machines.sunken-ship = { };
roles.default.machines.phantom-ship = { };
roles.bootstrap.machines.sunken-ship = { };
};
# dm-pull-deploy — pull-based NixOS deploy via data-mesher gossip.
# sunken-ship is the push node (runs `dm-send-deploy` manually or on a
# timer); both servers watch for new targets and nixos-rebuild switch.
# Replaces the current dotfiles-rebuild timer once proven. `switch` is
# aggressive — rolls all default hosts immediately on any pushed target.
inventory.instances.dm-pull-deploy = {
module.name = "dm-pull-deploy";
module.input = "clan-community";
roles.push.machines.sunken-ship.settings = {
gitUrl = "https://github.com/DannyDannyDanny/dotfiles.git";
branch = "main";
};
roles.default.machines.sunken-ship.settings.action = "switch";
roles.default.machines.phantom-ship.settings.action = "switch";
};
# `clan machines update` connection target. Priority 2000 > ZT's 900
# and overrides the ZT service's root@ default. Using the ZT IPv6 as
# the host makes updates work regardless of LAN DNS / mDNS state.
@ -63,6 +113,7 @@ in {
clan.core.networking.targetHost = "danny@[fdd5:53a2:de33:d269:6499:93d5:53a2:de33]";
clan.core.networking.buildHost = "danny@[fdd5:53a2:de33:d269:6499:93d5:53a2:de33]";
}
clanHostsModule
../nixos/hosts/sunken-ship.nix
config.flake.nixosModules.dotfiles-rebuild
inputs.home-manager.nixosModules.home-manager
@ -81,6 +132,7 @@ in {
clan.core.networking.targetHost = "danny@[fdd5:53a2:de33:d269:6499:936c:48a:bbdc]";
clan.core.networking.buildHost = "danny@[fdd5:53a2:de33:d269:6499:936c:48a:bbdc]";
}
clanHostsModule
inputs.nix-openclaw.nixosModules.openclaw-gateway
../nixos/hosts/phantom-ship.nix
config.flake.nixosModules.dotfiles-rebuild

122
flake.lock generated
View file

@ -1,5 +1,29 @@
{
"nodes": {
"clan-community": {
"inputs": {
"clan-core": [
"clan-core"
],
"flake-parts": "flake-parts",
"nixpkgs": [
"nixpkgs"
],
"systems": "systems",
"treefmt-nix": "treefmt-nix"
},
"locked": {
"lastModified": 1776431860,
"narHash": "sha256-OHZEcmUPo5ccqnUvL7YUPyfQ45U8pWs+Doa1uwNCfZ4=",
"rev": "d65c0d270a9142bf8c5ef7717b70c738ee851c08",
"type": "tarball",
"url": "https://git.clan.lol/api/v1/repos/clan/clan-community/archive/d65c0d270a9142bf8c5ef7717b70c738ee851c08.tar.gz"
},
"original": {
"type": "tarball",
"url": "https://git.clan.lol/clan/clan-community/archive/main.tar.gz"
}
},
"clan-core": {
"inputs": {
"data-mesher": "data-mesher",
@ -13,8 +37,8 @@
"nixpkgs"
],
"sops-nix": "sops-nix",
"systems": "systems",
"treefmt-nix": "treefmt-nix"
"systems": "systems_2",
"treefmt-nix": "treefmt-nix_2"
},
"locked": {
"lastModified": 1776557977,
@ -113,6 +137,27 @@
}
},
"flake-parts": {
"inputs": {
"nixpkgs-lib": [
"clan-community",
"nixpkgs"
]
},
"locked": {
"lastModified": 1775087534,
"narHash": "sha256-91qqW8lhL7TLwgQWijoGBbiD4t7/q75KTi8NxjVmSmA=",
"owner": "hercules-ci",
"repo": "flake-parts",
"rev": "3107b77cd68437b9a76194f0f7f9c55f2329ca5b",
"type": "github"
},
"original": {
"owner": "hercules-ci",
"repo": "flake-parts",
"type": "github"
}
},
"flake-parts_2": {
"inputs": {
"nixpkgs-lib": [
"nixpkgs"
@ -134,7 +179,7 @@
},
"flake-utils": {
"inputs": {
"systems": "systems_2"
"systems": "systems_3"
},
"locked": {
"lastModified": 1731533236,
@ -152,7 +197,7 @@
},
"flake-utils_2": {
"inputs": {
"systems": "systems_3"
"systems": "systems_4"
},
"locked": {
"lastModified": 1681202837,
@ -425,9 +470,10 @@
},
"root": {
"inputs": {
"clan-community": "clan-community",
"clan-core": "clan-core",
"disko": "disko_2",
"flake-parts": "flake-parts",
"flake-parts": "flake-parts_2",
"home-manager": "home-manager",
"import-tree": "import-tree",
"nix-darwin": "nix-darwin_2",
@ -460,6 +506,21 @@
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1774449309,
"narHash": "sha256-brhZ8DmuGtzkCYHJg4HEd602amKm89Y9ytsFZ5uWD1w=",
@ -475,21 +536,6 @@
"type": "github"
}
},
"systems_2": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"systems_3": {
"locked": {
"lastModified": 1681028828,
@ -505,7 +551,43 @@
"type": "github"
}
},
"systems_4": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"clan-community",
"nixpkgs"
]
},
"locked": {
"lastModified": 1775125835,
"narHash": "sha256-2qYcPgzFhnQWchHo0SlqLHrXpux5i6ay6UHA+v2iH4U=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "75925962939880974e3ab417879daffcba36c4a3",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
},
"treefmt-nix_2": {
"inputs": {
"nixpkgs": [
"clan-core",

View file

@ -28,6 +28,11 @@
clan-core.url = "https://git.clan.lol/clan/clan-core/archive/main.tar.gz";
clan-core.inputs.nixpkgs.follows = "nixpkgs";
clan-core.inputs.flake-parts.follows = "flake-parts";
# clan-community: dm-pull-deploy (and other user-curated services).
clan-community.url = "https://git.clan.lol/clan/clan-community/archive/main.tar.gz";
clan-community.inputs.nixpkgs.follows = "nixpkgs";
clan-community.inputs.clan-core.follows = "clan-core";
};
outputs = inputs @ { flake-parts, import-tree, ... }:

View file

@ -0,0 +1 @@
../../../../../../sops/machines/phantom-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:zBvALOnnz8ubaEU5degFP9ySosybyXIMrDcWT5TuckgSiWZDlzZuRQyDIdSm+NglxV7+tIPf1W2CA28QWSm41y6ThFmmJEdXYRENbvpIX/LmAy8rTidVcmxjSt1nQR58PaG46YW6ODgeOyP0JZmieOdTzXrIZnfkugE+vvh8ZQKJqOqVeHCczqhHjNxghQyH1O3YKRhiNFftA4n6HJKCEbkMAz9rblQfZDXllt+dtdM+FpnAxQ2PD2lYiU+N2Z3F1SdgKWeIquQkqlxcYClWI5lVLjbwa8HpcVgP0PVHGAQu12Wk2brjYoJ/L3yq,iv:ZMZYHbjauV7RlclQdMEsgrcIoOVQGOESwWc9eleA8kI=,tag:K4rdm+/R/WrOtHJJIYVQHA==,type:str]",
"sops": {
"age": [
{
"recipient": "age18gtjh28qxeltg2r2tzxwl096crkqkqk8tjhersyf7mzdsddady7qs34x0m",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAyMFJHRXFiT1Y5RHVMRGV0\nSFBXYlorU2Nud25VNXhvcGpSUnRnNjZGVWk0CktreG9MaFBMai9FTWRYS3k0ekJt\neGlPem55RWNiTllpZjY3K1RMR05rTmcKLS0tIEhaMkVQaVpHTEs4dFFkOFhHY0Vq\nZTI1ZGlFS09LRWRxTlVaWFRKOG5UZlkKso5iv/TYlIkcXE0U9PQ7J0MpCJ5N+Bdx\nrClL1wZSsi1wlAWTxHqP5MvZjXT1EZb6jG5LOSHljUHxBCkPFWXQ+g==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBQcHoxZUtHN3c5YU1YUks3\ndkZMTHJSWE02cU9XODRSRVdIK3MveUx4UFhrCm91RTlYRWtSY0RKUnBGUCtwZjJK\nbjZ3eE5vV3Y1WGpzWHJ1K3duWFVlZVkKLS0tIG1hcnlic050SFN4U0NYM2xYd0xX\ndGRVU2pMRlc4NGxjdlRsUW04a01LWXMKZZQCsP6fafmBN7aoyuMp6L0F8umVoZrG\nwsi+ZpANujBIPbq4Fpzqti8zit2aFfrc3k8xkP2GW0VmHC+m8AfAwg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:04Z",
"mac": "ENC[AES256_GCM,data:DxmbajDV37PDo3T8CLrFn5zEfCtjGzERZg1wpmIkUA4jDev+FJAXRQudxyeTAc+z6POKzsq8QT6W40C/1Nq9i2J0Ihjfkd0dVerZoYTwJ/h6+shyy37TxZBC89LqGL5gz9tzHh1xN4EO3/ioUipsBRORqyb0HOoAkJYLAahr8UM=,iv:knW5/8lyM4/LAV3p9b3p4nWJDblUKI7dqd3zyIIJ7qw=,tag:LJSUVZ6A3WUs1+9JT2ogdw==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1 @@
../../../../../../sops/machines/phantom-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:Ow1yORsXj8qjXIs/ZXMVQDAQtz2Kfy5lBanVJDm6Ucs/S5ka3Gw6N1DYt+mDQ8Luh3i1uwMs0WcYH6pMZYG/01WhtywsiHbyoCZe9LlpHxHTzpCJgeCkMolMjIOHA6R/axyReEZomGQsPiF16MOwmvDhh2UbMns=,iv:mmAUWG9VxYMpsaFKWO6+BE3VxcV8qGeBJjNJtaHqHAQ=,tag:LIIYmL+nhea0tKa96k0VDw==,type:str]",
"sops": {
"age": [
{
"recipient": "age18gtjh28qxeltg2r2tzxwl096crkqkqk8tjhersyf7mzdsddady7qs34x0m",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB1TG4xcWlvWGpvWk1ZUm1O\nZkRpcy9RWmlSUGR2UUZxeTJEdUxOSmczMW1VCi9FZHNHQU5aWEtkUGM2TnVZZ1pN\nU1lmL3hBbGpFa2d6SkZHMEtIa0lhWWsKLS0tIDdIMXI5V0dwUVVpMnhoSWp4dklG\nOEpzTldzODU1MEprcmhvSE5VbXpCZVkK4G0YIl+gST/RLXrYZGM6j4x4h0hJrOzy\nAvqSHDhxyGIdUCka0NxIe/soNLgzf1CrF0eYGQLP+LX742ml2TQqbQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0bCtFbGh5UkNUQTQ1MGpT\nbjIrM0xVRXB5NjUxMmtlTnplOUlVRjdXNVZJCnppNzVpZFJndllhZDY0NFB1S3JB\nZU5ReUc5OGpUTGxpcndiYStobUZrS2sKLS0tIGV1azFRQWI0OVZhS3pFUmlqOWVR\nOHM4eEsyQmJsa0x3MVUzVllBSXNvb00K4MklrqgKvLwmaEQ4LU7Q6nJGA504s9dY\n6Db1Hgqd1Tx4lHhlxCcTnA9MKC330r/9yPjvYuvPtDaVFOQK+cZaOQ==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:04Z",
"mac": "ENC[AES256_GCM,data:qhFvYR+paGi8CE8cSGHOVHRThvhcC5KD13p2W8x6lmQpXepeI++FzJAX6s8sSc+XCOBMcH4fr4CmgH0+9cowj0H6qRzhuRDt/nt7VJil8UhTZCXk/ATPqugOLYUTTKzcxeJJ+A5MdRkfCO7pX89DtF/Ktb82zhSL7JrGOmpgVgc=,iv:BI06oxGHGJkGXoV8WItRHFOCFtp14WzBfjl9SvXlmy0=,tag:H2wt1ySmLgMIkxaz5FMJgw==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAKMM01/WXRAgjHVlKdspWmV3kgkX42f3UpMo5xxIyrhQ=
-----END PUBLIC KEY-----

View file

@ -0,0 +1 @@
12D3KooWCZV7p7FiinyNJQTMhu9Us2AnzK6hbZiaw9bmWsaHUDoZ

View file

@ -0,0 +1 @@
../../../../../../sops/machines/phantom-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:NoDGZvrn0A4hniARvQW53R+yI0CsvuUsrcHHe9iUIhtKp4JKiRjxEds+gsn8s2diVtgy7F6RPnm8KBTtXzRSs3EQPDDrZXdSC/4a+5va1mC98GVN1UqWRsH3dpF53eOHOQfWudFMQ1HKVp7eDoAZYmskjKmM71A=,iv:jeVDsZIKjqQx3+uzcZ5fF4cUinC2AHcz0tntp7CB5CY=,tag:kMwkWj2DhopOd127Q6ukWg==,type:str]",
"sops": {
"age": [
{
"recipient": "age18gtjh28qxeltg2r2tzxwl096crkqkqk8tjhersyf7mzdsddady7qs34x0m",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhWXFDRVZWQmRtNXkvZWxT\ndVdsZG1Bay9DdnlEK2hYZEVVNDc3a1BjSVU0Cm9rUjh4czRFZmNyRk9lcHFqSG5I\nQzdtdzROODA2dlBUSG5tODlqUFZsdE0KLS0tIE1ZQVFQTGNaTGVXRldPRmQwMUNL\nR1QzWEZyZk0rNDM0NjdJakowRXU1cTgKrwsFYYz/MVt9RNs/ck+md6/OKFjudvHp\nvEmOMkLRYvZL/Mi9mkwOebDj/kyi+aOW8d9C50OoDpNGy3x32UtQ3g==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwN3hTbjNscUdzTlJiR2xU\ncW9RWEFucktjSFZWdlRDeVVUUlQ0NDJWckdNCmc1YWw1dUFqQzM4eFlFVzJWbWxO\neGlTVlRCY1JtVXVhbyswYkxJd3ZCL2cKLS0tIGFzSXJ2THdpWm9UNElHWXNSeWhV\ndmlFYm44bGtEMG5sSUtwYUpqajlEZTgKR3cpnBggPo8/vwalbI76VUIa9QsNvdQV\nli2iEcP6ClbYFPYh3/EJ5gV0GBfFMO44gaynSVApR5hdDo/ev0ErDg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:03Z",
"mac": "ENC[AES256_GCM,data:jH2O5iyuTsy/ankCXKx2aEDfT/uwbPrcGZbjj1gGxL2cxxKdaMKKlFUfKY4Zgn5On4sQHSuPtV//XYiGqNh0v0G+6DGPAb7g6WiRYsuM4DSARZYRwhAQMOx9TWDURuOi0REx6htvc/Jl9lA+1pP/9MqoO1zsWC4WCnMxG3mxfD0=,iv:264mkPVu4f9hSY11Ab8MnueSq7LnF9rpBwrWOLlwLM4=,tag:PaxqOpw4qYSiSDk1c1Jt4A==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAfA9rDsTSGAz7dDC3pOFMA+LPj08SjxMIc5BU4q5/in0=
-----END PUBLIC KEY-----

View file

@ -0,0 +1 @@
../../../../../../sops/machines/sunken-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:HUvMiGEnMxlfYnnxX5RgZlw7SdETT/4BCkU7J1LhCeXH/BBN9PcT0jqhepyQ+3ybksk2zOTbxb0uiIodeaoSUKJM+jO1OKRElwtJObAVFPYw65x4TpH2n3j8JTWyIj9OdHFh7sXYGFK92GUsSGDWoZBV++AfzKa/KHw//8Zzy4ol3dgx6JPPQjvTvKIPoTaCre43RcB013UUdO2VRdh8x27KgybtlT8HXb6lAIRpuUS2cXCfbPW4E3ayinyKjVJ2iLUsmaSGSl8SltTk5GdGAYLEVTITH0Y1GNliZ04ENNuGdHVF5VlCIpuLcon9,iv:I2NUjIU5lUe8xpPMc1bYF0sHQ1pwlOO4Gz9ox/KCnrs=,tag:iqzJpTXMUdqUyp98hM/blw==,type:str]",
"sops": {
"age": [
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBBU2ZyRjRURkNjSjcyaENQ\ncVZ5d2tKTlJVemdRaFZZUURzbEZGVFNGRlFFClY5Y29pRCtSelhlY3VlV0x6eXJx\nNmF1T1YwVjdjL3ZSaGZUK0I3cHQzc0EKLS0tIGkzVE9mcldIbWpicU5YeEZjbHVG\nQ0dJQXd1cENLeFNtaUxHM3EzTDRHSFkKeXjt+AnbcQqWTpOw3TWJTbIH+Mu0q/Du\noE3Lv8b3LcVFPb/OQz3tNvd7FftjEbH6yArcLJfKz8YcKSG6/X+H9w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zy3q73pujauyajgfqwu0pnyy8732lzwvw87tu7p2xg3xuzaujc2qh6ql77",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHeThUamlhRGVnb0pHUUQ3\nTWtwV3QvZXF6ZmRyVkRrNXg4dVgwZk96MWlNClAxMWhua29JRkpCeUNXdE14ODNv\ndk9DVVVsaTJiQ29IL1BHdERHWUhVSDAKLS0tIEg1bTRSRklaTFBhN2FLd3NIek1i\na1ZEQ1FxYzhzUmhMQmVlQjJYZ2M4MWMKhUBYaEA09xLoc0GAShctrGPFUE4YUGGk\nYW86mPh4uudivrxs6CAhH0GVB7qwVtc9EGEw8bVA2STdNnCzr0JmMg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:04Z",
"mac": "ENC[AES256_GCM,data:yvwDLQ1unefwvtlad7/QBqKnWIsU3hALVB3ia6vYl5wnaRZgycE1IHrDLrHVV20ANAAs1gRKcZYUAAKLYKo4SqduBJgVSf3Hjk9t5VRjcBvRRFizwFbBa4rtWZMBrJS0cV99me6FoLioFLA+zGonRmmkiCEbWbBvSZdf1J04ixw=,iv:mD42aLv2IY8Dvt9qfTBQKH2ZHeI4537tRMlA8AXdyVk=,tag:Up/RwgH+fsJIpwPFzM6B9g==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1 @@
../../../../../../sops/machines/sunken-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:AlD+xw5DFrH8VwsNXqRgX/bdU2+bD1BbMSNMl+h6MloEFgMWGBt0kypqpq3LXj/p9Vtqr7rCy9N4wNAazWpQHGpA3Dv3Oka0S9xK6ghWJJWqDy1NiKkQR6a459jO7GiOzF5EGAfSp5fa4EDk/0LkIE/jkhg1ckg=,iv:+1Nsq644xQaXRIFMGfa6hv/T68YaVdNG7Aj/clKJy/o=,tag:YPpAcKkoxc6PRYxCJDcm/Q==,type:str]",
"sops": {
"age": [
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmVE15YnlYcFdQSnlxYWpi\nNmtHQ3JlZmltOHBRaC9iRlpUVDRiY0NHUGxzCjhrVU9jT29vRlFmeWJTNCt3VjR0\nVHFLNUVRS0k4eExrSHRPYmlZRHZkWncKLS0tIEFQSnUwWUxzbzY0TFREaWlPdUti\nVW1GTWpoVUxwdE9VT0h1Mm8wQ2JhaFEKkfS+cJVZ3aKJi+N4N76yilDJqutMLBKZ\nfaSHFyGwOkk9kS6pf53g6GHKmakJJa9KMVGF+d2FFLgnX0XX0H9qig==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zy3q73pujauyajgfqwu0pnyy8732lzwvw87tu7p2xg3xuzaujc2qh6ql77",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzQVlkR080UmhuVHg0RlFP\nQ3phcisvY00zNTJZUFdLWUJ0ekZWRXFVRkNFCjdUc0U5ZEx3aU5ET2pIdkJzK050\nTEMzMlF4Zm9KNWR1RWY5TXBVZi9saWcKLS0tIDBHZWJWQUxoUU5BRkYvL1l0elV4\ndi90SWdkRDc1akV3ZGdiOHBhc3ppTXcKKs7RUx4WTNdEOL0J0aMZiiUD4xpnJQFC\n+Vj/6GQJmeenB1znvWZbgMUKDRhufzzg1gd8oDbjfaI1H6UP1MilNw==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:04Z",
"mac": "ENC[AES256_GCM,data:44xy2P1es6SKe4s2aUo1MpwSlRH262TEp+TTRpOyB0ANAunJI5ViN0Db2aHaqq0aPSiYkquIvKeqzzX9pHYqZX9Dmr37PEvoCILP5wbarO5XRCc2N53vuarEfH6xyNQCoGNw2aujpqm5ero1jJbDkYlMu2dmrAtm7y4mazcjM7s=,iv:iGzaXP7DrsEXoyntt0e/f8/M998QG9hN1Vx4C92cshU=,tag:SDm2jnXPy/gN5woNWMRcPA==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAzYp9wRD7TpiZHYECCoYgMBdaYJWV31zbhN9u0xmRJIQ=
-----END PUBLIC KEY-----

View file

@ -0,0 +1 @@
12D3KooWPeiEFGKFd58Q6CTbVyCmD5RMXJk7RtcuZfpsshYDxpmy

View file

@ -0,0 +1 @@
../../../../../../sops/machines/sunken-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:E1Kds+yeaAIqu+az9a4QwyXb9yxIcq31IjrqqwLBnILp8oEIbPjaKbbCS/C8bbom9BeYixfeAlmo8iDE3IIdbq5W2vf/JNsLSulKF+9KnwA86aq1aNeI7akZGcs9Nvmly4lEUjCQH+rF3kGPNj/ji4uvNxm7FLU=,iv:LbOQMEBhSvwAWipVmF+NHW34CKXZla/YHYWPwySb/+M=,tag:EMHcLXPzUOABzy1+EGZw0Q==,type:str]",
"sops": {
"age": [
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwQVUxSGdkWFNZdm92OTFM\nZnZCeERNSEtWWnpiV0hLS2lsNzNCYkdBUDBJCm1kSzY1eFBGakVXVEV5TVFpdEts\nTkNiQmNHcnZZaTE1NnlVaCtFelF3clUKLS0tIHljYkM1QXVwKzlNNjJOOXlCT0FL\ncmdqcjRzeE8vR3VaU2JCcVdxTXJJd1kKR637rNaq3aceU7NxwBves13/2foYGzje\ncqnfkDARHDltiykBW0QXOfy8ws0XOrCXu5snd414WNeyGxgHuygXJQ==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zy3q73pujauyajgfqwu0pnyy8732lzwvw87tu7p2xg3xuzaujc2qh6ql77",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBZSTRBV1FGSkEzNHpoOHRE\nQU1rR0p5VVBtWXV0eXJ2L0ZWeW1iS3FDb21rCkpudnZiMjQrbEVzSWY1SEVhZk5v\naFV6NktldUkzaFlVQmdKNlFTalVoUEEKLS0tIDdrN2Vzejd6a3ByblJKcnhRMytR\nZm9DMFBFWSs1Z0IzeXlnWlVNWi9zbmMKULDR3ES98A2+BAXHuKvgod6IRQS9jbAK\nkGo8k2taP1+UhEIJbWY3WdfF621Eg/Ojc6+IQofrcrHTL+mu2MDN+g==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:04Z",
"mac": "ENC[AES256_GCM,data:YyEnzCEsCF2E5TuB9cbYaaMpDGqkCGYQ/fnS/+r/VsXINF9fVTRNbN8nYGWMsJvv3YOYkbGzfQXk0ydAEDYoQ7mFMjqtQjcLJqACkWLknkr366/CQ4eFnIvUMpiritjzPDX/8K7RFkCsWgtfIrKgKtCeoRkjbmxsKeP3gZWKqAI=,iv:G5zNZlVKmCS6297whHQpnSJXckwPS9pDpNcpFiAu8FE=,tag:VGaPrFF0swxqXTTsqZzgug==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAYFTwnobAoybi21WD7LbwId2Mt3RdMAg4j5i0gKJa9Rs=
-----END PUBLIC KEY-----

View file

@ -0,0 +1,14 @@
{
"data": "ENC[AES256_GCM,data:R4nCHoU/rU9JtO0++nwu+DWr9lB8iMb5CnH0YxG8kEp/UIFS8ZJrO/ZFR5f8NFAWLJQyhDb8rXyWehHbSBxqzEdT6topx0Jj7Ehx07pOsajLSaVLfHMBp3sgLWkMCNYFm76NRnq0aT7Fq6+eFACdU7K2ZgPPdGs=,iv:09RfU5lOKeXDVGQGI5qbWB9zEkUbS9sEQWqDo2TbIsA=,tag:VH4X0VKrzCaPYCM6wfvBrQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBWQTgxOTQrQVVWbkhlMC9h\nYlFtdk9XdUlUQTVjeU1USTk1U3YzaXlMN2dzCmtaSWRlb2JudzR4U090OGlSa2hu\neUgxNTRLYmd4RTY2Vkp4ZlQwQjlxRHMKLS0tIFNHUEhpRGJPM0VIV1ZwRnFjU3Ri\nek9NT3Q4UnBqUWJzai84alpLMWpwREEKFA1LUso4N82+YlX2QtsC8JpUBde4Z1yQ\nbCP9joC8c7CuSwfJGVm7JfL2KlbxPeihyJsswhpWoupWjlTL4Nn2rg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:03Z",
"mac": "ENC[AES256_GCM,data:R6yaI8KB40un4P9aq6mQsVsr2gRh0LEKJ+c/DG4zydWVUxQOcLtPfYEsOOo9LNXOF0XvbnvXrVwwBSIe5aWFyPELft3mOyxFgVkxuFNfi1ppWduFaVe1EnnNwy1AiIzLsCfVr7CM8KYffaLXreZ5R3vc/QUF0ORxzhWzzbndPu8=,iv:O384W8d6nhVONeOkT7CF4Fa1bQroITsZWV4jaIP/LF4=,tag:a3zabV6K+VdSKBypOT9ofw==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAJrN3VxpiOwikr4TlcjkjbdguTD37fPpgIDOBtrLGOkY=
-----END PUBLIC KEY-----

View file

@ -0,0 +1 @@
../../../../../sops/machines/sunken-ship

View file

@ -0,0 +1,18 @@
{
"data": "ENC[AES256_GCM,data:33EcsUpW/KKNFdpPihdj3Mv5hMEo3lBYNOzRe43H1SH/tpwy5dLGl2FR0KGavOyoBwWf8tL6E3rp2gSm0pt4mGCq4FpMZaa/D4rZ6WWpwNTuNFKUH4uGVs6vRULI6G5yMorzp91TAv2E3yoh6mOKcMdlvqr6K2A=,iv:UR8xtdl6iYCVH4EueD9HyL4BprBJPw9A1KBtPX41uAI=,tag:0c/LO8ggYvHiowTJTe0LdQ==,type:str]",
"sops": {
"age": [
{
"recipient": "age1g6y8gvcampqj5y3yzdajke2h5n7k6ckdg6a424cghy5325px7cmqjmmd28",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFOGRpaFBzYmJBZ092MnJw\nbXIremlST3k5UVY4ZkQ1SVc5amNjbjhTRng0CnYySmZ5Ym8xR09yOUhwVXoyM0tL\nTE9OaElDSXFUUG83dkhFVVlkTUxCb2MKLS0tIHM0WkovcGkvUW9OazZncFhsYTVN\nTnByV3QzeURhdUlyL3FJclpDL1J2T1kKMpSf2lxaEbOl9rcYixFkQoaL4fS0LLz+\nqtCzpbChDgsUZ4aAMowIgPVpH1es4WA412MTmmrhbznNXIdHxnZ40w==\n-----END AGE ENCRYPTED FILE-----\n"
},
{
"recipient": "age1zy3q73pujauyajgfqwu0pnyy8732lzwvw87tu7p2xg3xuzaujc2qh6ql77",
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBiNTA4cHZjaVdtVllkcmo1\nVlFuWVk3eEpNTWtTVUQvNy8yTGF0NkNjc0dJCjlMcm5taWt4R3g4eklIQ3hlY1ow\nK2dsaUMvTU84VkJOVG1uRTJBbDJ0WkEKLS0tIDgyNjZtU3VyNHlianAxcFY5Q0Ra\nU2pHQzd0Y3dUc1VSNDZuZ2RXem1qVkkK0iK/h8nLWZnDbXSNSXh1133Sctia5qsJ\nTsgRZt8amU8IxMF6IlgTQ0voEu5HJbKWzWqrD1tpab1dRil8+b6ljg==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2026-04-20T09:37:03Z",
"mac": "ENC[AES256_GCM,data:X/IjodUnCLcNfK251jkUuDU7YO5LXuau6zo5Aef7rX2XVsAFSUT4n+62RX8U4zNturCPkbInb3kUHVr+mCPgIG7k2GHRKZIFu0tbdb8aJlgg2IZ3Zswkd8yiRpqWygV/9rYGKpn58X7czj2aM1ydXr98qKUy8xgKcskB6CgN00E=,iv:2pjNT1o0QdwFRFKq4cTK3lDse652B58tMDHob9ppdM8=,tag:pxQLadQe5OfXscuKeHOa1w==,type:str]",
"version": "3.12.2"
}
}

View file

@ -0,0 +1 @@
../../../../../sops/users/danny

View file

@ -0,0 +1,3 @@
-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAu7f60z9GVfxiyIJRmH3zlz6QBF/nDzICHHGUcAgUd0M=
-----END PUBLIC KEY-----