blob: 771f16c476bb454fadd5653e042710c64f1653a9 [file] [log] [blame]
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +00001{ base, pkgs, drive_paths, 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";
TheCodedProfaec8c452023-06-12 18:26:46 -04007
Skyler Grey87a11552023-06-14 23:02:25 +02008 sops.secrets = lib.pipe [ "ADMIN_TOKEN" "SMTP_PASSWORD" "YUBICO_SECRET_KEY" "HIBP_API_KEY" ] [
9 (map (name: {
TheCodedProfb6184602023-06-13 17:04:59 -040010 inherit name; value = {
11 mode = "0400";
12 owner = config.users.users.root.name;
13 group = config.users.users.nobody.group;
14 sopsFile = ../secrets/vaultwarden.json;
15 format = "json";
16 };
Skyler Grey87a11552023-06-14 23:02:25 +020017 }))
TheCodedProfb6184602023-06-13 17:04:59 -040018 builtins.listToAttrs
19 ];
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000020} (
TheCodedProfb6184602023-06-13 17:04:59 -040021 let
22 isDerived = base != null;
23 in
24 if isDerived
25 # We cannot use mkIf as both sides are evaluated no matter the condition value
26 # Given we use base as an attrset, mkIf will error if base is null in here
27 then
28 with lib;
29 let
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000030 cfg = config.services.vaultwarden;
TheCodedProfb6184602023-06-13 17:04:59 -040031
32 vaultwarden_config = {
TheCodedProfaec8c452023-06-12 18:26:46 -040033 # Server Settings
34 DOMAIN = "https://passwords.clicks.codes";
35 ROCKET_ADDRESS = "127.0.0.1";
36 ROCKET_PORT = 8452;
37
38
39 # General Settings
TheCodedProfb6184602023-06-13 17:04:59 -040040 SIGNUPS_ALLOWED = false;
41 INVITATIONS_ALLOWED = true;
42 SIGNUPS_DOMAINS_WHITELIST = "clicks.codes,coded.codes,thecoded.prof,starrysky.fyi,hopescaramels.com,pinea.dev";
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000043 SIGNUPS_VERIFY = true;
TheCodedProfaec8c452023-06-12 18:26:46 -040044
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000045 RSA_KEY_FILENAME = "${drive_paths.External1000SSD.path}/bitwarden/rsa_key";
46 ICON_CACHE_FOLDER = "${drive_paths.External1000SSD.path}/bitwarden/icon_cache";
47 ATTACHMENTS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/attachments";
48 SENDS_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/sends";
49 TMP_FOLDER = "${drive_paths.External4000HDD.path}/bitwarden/tmp";
TheCodedProfaec8c452023-06-12 18:26:46 -040050
TheCodedProfb6184602023-06-13 17:04:59 -040051 DISABLE_2FA_REMEMBER = true;
TheCodedProfaec8c452023-06-12 18:26:46 -040052
53 # Admin Account
TheCodedProfb6184602023-06-13 17:04:59 -040054 ADMIN_TOKEN = "!!ADMIN_TOKEN!!";
TheCodedProfaec8c452023-06-12 18:26:46 -040055
56
57 # Database Settings
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000058 DATABASE_URL =
59 "postgresql://vaultwarden:!!clicks_bitwarden_db_secret!!@127.0.0.1:${toString config.services.postgresql.port}/vaultwarden";
TheCodedProfaec8c452023-06-12 18:26:46 -040060
61
62 # Mail Settings
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000063 SMTP_HOST = "mail.clicks.codes";
TheCodedProfaec8c452023-06-12 18:26:46 -040064 SMTP_FROM = "bitwarden@clicks.codes";
65 SMTP_FROM_NAME = "Clicks Bitwarden";
66 SMTP_SECURITY = "starttls";
67 SMTP_PORT = 587;
68
Skyler Grey (Minion3665)e430df32023-06-23 18:22:19 +000069 SMTP_USERNAME = "bitwarden@clicks.codes";
TheCodedProfbdc23452023-06-14 13:39:10 -040070 SMTP_PASSWORD = "!!SMTP_PASSWORD!!";
TheCodedProfaec8c452023-06-12 18:26:46 -040071
TheCodedProfbdc23452023-06-14 13:39:10 -040072 REQUIRE_DEVICE_EMAIL = true;
TheCodedProfaec8c452023-06-12 18:26:46 -040073
74
75 # YubiKey Settings
TheCodedProfbdc23452023-06-14 13:39:10 -040076 YUBICO_CLIENT_ID = "89788";
77 YUBICO_SECRET_KEY = "!!YUBICO_SECRET_KEY!!";
TheCodedProfaec8c452023-06-12 18:26:46 -040078
79
80 # TODO: Buy a license
81 # HIBP Settings
TheCodedProfd23784c2023-06-13 14:28:23 -040082 # HIBP_API_KEY="!!HIBP_API_KEY!!";
TheCodedProfb6184602023-06-13 17:04:59 -040083 };
84
85 nameToEnvVar = name:
86 let
87 parts = builtins.split "([A-Z0-9]+)" name;
88 partsToEnvVar = parts: foldl'
89 (key: x:
90 let last = stringLength key - 1; in
91 if isList x then key + optionalString (key != "" && substring last 1 key != "_") "_" + head x
92 else if key != "" && elem (substring 0 1 x) lowerChars then # to handle e.g. [ "disable" [ "2FAR" ] "emember" ]
93 substring 0 last key + optionalString (substring (last - 1) 1 key != "_") "_" + substring last 1 key + toUpper x
94 else key + toUpper x) ""
95 parts;
96 in
97 if builtins.match "[A-Z0-9_]+" name != null then name else partsToEnvVar parts;
98
99 # Due to the different naming schemes allowed for config keys,
100 # we can only check for values consistently after converting them to their corresponding environment variable name.
101 configEnv =
102 let
103 configEnv = concatMapAttrs
104 (name: value: optionalAttrs (value != null) {
105 ${nameToEnvVar name} = if isBool value then boolToString value else toString value;
106 })
107 vaultwarden_config;
108 in
109 { DATA_FOLDER = "/var/lib/bitwarden_rs"; } // optionalAttrs (!(configEnv ? WEB_VAULT_ENABLED) || configEnv.WEB_VAULT_ENABLED == "true") {
110 WEB_VAULT_FOLDER = "${cfg.webVaultPackage}/share/vaultwarden/vault";
TheCodedProfbdc23452023-06-14 13:39:10 -0400111 } // configEnv;
TheCodedProfb6184602023-06-13 17:04:59 -0400112
113 configFile = pkgs.writeText "vaultwarden.env" (concatStrings (mapAttrsToList (name: value: "${name}=${value}\n") configEnv));
114 in
115 {
116 scalpel.trafos."vaultwarden.env" = {
117 source = toString configFile;
118 matchers."ADMIN_TOKEN".secret =
119 config.sops.secrets.ADMIN_TOKEN.path;
120 matchers."SMTP_PASSWORD".secret =
121 config.sops.secrets.SMTP_PASSWORD.path;
122 matchers."YUBICO_SECRET_KEY".secret =
123 config.sops.secrets.YUBICO_SECRET_KEY.path;
124 matchers."HIBP_API_KEY".secret =
125 config.sops.secrets.HIBP_API_KEY.path;
126 matchers."clicks_bitwarden_db_secret".secret =
127 config.sops.secrets.clicks_bitwarden_db_password.path;
128 owner = config.users.users.vaultwarden.name;
129 group = config.users.groups.vaultwarden.name;
130 mode = "0400";
131 };
132
133 services.vaultwarden.environmentFile = config.scalpel.trafos."vaultwarden.env".destination;
134 } else { }
135)