The machines_dir() function was hardcoding "machines" without considering
the directory parameter from buildClan/clan configuration. This caused
update-hardware-config and other commands to write files to the wrong
location when a custom directory was specified (e.g., directory = ./clan).
Solution:
1. Added relativeDirectory to inventoryClass in Nix, computed where both
self and directory have consistent store paths during evaluation
2. Updated machines_dir() to use this pre-computed relative path from Nix
via flake.select("clanInternals.inventoryClass.relativeDirectory")
Fixes: https://git.clan.lol/clan/clan-core/issues/2906
The option curretly keeps it default value, even if set. This fixes the
value being passed through correctly, so that the user-specified value
is actually used.
Fixes: #5669
That means we rely on a certain structure of the user flake
these assumptions cannot be made. Their flake can have any shape and is not controlled by us
Fix dynamic shell completions by correcting parameter names
Dynamic completions for the CLI were not working because completion
functions used `_prefix` as the first parameter name instead of `prefix`.
This is incompatible with how `argcomplete` passes it's arguments.
Add regression test for the prefix parameter as well as some basic shell
completion testing.
The default 30-day expiration was causing certificates to expire
frequently, breaking monitoring. Setting to 100 years provides a
temporary solution until automated certificate rotation is implemented.
Fixes#5605
The client role now automatically collects and merges searchDomains from
ALL servers in the instance when not explicitly configured. This eliminates
redundant configuration and ensures clients trust certificates from all
servers.
Also uses lib.mkIf with .exists check to safely handle the openssh-cert
generator access, checking searchDomains first to enable lazy evaluation.
Within a clan.service the module can access 'role.peer.settings' and 'role.peer.machine.jon.settings'
While the current machine is jon, accessing the role settings is arguably a design mistake.
I didn't catch that problem, unfortunately this might be a breaking change
Prevents "File name too long" errors when users provide age keys directly
to 'clan secrets users add', as Path.is_file() would fail before the key
validation could run.
Fixes: https://git.clan.lol/clan/clan-core/issues/5522
Fix `extraPythonPackages` support in the container test driver.
It triggered the following warning from `nixpkgs`:
```
python3Packages = throw "do not use python3Packages when building Python packages, specify each used package as a separate argument"; # do not remove
```
The following `callPackage` usage triggered the `throw`:
```
hostPackages.python3.pkgs.callPackage
```
The change to a regular `callPackage` i`nvocation fixes this issue.
Added a container test with a popular package to ensure compatibility in the future.
Closes: #5459
This fixes an issue where check_vars() would add machine keys or authorize machines for shared vars.
These write operations should only ever be done on a `clan vars generate`, which `clan vars check` should be a read-only operation
- role="button" was removed at some point during refactoring which broke how the story was finding buttons
- button no longer has automatic loading state, instead it is now controlled.
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBHVC8wZUZJYUl5MXVNa2k5\ndGV1MnFWbUNLNVdxeEtCVUc3MTd0ck9aeFFBCnFhZW40amVYc3FlN1FPRTFSWTJR\nQzhNOERKbnRnSlJVeElNSEM5ZUJsZGsKLS0tIG1uNnlNN3MweHlYczNRTW9xSytu\neThzUmxKZTJBT2lCcTdiNUI4N3paTVEKgS9j2/GVt1KBoggUj9d6UK/mIlK4niLQ\nzVq2BHt3irxQpkpGUogXH2b86zSAOEJFzsL1Rk8HM1mogTG8jqf0qA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBlR3RGQ2ZLTkR3ZWxNVCsv\naXJHRjBiVUVYZVRIY2swY2xubGhmb3pLRkNvCldhQUV2WDlqYjZ4ZUFWYXkvUEEw\nZi9XRWw0Mi9mRENDcnI0aENDR2Z4MHcKLS0tIGFQU3Q4WEErbnBjOHpNR1BSR2cr\nRFg0anE1cHExT0sySmxuUks1R05nczAKZO3R6+f9co2+YGO8HPufoq1fLqqrdTWD\n4zqemMmG2BjMRDumxtcKp8CLaZWlJoP4e/+tonfdoe42qmNF5NJcFw==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzZWo4WGh1cWxKeDhDdlBm\nTVFjVFBIUU9xaGRkanNHaUVUUHN1czNRSUhNCkp5MmwzSGdycmsrZGhaRUhEbXBF\nNUhtdEF6bHZQOGJYUVhFVHlYc3FPODAKLS0tIDBRQ2VGT2IvU1F4MEVabzhYSFJq\nOWZmbGpkQmNSMnNKa0s4K2JXdGgwRlkKUQRREpG5H1mNHSc/cZrdMiSz0veJFR4N\n+W49XL/wQUZwajykwYj++G+dWDO7DQ+fpbB9w4mzbsAmCsXirseTLA==\n-----END AGE ENCRYPTED FILE-----\n"
We are still refining its interfaces, instability and breakages are expected.
---
This module is part of Clan's [networking interface](https://docs.clan.lol/guides/networking/networking/).
Clan's networking module automatically manages connections across available network transports and falls back intelligently. When you run `clan ssh` or `clan machines update`, Clan attempts each configured network in priority order until a connection succeeds.
The example below shows how to configure a domain so server1 is reachable over the clearnet. By default, the `internet` module has the highest priority among networks.
This NixOS module installs and configures Synapse — a federated Matrix homeserver with end-to-end encryption — and optionally provides the Element web client.
The example below demonstrates a minimal setup that includes:
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaeXRjU214aWk5ajl1aW9E\naGJlb1ViaVRmMTBHdkFDQUNDZS94WFZiNUNvCllmWTJBck9hR3U3V09VWDZwQ2xI\nd3ZEQnBIUG5ZSTVIdS8rQ2FMYVhyNk0KLS0tIEE1UG8rSzFyU01sVXhGVHpoaE9i\nSis4Qi9tMGFqbTNMTDZUVk1ZdXkrM28Km4VkfaOsZ69ckjvrg+os43H/O1IoWHzC\nt4LqZRz1Tk7/d1aLWavSPPjVYrCOMZeNBqGbQpGfjjuXrafClRNQdQ==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBNQS96MUFubVdOR2VCc2xO\ncTc5QnNHNTFpdURnSnF3dVhBQXQ3bnBuRW1RCngzSVlhSW9rNUxoSWdKcEtKVXc3\nQitLZ2NDUXBSUmxtVWpYRUlvOHVXcW8KLS0tIGZaWlRVak9NYmt2elpwYStYenRE\nanlkT3BET1FjQ2lFZkp3SXFMSkJSaVkKKkr+MNNqs6Ve3K5OrZfBEGlnc7OAthqf\nOZrP9NYOTMgkvhFsZTVpUS0zskry0iwmTNt+KeluYf0Tko8K53Kx2A==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3R1RHTGViTnRLVVkyM3J0\nbm96cGVPTlo4NXBNL0g1eEVSNG9DUkgwVFRBCmRKVTlMRmV3Tmg2RTZIclBlWlcr\ndzI5MUxhcllzbE1IMDNxa08zVkpITmsKLS0tIG01Y2dyQkY3UmRudFk2d0p6bThn\nemlaWnZoS3p4VHhMTFFwTm9VN0ttYzQKVbLFgtK6NIRIiryWHeeOPD45iwUds4QD\n7b8xYYoxlo+DETggxK6Vz3IdT/BSK5bFtgAxl864b5gW+Aw4c6AO5w==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXd2dVYmJIbUVVeXk5Nk1E\nekFiUldVVUhRTmE4dHRiTHNDdEMyS1pRV1RrCkNScGdXVSs4UU5id29DV0pZWDQr\nenV1QmpnOFk5aFpTTUxmb0hDVHZDdFkKLS0tIHpmalJtRC94bEhaUStmeUlHT21w\nd3o3UzJHZklxK0RCYUUxc2c3aG1XclkKEPq1ZgyGiAK/Hy4zT7wfdDfPEE3vMHpR\nzwQV5y3M3DmlnKQEvJu0DpQ334CyAcubZC7cswQdUrM8TPqJhb/TuA==\n-----END AGE ENCRYPTED FILE-----\n"
- Generates and persists SSH host keys via `vars`.
- Optionally issues CA‑signed host certificates for servers.
- Installs the `server` CA public key into `clients``known_hosts` for TOFU‑less verification.
- Optionally issues CA-signed host certificates for servers.
- Installs the `server` CA public key into `clients``known_hosts` for TOFU-less verification.
When to use it
- Zero‑TOFU SSH for dynamic fleets: admins/CI can connect to frequently rebuilt hosts (e.g., server-1.example.com) without prompts or per‑host `known_hosts` churn.
## When to use it
- Zero-TOFU SSH for dynamic fleets: admins/CI can connect to frequently rebuilt hosts (e.g., server-1.example.com) without prompts or per-host `known_hosts` churn.
Roles
- Server: runs sshd, presents a CA‑signed host certificate for `<machine>.<domain>`.
- Client: trusts the CA for the given domains to verify servers’ certificates.
### Roles
- Server: runs sshd, presents a CA-signed host certificate for `<machine>.<domain>`.
- Client: trusts the CA for the given domains to verify servers' certificates.
Tip: assign both roles to a machine if it should both present a cert and verify others.
Quick start (with host certificates)
@@ -80,12 +80,13 @@ Admins should trust only production; CI should trust prod and staging. Servers a
};
}
```
- Admin -> server1.prod.example.com: zero‑TOFU (verified via cert).
### Explanation
- Admin -> server1.prod.example.com: zero-TOFU (verified via cert).
- Admin -> server1.staging.example.com: falls back to TOFU (or is blocked by policy).
- CI -> either prod or staging: zero‑TOFU for both.
Note: server and client searchDomains don’t have to be identical; they only need to overlap for the hostnames you actually use.
- CI -> either prod or staging: zero-TOFU for both.
Note: server and client searchDomains don't have to be identical; they only need to overlap for the hostnames you actually use.
Notes
### Notes
- Connect using a name that matches a cert principal (e.g., `server1.example.com`); wildcards are not allowed inside the certificate.
- CA private key stays in `vars` (not deployed); only the CA public key is distributed.
- Logins still require your user SSH keys on the server (passwords are disabled).
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA5b0Y3aldQWXJyZzU3aGZU\naWpOK1VXdUVlSUVvZzJqSDVCekQ0Z2JxblRvCmFWd0c1SC9jckMweTIrNmg0VnN3\ncTNwMkVTL0ZyT3RGeUs2NnlNb21GWTQKLS0tIEpGM2FacUNoakJ0dlJwMWZMNU0x\nVWhmV1pDOTRFNExpVHBTRUx2L2ZaMVUK+ka9oqcvoLjwwUqIol0rU1VsJHhs4S1P\nWpKKPetUPEF4xxWj0OdeMc40XCTjl6CBdbtcrslH3tuZHjeSWQ6QCg==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkNlpCNGR0SHVtVzJ2K0hM\ncng1ZWlTSGQzWndXVWhlbEZMN25TUklXV1I4Cm9PZkJ3Zi81YXoxdzVPTFI3dE1a\nUnJnUmJPbi9CYmdFL2ltaTRSQ1MreFUKLS0tIDE4Y05IamJjL0huY2l2YU4zbDJs\ndTl1b0wzaTM4MndlcFZYVThqbWtVeFUKuSZLJpUrccuusJPU2xWHw19wTN8mKZW3\n1GJJjlb79rZp/RbSMxFxkyVHgu+F9kbpRgViICJSWkeR495786oArA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLM3lNL1UyUjhRdFBvenlv\naXBTYXJva0hCTS8vK1hCYmdQdlpBNGFNTkNrCmVTbFROTWVWRzZyc2E0SjVDT1hs\nMm9qT0plcHNJaWczcWJTd0llYldGMVkKLS0tIGh6M04yQ3RiMGVYbTNYMEdCVTNK\nUDhaS3FSVWl4ZGlPYTRodW80VElsZ1UKxi48UZpxuu7gkRtQrCi4//suOpuFY6sl\n8b1xcN/tMn2MWW9hvx4K4qJLXTWOm+9GiZqJ51JBb0hihRh7fC3SfA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBGK2Z5OGFsVjBJcGFITENH\nL205TDBaNkRvQ3ZBbGVDU0wrWnl5QkJaSFZNCjhNSXpMTTd1ejlqbVNBUDZ2TlFn\neUhNdEh4M1RhQnFabHpaMVd5eG11THcKLS0tIE9PS3JlVFVPNG5sM3hpWG95V1ho\nSXBySU1SUExkVHNHZElmQWExTVN3cHMKvzdlCWP8/9xviu/9AMxw/4ZyXo4O3AE9\n84IQBDO4GYrqnXvOroxjsNCDrCBDH0WPuYAphctJvyI5SSAtL4uHhQ==\n-----END AGE ENCRYPTED FILE-----\n"
We are still refining its interfaces, instability and breakages are expected.
---
This module is part of Clan's [networking interface](https://docs.clan.lol/guides/networking/networking/).
Clan's networking module automatically manages connections across available network transports and falls back intelligently. When you run `clan ssh` or `clan machines update`, Clan attempts each configured network in priority order until a connection succeeds.
The example below configures all your nixos machines to be reachable over the Tor network. By default, the `tor` module has the lowest priority among networks, as it's the slowest.
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjZnpWd0grazhjak0ra3NK\nSEpVTWVEaXEzc3ZIeloySXBqVk01SVNsVmtzCk5weWJCSGNlb2FRM0RWVEYwTHlC\nTVFBd1cvYlZrNlQ4TFRydFNzWXNicE0KLS0tIFZ5WllRNEI0Q3hQaVU2WjhGNDFr\nLy9pSXU5Y2FINy9LbXg4dzdHREQveE0KyxWDDyRpo0eTIXj0lHQtOunLtAP/Q+70\n+GvfjW7WXHXvXyg6CXzpCy6F6UWie4LHO9VrJM2mTjoh+q4l5DT6CA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBLWEV0STNnMlRreElVSk1y\nRTB6cCtWc0tkNUEycklSU0x5cHZwN3FIQkcwCkJQemRZOWZFSit3QmZ2a3RrOGFh\nUEhLSEZLRW9lWkN2b1VKK2EybUYvcTQKLS0tIGt6VWFmVHpNc2c0T3E0TjBYeWp1\ncjFCcEd3MTlYVGRsRlpXWWRsWlU0dkEKe5NUijC+GVxzj8bMEY6v+qHw9iylpwQz\nFLKneLikKVcRYoTYecimaQdUbYCiEwUB7KCpENcNmjZx6eVmTvGeMQ==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6T1hheHNaZ2h6Mlc5WEJq\nUk8zTC82N2ZHUUJQK0VLdXBkNEFnNlRHamh3CitrWGpVVGQreDRZdTF5L2VXNENn\neThUd0tjUWpCNW01QklZakx6NnNoT28KLS0tIGVOLytqUGtsaWhFbi9mU2ttMmow\nOFhwVmkyVDdZK09ramZOYktFdkV5R1EKWGseGbOtLS45gb6fb8LFzlfdsRGC7x9B\ncn03oAcfC2Yo/kqoT4tjQF/COn408SBkytwZ3GbL8Bnul/RyjcHJNQ==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvcGJEM3ZLYUJleStRWkpy\nSmwzZXVXWUZTY2htbzk0UGlxV2gwWExyT21nCjRGYmFyRnNBYnJQa0hSRGtCZDdG\nTjdHMG94Q3diZnVsRy84TXJXKzJrTW8KLS0tIEF2dk1uSW5NQ0JxRFdmczNSYmJF\nRThyTnY5QVlOTEZ4eThpdEJmOFhvVFEKA7oltxLLS3w3LOOS2S4RZNJreZftJD2m\niXtDAfWOKLGYTdhfttzWWfxFHt/72OCL1WKm1COgmzBznJJ+RBehEw==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5ZmZ3d0xNRkQycnFaM2pB\nL1ZLeVRFQXozeGFpMGtnc1FBR20ycXl2UmxvCk42QVVieC8waDBwenhVdVFTc2M0\nL2lSM0QvUzhDMXFjTVVnZGY2YXcxakUKLS0tIHZiTGZsMEZ3elVkK2p2Q1kyNXFZ\nTmJybzJaSnZyZE5sb2ZPUjZyNjRhak0KjIyzfPw1BHYJ5REWRSoKG9cY2b23dbdt\ndHioloXv3tW5bTSWytuDSQ5+xzruJqr1w099EZ6Gl6aeeo0oQQkpyw==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBxN2EwVHN3SENVTjdjZGRi\nQmJOWlNGYmpmM1BnZnpYWGhaSlRaUVJIODFRCkhhMUhyZzVWWk53SDBwSVBVZGVY\nVUpMTm9qWTIzc3VwdGJHcUVWVzFlV0UKLS0tIDBBVXdlS1FFbzNPSnlZWWtEaDJi\nK215OWQvMVRCRUZyQjFZckJFbHBZeDQK2cqgDnGM5uIm834dbQ3bi3nQA5nPq6Bf\n0+sezXuY55GdFS6OxIgI5/KcitHzDE0WHOvklIGDCSysoXIQ3QXanA==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBUdDNFSE8zdm00QTc1L3kx\nUkZYMFRwVTZkZDQxZTZEWlZBV2pSZ1NidGxvCk5MRE5Da0I1R0MxRzBFYVpNNWwz\nNGdDazh4cll5MHlDUGZ4N1lZb242UlUKLS0tIFBwWVhpS1JEc2JBWDZKdFBCUUF3\nRlVRZTR4YW93SXZlNXhjWlFDYnd5UEEKcZ7sbVO4ZhhTV4pNinJhk7+qWk4nr2E9\nvjQCXZvAMhXP485S+Dbiuvc426cOOL+KrOelMFRJgZg3sDtuN4AFLw==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSA0NDB5SVcrU0V6akYwbDlv\na1BuSm5XbjYwN2ZkZWtIcnhBVHBTWGFxd24wCnZTVGlPRm5uZEd3QXYwdFRMS09K\nWWw5N2RJZ3d4N0VDMWZmM2lkYVM4VncKLS0tIGplTDVka1VoUVdXMU9VS3hYSlZ1\nRjZGL25hQWxHWEx3OXdQamJiNG9KaDgKk94uXPuCE/M4Hz/7hVKJPHuzQfbOQi/9\nVfR2i17Hjcq08l68Xzn+DllQEAFdts2fS96Pu4FFKfiLK7INl/fUOg==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6RHhiQVFKMCs2NkZ6NENl\nRzUxVWRXWmxzcGhRSXNxNjBIQ1RkN2tpN0RRCmF3QzRvQXdzSVFFcnpBOHdmRFpL\nVzBoSWZKQjJLVDRkZDdlbEVZR2ZzRTAKLS0tIHlOR1dmWEk0UTNYa05nbVR6Q2pn\nVXFDMnNxZ0xJd1ZnVWhJSVlJYmZxQUkKnWc72eUjsVpeipP76ZoiPSGockLXMR/p\nUswkQR01sCcvuPV0sJLBUK+PRMEKBjUH7O9opOvzCsTTzIVaJyLpRg==\n-----END AGE ENCRYPTED FILE-----\n"
"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBSVXUxNGpGYnFEdlpNNUwv\nTEo3a25sSnhHNmlZb0h0QTBwUlpjTFBtZXljCngxcUpxTEZRZlJoTHAxeFRGWXpL\nUzM0eTFOMXQzS0ZEak9NOEJzbHlGS1kKLS0tIFpkWGcwVnVIVUZEYkNlcWVMUTdE\nR21qaTgxT3BpUzVoRUlQODlyRUxodFkKYQPKrDaogCO3m9JfFHc8IrGauipcWPRF\n4P51UqhAUtWwZLdiUIoY5ucG+NaDzBxxUJqJYlUqkQMbW/OvHihu9g==\n-----END AGE ENCRYPTED FILE-----\n"
}
],
"lastmodified": "2025-05-29T13:15:02Z",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.