depot/ops/nixos/lib/vault-agent.nix
Luke Granger-Brown 58a907b700 nixos/vault-agent: listen on UDS only
This UDS is going to be private to vault-agent and tokend (which doesn't exist
yet).

As a stopgap, for the moment, secretsmgrd will be granted direct access to
speak to the Vault Agent over the UDS.

tokend will be responsible for provisioning applications with tokens, by
issuing subtokens which have roles corresponding to the user account requesting
access.
2022-03-20 11:14:51 +00:00

102 lines
3.2 KiB
Nix

# SPDX-FileCopyrightText: 2020 Luke Granger-Brown <depot@lukegb.com>
#
# 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" ];
};
};
};
}