main
1{lib, ...}: {
2 den.aspects.services.headplane = {
3 settings.host = {
4 domain = lib.mkOption {
5 type = lib.types.nullOr lib.types.str;
6 default = null;
7 };
8 port = lib.mkOption {
9 type = lib.types.port;
10 default = 8081;
11 };
12 cookieSecretFileAged = lib.mkOption {
13 type = lib.types.path;
14 description = "An age encypted file containing the cookie secret. The secret must be exactly 32 characters long.";
15 };
16 };
17
18 persist = {
19 directories = [
20 {
21 directory = "/var/lib/headplane";
22 user = "headscale";
23 group = "headscale";
24 mode = "0700";
25 }
26 ];
27 };
28
29 reverseProxy = {host, ...}: let
30 cfg = host.settings.services.headplane;
31 in {
32 ${cfg.domain} = {
33 port = cfg.port;
34 path = "/admin";
35 stripPath = false;
36 };
37 };
38
39 nixos = {
40 host,
41 config,
42 ...
43 }: let
44 cfg = host.settings.services.headplane;
45 in {
46 services.headplane = {
47 enable = true;
48
49 settings = {
50 headscale = {
51 config_path = "/var/lib/headscale/config.yaml";
52 dns_records_path = "/var/lib/headscale/dns-records.json";
53 };
54 server = {
55 base_url = "https://${cfg.domain}/admin/oidc/callback";
56 port = cfg.port;
57 cookie_secret_path = config.vaultix.secrets.headplane-cookie-secret.path;
58 };
59 };
60 };
61
62 vaultix.secrets.headplane-cookie-secret = {
63 file = cfg.cookieSecretFileAged;
64 owner = config.services.headscale.user;
65 group = config.services.headscale.group;
66 mode = "0400";
67 };
68 };
69 };
70}