From d43519fc29e90f3608ed3bdb809f40cfe38ff8da Mon Sep 17 00:00:00 2001 From: Jordan Holt Date: Mon, 1 Sep 2025 23:06:36 +0100 Subject: [PATCH] kanidm: add provisioning --- hosts/common.nix | 3 +- hosts/library/ai.nix | 7 +- hosts/library/secrets/open-webui-envfile.age | 10 +++ hosts/vps1/default.nix | 2 + hosts/vps1/kanidm.nix | 77 +++++++++++++++++- hosts/vps1/ssh_host_ed25519_key.pub | 1 + .../generated/vps1/kanidm-admin-password.age | 7 ++ .../vps1/kanidm-idm-admin-password.age | 8 ++ .../generated/vps1/kanidm-oauth2-gitea.age | 9 ++ .../vps1/kanidm-oauth2-open-webui.age | 8 ++ ...d8414f6f7e26655fe0f-open-webui-envfile.age | Bin 0 -> 512 bytes ...34f22226832529aa8c-kanidm-oauth2-gitea.age | Bin 0 -> 382 bytes ...d48c4e1d842774b1-kanidm-admin-password.age | 7 ++ ...c175c5a6d38e-kanidm-idm-admin-password.age | 8 ++ ...5cdabd3e84d46-kanidm-oauth2-open-webui.age | 8 ++ 15 files changed, 149 insertions(+), 6 deletions(-) create mode 100644 hosts/library/secrets/open-webui-envfile.age create mode 100644 hosts/vps1/ssh_host_ed25519_key.pub create mode 100644 secrets/generated/vps1/kanidm-admin-password.age create mode 100644 secrets/generated/vps1/kanidm-idm-admin-password.age create mode 100644 secrets/generated/vps1/kanidm-oauth2-gitea.age create mode 100644 secrets/generated/vps1/kanidm-oauth2-open-webui.age create mode 100644 secrets/rekeyed/library/f46a5bd752fddd8414f6f7e26655fe0f-open-webui-envfile.age create mode 100644 secrets/rekeyed/vps1/3c5deb9c71bac734f22226832529aa8c-kanidm-oauth2-gitea.age create mode 100644 secrets/rekeyed/vps1/80ea265ad53ef54ed48c4e1d842774b1-kanidm-admin-password.age create mode 100644 secrets/rekeyed/vps1/a8f9724475694d2a470fc175c5a6d38e-kanidm-idm-admin-password.age create mode 100644 secrets/rekeyed/vps1/d4527fa57d6907c78335cdabd3e84d46-kanidm-oauth2-open-webui.age diff --git a/hosts/common.nix b/hosts/common.nix index 2ab28f4..abe5fbe 100644 --- a/hosts/common.nix +++ b/hosts/common.nix @@ -16,7 +16,8 @@ age.rekey = { masterIdentities = [ ../secrets/yubikey-nix-primary.pub ]; storageMode = "local"; - localStorageDir = ./. + "/secrets/rekeyed/${config.networking.hostName}"; + generatedSecretsDir = inputs.self.outPath + "/secrets/generated/${config.networking.hostName}"; + localStorageDir = inputs.self.outPath + "/secrets/rekeyed/${config.networking.hostName}"; }; nixpkgs = { diff --git a/hosts/library/ai.nix b/hosts/library/ai.nix index 3f715da..57aa391 100644 --- a/hosts/library/ai.nix +++ b/hosts/library/ai.nix @@ -1,13 +1,12 @@ { - inputs, config, pkgs, ... }: { - age.secrets."files/services/open-webui/envfile" = { - file = "${inputs.secrets}/files/services/open-webui/envfile.age"; + age.secrets.open-webui-envfile = { + rekeyFile = ./secrets/open-webui-envfile.age; }; services.open-webui = { @@ -30,7 +29,7 @@ OPENID_PROVIDER_URL = "https://auth.vimium.com/oauth2/openid/${clientId}/.well-known/openid-configuration"; OPENID_REDIRECT_URI = "${publicUrl}/oauth/oidc/callback"; }; - environmentFile = config.age.secrets."files/services/open-webui/envfile".path; + environmentFile = config.age.secrets.open-webui-envfile.path; }; modules.services.borgmatic.directories = [ diff --git a/hosts/library/secrets/open-webui-envfile.age b/hosts/library/secrets/open-webui-envfile.age new file mode 100644 index 0000000..b3edd3d --- /dev/null +++ b/hosts/library/secrets/open-webui-envfile.age @@ -0,0 +1,10 @@ +age-encryption.org/v1 +-> piv-p256 a1N2XA AqHsJTdBE6LT9QJK7Dek6b3zA/PaqAmma7uRdKHdQQym +KMB+yq8M+eej5pg7MHFBqzYhQhVnrPpTevDVo1RZn5Q +-> m;#M[T-grease > G>`e0C&G OS +ichBG8145Jl9vthZfVHcznJmi+c81HHZfd7UGzdfP7TR1wp9ub6IXiqK9KRe7ga7 +N3osvWzwiwCI5oN0NA +--- ILq3bk5+xuZ4CV7J/rQkYBMz5wG2dHzn+G+cvEqUSRw +j +X+rjZW pk%ǗxdC5mͧ '[wx雸#O7bC'83b{_%_s&ѹrr, 5L8yCO6ok}_imu3|f 55AV>+E=EaE-Ԑ^Qj76PbE8*4߄ OtS +h<׺MfEZ| \ No newline at end of file diff --git a/hosts/vps1/default.nix b/hosts/vps1/default.nix index d2627dd..fde28ed 100644 --- a/hosts/vps1/default.nix +++ b/hosts/vps1/default.nix @@ -20,6 +20,8 @@ hostPlatform = "x86_64-linux"; }; + age.rekey.hostPubkey = ./ssh_host_ed25519_key.pub; + networking = { hostId = "08bf6db3"; firewall = { diff --git a/hosts/vps1/kanidm.nix b/hosts/vps1/kanidm.nix index a4c7bff..5ea45c3 100644 --- a/hosts/vps1/kanidm.nix +++ b/hosts/vps1/kanidm.nix @@ -6,14 +6,26 @@ let baseDomain = "vimium.com"; domain = "auth.${baseDomain}"; + + mkRandomSecret = { + generator.script = "alnum"; + mode = "440"; + group = "kanidm"; + }; in { + age.secrets.kanidm-admin-password = mkRandomSecret; + age.secrets.kanidm-idm-admin-password = mkRandomSecret; + + age.secrets.kanidm-oauth2-gitea = mkRandomSecret; + age.secrets.kanidm-oauth2-open-webui = mkRandomSecret; + services.kanidm = let uri = "https://${domain}"; in { - package = pkgs.unstable.kanidm; + package = pkgs.unstable.kanidmWithSecretProvisioning; enableClient = true; enableServer = true; clientSettings = { @@ -28,6 +40,69 @@ in tls_key = "${config.security.acme.certs.${domain}.directory}/key.pem"; version = "2"; }; + provision = { + enable = true; + adminPasswordFile = config.age.secrets.kanidm-admin-password.path; + idmAdminPasswordFile = config.age.secrets.kanidm-idm-admin-password.path; + + persons.jordan = { + displayName = "Jordan Holt"; + legalName = "Jordan Holt"; + mailAddresses = [ + "jordan@vimium.com" + ]; + groups = [ + "gitea_admins" + "gitea_users" + "jellyfin_admins" + "jellyfin_users" + "open-webui_admins" + "open-webui_users" + ]; + }; + + groups."gitea_admins" = { }; + groups."gitea_users" = { }; + systems.oauth2.gitea = { + displayName = "Gitea"; + originUrl = "https://git.vimium.com/user/oauth2/Vimium/callback"; + originLanding = "https://git.vimium.com/"; + basicSecretFile = config.age.secrets.kanidm-oauth2-gitea.path; + scopeMaps."gitea_users" = [ + "openid" + "email" + "profile" + ]; + allowInsecureClientDisablePkce = true; + preferShortUsername = true; + claimMaps.groups = { + joinType = "array"; + valuesByGroup."gitea_admins" = [ "admin" ]; + }; + }; + + groups."jellyfin_admins" = { }; + groups."jellyfin_users" = { }; + + groups."open-webui_admins" = { }; + groups."open-webui_users" = { }; + systems.oauth2.open-webui = { + displayName = "Open WebUI"; + originUrl = "https://chat.ai.vimium.com/oauth/oidc/callback"; + originLanding = "https://chat.ai.vimium.com/"; + basicSecretFile = config.age.secrets.kanidm-oauth2-open-webui.path; + scopeMaps."open-webui_users" = [ + "openid" + "email" + "profile" + ]; + allowInsecureClientDisablePkce = true; + claimMaps.groups = { + joinType = "array"; + valuesByGroup."open-webui_admins" = [ "admin" ]; + }; + }; + }; }; # LDAP server binds to tailscale network interface diff --git a/hosts/vps1/ssh_host_ed25519_key.pub b/hosts/vps1/ssh_host_ed25519_key.pub new file mode 100644 index 0000000..c35e7a4 --- /dev/null +++ b/hosts/vps1/ssh_host_ed25519_key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAII9NBbTqjs709LTRgeBV306s3SI7WuQMbor195QprBFc diff --git a/secrets/generated/vps1/kanidm-admin-password.age b/secrets/generated/vps1/kanidm-admin-password.age new file mode 100644 index 0000000..7dadb97 --- /dev/null +++ b/secrets/generated/vps1/kanidm-admin-password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> piv-p256 a1N2XA A54fi3eKkgTq6VOnMm2ze+aHVpJ0NNsqT+w7nvYoznbM +t/dRpZzqO/mX7iHLxbvzVxdmTECkRFPA5jmYfZwbMR0 +-> O_h4MVE-grease {- v~ 05B3 +Clwo0RqQmOGC24XDUIA+4MfDLlWnc3SjR8Kk0Wokqf6R5QFobU4 +--- loq7Xutgff/pptwqLMmjVA1uZwtDE1z6wsORzSgY80w +"2Q`D $N<.=58%gEl[TIy lf8/pP(_UĐm+ \ No newline at end of file diff --git a/secrets/generated/vps1/kanidm-idm-admin-password.age b/secrets/generated/vps1/kanidm-idm-admin-password.age new file mode 100644 index 0000000..fdf969e --- /dev/null +++ b/secrets/generated/vps1/kanidm-idm-admin-password.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> piv-p256 a1N2XA Aul2Rho3PfWaREBYYJr5FpyV5+eQ18GY5DT1dB9QcAH8 +wDHmswR1WRsqCrqRv6imy2oeo+FP3Z1kDpWvr/IzcUY +-> 4-grease x K>#G$! +WbQ2yy2Pkkn0BYBR+y0tPLCFTN6cKEYGEp4B+nagPf42XONM3Q4ewp5UJF25rAiJ +LsUecsY7dvX1n9HAz6uBwMm6Xt4 +--- iPJfeOsee5HmeCB5NRHSPIywjhUrjdhsoEx9aTxbrZs +^ɽ$jFP @銿[|Np2|[I>>%f֧lW!Av`28jVffJ \ No newline at end of file diff --git a/secrets/generated/vps1/kanidm-oauth2-gitea.age b/secrets/generated/vps1/kanidm-oauth2-gitea.age new file mode 100644 index 0000000..63b2a22 --- /dev/null +++ b/secrets/generated/vps1/kanidm-oauth2-gitea.age @@ -0,0 +1,9 @@ +age-encryption.org/v1 +-> piv-p256 a1N2XA A5Gj5hu1YQbUrm3IK35oDUHhnohr594lykadF+Smf+LB +grnVZatvY80rTTQR8bZphg/25aa1cKJYUGh+jYGqi7A +-> 0-grease 6#aWp kp fD7ks3KL -)qyQ +FH1L4t8VAxZIOeP6bPJV3qdaBXPXGkuroABtMs7D88WzHduNjBoETZH47zekRDVM +BAGAdcqSHuGyCp7EA4lgttN/vfA+8fAbcit/p98TTiGQbXZ4YYg +--- KB5apFUmA/vu8OLpReNzr2zeDyig5NZ8iBXdy5XDbXM +ԝrŧ)NS8XsGxq%Co +S6ܐL\Uz piv-p256 a1N2XA Ah6buspw/yLQJuiyWr0t3Phy+U3HhRY2t0SofqISzHmJ +pVYmmBoqXD9l55DUIad9D/0h/vhXmeMauK+xaBpX0cM +-> M)*gn$-grease _b3%6l sH|2-zq P%h +CWIfvXf9R5QvRXzv8wv+vB8nXLk0eTxy/htCUSm2ujjw +--- 1t/2tU8qFo9C2yH3ZtsZIp8ZMNEjrecLh2HkDVnKTx4 +\eP,tVxAKe}\] +`5vA8D2wX`~-uT;%Umn(SB-7LuM+YT%h+n(b*^;bRdP=31C!l5CNiY?0!}o8z@@9JtKgN9n-`u}shyka9TuLZ@9z?9?q{0m?c(9#RTZ3{ zljNUdUS6zSQEu#>%$0a?W`ML_oVKmasR?b|dtP~a?EcC)RU`PgR^YFg+?kE>$}Q7( zlp9N=urmLY{<39n!R-WT#X`H8I}@uC-&CD$lZ$6G56Jtw@07`ovI$a|LYtcz-}154 zZrs_i_Ey@1+^-n?4 z8$RAR=Ra@d^sm>nmp&7fpEIjFKGSyMwYLgZ&r8poJWKoL&`o zmf_vQqYHzW4jT0_v>dE0U@ePH+ElrAZSu;^neYGf%~feobmVDiY;1VrW38URlm76A J)!)?;mjLvF&4mB} literal 0 HcmV?d00001 diff --git a/secrets/rekeyed/vps1/3c5deb9c71bac734f22226832529aa8c-kanidm-oauth2-gitea.age b/secrets/rekeyed/vps1/3c5deb9c71bac734f22226832529aa8c-kanidm-oauth2-gitea.age new file mode 100644 index 0000000000000000000000000000000000000000..43546a2efbce59aec7bacf53420cecec76cef079 GIT binary patch literal 382 zcmYdHPt{G$OD?J`D9Oyv)5|YP*Do{V(zR14F3!+RO))YxHMCU7@vrpEaa1tQFRmzb zOtcL5NcAhs@y-b^@~Cvq4KOfHEbz6^E=%_+3-b$g&Irs3cje0VD$mIB%r5t;NQy8I z57IYwF7VN=3W-RL$SX=I%t|gv%TG60Isl$vZD;mMU2;O^`i9AzHhpW~WaX_04<&ZVoXtKetq zR9P9I?;hz_UTmD0=@nF&?~{~X<`U#+UZw4p8WE7=>0e?HoNkmG%5{U&=>S*#^VAcw z+~*v6x4z?)TR+49-c6Cpxu&vl6BPTFx=g=h7hv{rsxXJb>LZsM^zKd+{q+9`jZc8i_|08pHap8x;= literal 0 HcmV?d00001 diff --git a/secrets/rekeyed/vps1/80ea265ad53ef54ed48c4e1d842774b1-kanidm-admin-password.age b/secrets/rekeyed/vps1/80ea265ad53ef54ed48c4e1d842774b1-kanidm-admin-password.age new file mode 100644 index 0000000..88bcae5 --- /dev/null +++ b/secrets/rekeyed/vps1/80ea265ad53ef54ed48c4e1d842774b1-kanidm-admin-password.age @@ -0,0 +1,7 @@ +age-encryption.org/v1 +-> ssh-ed25519 lOyIlA OQXbnkBzK8DL7wJkbHWo/XUlLQHjBEVu1xMzmhB78Xc +vGcN1v+YxXidGs7Z3hvZypklIZVF1/J6DZpx8JId/hw +-> mfI^2]-grease , +2C8Bs6nnhfatjdqc/Wc +--- tuwRBOHiF0e6lgo4bK4Ui+bjjuTf5uZJgDJnpqf1seU +J\g;V qFNq[7lfw 㝯i|RDLR#%u-A1–=AWc \ No newline at end of file diff --git a/secrets/rekeyed/vps1/a8f9724475694d2a470fc175c5a6d38e-kanidm-idm-admin-password.age b/secrets/rekeyed/vps1/a8f9724475694d2a470fc175c5a6d38e-kanidm-idm-admin-password.age new file mode 100644 index 0000000..5f37bce --- /dev/null +++ b/secrets/rekeyed/vps1/a8f9724475694d2a470fc175c5a6d38e-kanidm-idm-admin-password.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 lOyIlA XbDvpING9Qe/x3sNWrqn2vqEw2SvgP79ApCrJTTGuiM +cOaoXvYgPH7egMF1MT4gtaMHnoHWgeKeEjkwCoOQf74 +-> y''zjcK-grease J y ,CxRN3 +2kaqVO6qm24DPq5fhEN+AM+hPvW3VPHKlzuMy8SLeW/3um8bXNmFdxwzfkDoFSf3 +viYrDFmlY7+RTFt6JADBs67eYlQblBgZwTo +--- NwBzcAYM5hOyvIsRVLYH8ez6gn8Z3yxmX8Tfz1hETz0 +g>@lg[RٽXv9ߵ"\hۺUy4ܞO =zxB@DzIJOMLH< \ No newline at end of file diff --git a/secrets/rekeyed/vps1/d4527fa57d6907c78335cdabd3e84d46-kanidm-oauth2-open-webui.age b/secrets/rekeyed/vps1/d4527fa57d6907c78335cdabd3e84d46-kanidm-oauth2-open-webui.age new file mode 100644 index 0000000..995eac0 --- /dev/null +++ b/secrets/rekeyed/vps1/d4527fa57d6907c78335cdabd3e84d46-kanidm-oauth2-open-webui.age @@ -0,0 +1,8 @@ +age-encryption.org/v1 +-> ssh-ed25519 lOyIlA VsJu05NEZogLfeKJ8f9PiUH9RZn2RKJ+/FYOTzUOIyY +Zd5ze/ijrlRs948f6fhCR+IN6uXpck6ejMlpyGugOfQ +-> z+o-grease +J< ey N" +uAedOA+JGje0EKhTuQJj+RDh98H6dqryAUe7nC2iF6t7wAT1NHFLWWfRqw3nNtMb +Cb0pH7hECmbW0vygVD67NusZOvleB2RHng +--- KcTuAfeh0NIBLRmtXZFlbsAAmH9Eu2KmswfZzWgaeZ8 +9EQުF`io~/V<*{'A~n0 '@K