-
Notifications
You must be signed in to change notification settings - Fork 0
/
token.nix
84 lines (78 loc) · 3.15 KB
/
token.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
{ pkgs, lib, rootTokenPath, tokenPath, ... }: with lib; let
in {
mkTimers = tokenName: {
"turnkey-${tokenName}-timer" = {
enable = true;
wantedBy = [ "turnkey.target" ];
partOf = [ "${tokenName}-token.service" ];
after = [ "turnkey.service" ];
description = "Emerald City Turnkey Token: Renew Minder for ${tokenName}";
timerConfig.OnCalendar = "*:0/1"; # renew every minute
timerConfig.RandomizedDelaySec = "10s";
};
};
mkServices = cfgIn: tokenName: let cfg = cfgIn.${tokenName}; in {
"turnkey-${tokenName}-token" = {
description = "Emerald City Turnkey Token: ${tokenName}";
after = [ "turnkey.target" ];
requires = [ "turnkey.target" ];
wantedBy = [ "turnkey.target" ];
serviceConfig = {
Type = "simple";
RemainAfterExit = "yes";
# NOTE: Maybe these shouldn't be oneshots, but rather end in a loop which kills the
# service if the managed token goes blank. it can wake up every few seconds, get a read
# lock, verify it's nonempty, then repeat. If it ever gets a readlock and it's empty it
# shuts itself down, and then restart policy can trigger to re-acquire?
ExecStart = with pkgs; pkgs.writeShellScript "turnkey-${tokenName}-token.sh" ''
tokenPath = "${tokenPath tokenName}";
flock -s ${rootTokenPath} -c "{
vault login token=$(cat ${rootTokenPath})
vault token create -field=token -policy=${concatStringsSep " -policy=" cfg.policies} -ttl=${cfg.ttl} > $tokenPath
chown ${cfg.user}:${cfg.group} $tokenPath
chmod 600 $tokenPath
}" &>/dev/null
echo "Token acquired, entering monitoring loop."
while true ; do
flock -s $tokenPath -c "{
# If the token has been removed, we need to exit
[ -e $tokenPath ] && exit 1
# If the token has gone empty, we need to fail.
[ -z $(cat $tokenPath) ] && exit 2
}" &>/dev/null
echo "Token still fresh"
sleep 15;
done
'';
ExecStop = with pkgs; pkgs.writeShellScript "${tokenName}-cleanup.sh" ''
flock -x $tokenPath -c "rm -f $tokenPath"
'';
};
};
"turnkey-${tokenName}-renew" = {
enable = true;
description = "Emerald City Turnkey Token: Renew ${tokenName}";
partOf = [ "turnkey-${tokenName}-token.service" ];
path = [ pkgs.vault-bin pkgs.util-linux pkgs.jq ];
environment.VAULT_ADDR = "https://vault.emerald.city:8200";
serviceConfig = {
User = "root";
Group = "root";
Type = "oneshot";
ExecStart = with pkgs; pkgs.writeShellScript "turnkey-${tokenName}-renew.sh" ''
flock -x ${rootTokenPath} -c "{
vault login token=$(cat ${rootTokenPath})
vault token renew $(cat ${tokenPath tokenName})
}" &>/dev/null
echo "Token expires at:"
vault token lookup -format=json | jq .data.expire_time
'';
};
};
/*
# TODO: Implement a rotation script to run less often
"turnkey-${tokenName}-refresh" = {
};
# */
};
}