# SPDX-FileCopyrightText: 2020 Luke Granger-Brown # # SPDX-License-Identifier: Apache-2.0 { pkgs, config, depot, lib, ... }: let inherit (lib) mkEnableOption mkOption types mkBefore; mkDefault = lib.mkOverride 900; format = pkgs.formats.json {}; templatePathDirectories = lib.unique (map (t: dirOf t.destination) config.my.vault.settings.template); # Remove empty lists at the top level because they make Vault implode. cleanedSettings = lib.filterAttrs (n: v: !((builtins.typeOf v) == "list" && (builtins.length v) == 0)) config.my.vault.settings; in { options.my.vault = { enable = mkEnableOption "vault agent"; roleID = mkOption { type = types.str; default = config.networking.hostName; }; secretIDPath = mkOption { type = types.str; default = "/var/lib/vault-agent/secret-id"; }; settings = mkOption { type = format.type; default = {}; }; bindMountStateTo = mkOption { type = types.nullOr types.str; default = null; }; }; config = { my.vault.enable = mkDefault true; my.vault.settings = { pid_file = mkDefault "/run/vault-agent/pid"; vault = { address = mkDefault "https://vault.int.lukegb.com"; retry.num_retries = mkDefault 1; }; auto_auth.method = mkDefault [{ type = "approle"; config = { role_id_file_path = pkgs.writeText "${config.my.vault.roleID}-role-id" config.my.vault.roleID; secret_id_file_path = config.my.vault.secretIDPath; remove_secret_id_file_after_reading = false; }; }]; cache.use_auto_auth_token = mkDefault true; listener.unix = { address = mkDefault "/run/vault-agent/sock"; tls_disable = mkDefault true; }; }; users.groups.vault-agent = {}; users.users.vault-agent = { isSystemUser = true; group = "vault-agent"; }; systemd = lib.optionalAttrs config.my.vault.enable { services.vault-agent = { description = "Hashicorp Vault Agent"; wants = [ "network.target" ]; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; path = with pkgs; [ glibc.bin ]; environment.VAULT_CLIENT_TIMEOUT = "15m"; serviceConfig = { RuntimeDirectory = "vault-agent"; RuntimeDirectoryMode = "0750"; StateDirectory = "vault-agent"; StateDirectoryMode = "0700"; User = "vault-agent"; NoNewPrivileges = true; ProtectSystem = "strict"; ProtectHome = "yes"; ReadWritePaths = templatePathDirectories; ExecStart = "${pkgs.vault}/bin/vault agent -config=${format.generate "vault-agent.json" cleanedSettings}"; }; }; mounts = lib.optional (config.my.vault.bindMountStateTo != null) { unitConfig.RequiresMountsFor = "${config.my.vault.bindMountStateTo} /var/lib"; options = "bind"; what = config.my.vault.bindMountStateTo; where = "/var/lib/vault-agent"; requiredBy = [ "vault-agent.service" ]; before = [ "vault-agent.service" ]; wantedBy = [ "vault-agent.service" ]; }; }; }; }