blob: ced326c92816abb66e40bf31d5c3f42bc42d1ea0 [file] [log] [blame]
Skyler Grey22428b02023-11-19 13:20:56 +00001{ base, pkgs, lib, config, ... }:
2lib.recursiveUpdate {
TheCodedProfb6184602023-06-13 17:04:59 -04003 environment.systemPackages = with pkgs; [ vaultwarden ];
TheCodedProfaec8c452023-06-12 18:26:46 -04004
TheCodedProfb6184602023-06-13 17:04:59 -04005 services.vaultwarden.enable = true;
6 services.vaultwarden.dbBackend = "postgresql";
Skyler Grey915067d2023-12-03 13:46:53 +00007 systemd.services.vaultwarden.requires = [ "postgresql.service" ];
TheCodedProfaec8c452023-06-12 18:26:46 -04008
Skyler Greyfe1740c2023-10-21 01:24:18 +00009 sops.secrets = lib.pipe [
10 "ADMIN_TOKEN"
11 "SMTP_PASSWORD"
12 "YUBICO_SECRET_KEY"
13 "HIBP_API_KEY"
14 ] [
Skyler Grey87a11552023-06-14 23:02:25 +020015 (map (name: {
Skyler Greyfe1740c2023-10-21 01:24:18 +000016 inherit name;
17 value = {
18 mode = "0400";
19 owner = config.users.users.root.name;
Skyler Greybcb46d32023-11-10 20:48:38 +000020 group = config.users.users.root.group;
Samuel Shuertf68685d2023-10-28 20:07:56 -040021 sopsFile = ../../secrets/vaultwarden.json;
Skyler Greyfe1740c2023-10-21 01:24:18 +000022 format = "json";
23 };
Skyler Grey87a11552023-06-14 23:02:25 +020024 }))
TheCodedProfb6184602023-06-13 17:04:59 -040025 builtins.listToAttrs
26 ];
Skyler Greyfe1740c2023-10-21 01:24:18 +000027} (let isDerived = base != null;
28in if isDerived
29# We cannot use mkIf as both sides are evaluated no matter the condition value
30# Given we use base as an attrset, mkIf will error if base is null in here
31then
32 with lib;
33 let
34 cfg = config.services.vaultwarden;
35
36 vaultwarden_config = {
37 # Server Settings
Skyler Grey22428b02023-11-19 13:20:56 +000038 DOMAIN = "https://vaultwarden.clicks.codes";
39 ROCKET_ADDRESS = "127.0.0.255";
40 ROCKET_PORT = 1028;
Skyler Greyfe1740c2023-10-21 01:24:18 +000041
42 # General Settings
43 SIGNUPS_ALLOWED = false;
44 INVITATIONS_ALLOWED = true;
45 SIGNUPS_DOMAINS_WHITELIST =
46 "clicks.codes,coded.codes,thecoded.prof,starrysky.fyi,hopescaramels.com,pinea.dev,trans.gg";
47 SIGNUPS_VERIFY = true;
48
Skyler Greyfe1740c2023-10-21 01:24:18 +000049 DISABLE_2FA_REMEMBER = true;
50
51 # Admin Account
52 ADMIN_TOKEN = "!!ADMIN_TOKEN!!";
53
54 # Database Settings
55 DATABASE_URL =
Skyler Grey22428b02023-11-19 13:20:56 +000056 "postgresql://vaultwarden:!!clicks_vaultwarden_db_secret!!@127.0.0.1:${
Skyler Greyfe1740c2023-10-21 01:24:18 +000057 toString config.services.postgresql.port
58 }/vaultwarden";
59
60 # Mail Settings
61 SMTP_HOST = "mail.clicks.codes";
Skyler Grey22428b02023-11-19 13:20:56 +000062 SMTP_FROM = "vaultwarden@clicks.codes";
63 SMTP_FROM_NAME = "Clicks vaultwarden";
Skyler Greyfe1740c2023-10-21 01:24:18 +000064 SMTP_SECURITY = "starttls";
65 SMTP_PORT = 587;
66
Skyler Grey22428b02023-11-19 13:20:56 +000067 SMTP_USERNAME = "vaultwarden@clicks.codes";
Skyler Greyfe1740c2023-10-21 01:24:18 +000068 SMTP_PASSWORD = "!!SMTP_PASSWORD!!";
69
70 REQUIRE_DEVICE_EMAIL = true;
71
72 IP_HEADER = "X-Forwarded-For";
73
74 # YubiKey Settings
75 YUBICO_CLIENT_ID = "89788";
76 YUBICO_SECRET_KEY = "!!YUBICO_SECRET_KEY!!";
77
Skyler Greyfe1740c2023-10-21 01:24:18 +000078 # HIBP Settings
Skyler Grey22428b02023-11-19 13:20:56 +000079 HIBP_API_KEY="!!HIBP_API_KEY!!";
Skyler Greyfe1740c2023-10-21 01:24:18 +000080
81 ORG_ENABLE_GROUPS = true;
82 # I have looked at the risks. They seem relatively small in comparison to the utility
83 # (stuff like sync issues if you don't refresh your page)
84 # Also a general lack of real-world testing. Which, honestly, doesn't
85 # seem too bad. Please contact me *immediately* upon noticing issues
86 # as I want to make sure that as little as possible is lost if we need
87 # to restore from backups (although I doubt it'll come to that)
88 };
89
90 nameToEnvVar = name:
Skyler Grey31618512023-08-20 21:54:44 +000091 let
Skyler Greyfe1740c2023-10-21 01:24:18 +000092 parts = builtins.split "([A-Z0-9]+)" name;
93 partsToEnvVar = parts:
94 foldl' (key: x:
95 let last = stringLength key - 1;
96 in if isList x then
97 key
98 + optionalString (key != "" && substring last 1 key != "_") "_"
99 + head x
100 else if key != "" && elem (substring 0 1 x)
101 lowerChars then # to handle e.g. [ "disable" [ "2FAR" ] "emember" ]
102 substring 0 last key
103 + optionalString (substring (last - 1) 1 key != "_") "_"
104 + substring last 1 key + toUpper x
105 else
106 key + toUpper x) "" parts;
107 in if builtins.match "[A-Z0-9_]+" name != null then
108 name
109 else
110 partsToEnvVar parts;
TheCodedProfb6184602023-06-13 17:04:59 -0400111
Skyler Greyfe1740c2023-10-21 01:24:18 +0000112 # Due to the different naming schemes allowed for config keys,
113 # we can only check for values consistently after converting them to their corresponding environment variable name.
114 configEnv = let
115 configEnv = concatMapAttrs (name: value:
116 optionalAttrs (value != null) {
117 ${nameToEnvVar name} =
118 if isBool value then boolToString value else toString value;
119 }) vaultwarden_config;
120 in {
121 DATA_FOLDER = "/var/lib/bitwarden_rs";
122 } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED)
123 || configEnv.WEB_VAULT_ENABLED == "true") {
124 WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
125 } // configEnv;
Skyler Grey31618512023-08-20 21:54:44 +0000126
Skyler Greyfe1740c2023-10-21 01:24:18 +0000127 configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList
128 (name: value: ''
129 ${name}=${value}
130 '') configEnv));
131 in {
132 scalpel.trafos."vaultwarden.env" = {
133 source = toString configFile;
134 matchers."ADMIN_TOKEN".secret = config.sops.secrets.ADMIN_TOKEN.path;
135 matchers."SMTP_PASSWORD".secret = config.sops.secrets.SMTP_PASSWORD.path;
136 matchers."YUBICO_SECRET_KEY".secret =
137 config.sops.secrets.YUBICO_SECRET_KEY.path;
138 matchers."HIBP_API_KEY".secret = config.sops.secrets.HIBP_API_KEY.path;
Skyler Grey22428b02023-11-19 13:20:56 +0000139 matchers."clicks_vaultwarden_db_secret".secret =
140 config.sops.secrets.clicks_vaultwarden_db_password.path;
Skyler Greyfe1740c2023-10-21 01:24:18 +0000141 owner = config.users.users.vaultwarden.name;
142 group = config.users.groups.vaultwarden.name;
143 mode = "0400";
144 };
Skyler Grey31618512023-08-20 21:54:44 +0000145
Skyler Greyfe1740c2023-10-21 01:24:18 +0000146 services.vaultwarden.environmentFile =
147 config.scalpel.trafos."vaultwarden.env".destination;
148 }
149else
150 { })