depot/ops/nixos/lib/vault-agent.nix
Luke Granger-Brown 7592e76a31 tokend: init
tokend is responsible for issuing service-scoped tokens based on the token held
and generated by the Vault Agent.

It can also generate "server-user" scoped tokens, which exist for convenience's
sake: they are not a strong attestation of the user on the machine, and have
limited privileges compared to a Vault token issued using e.g. `vault login
-method=oidc`.
2022-03-20 17:47:52 +00:00

105 lines
3.3 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;
socket_mode = "770";
socket_user = "vault-agent";
socket_group = "vault-agent";
};
};
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" ];
};
};
};
}