buildkite-agent: secrecy improvements: non-store, non-Nix provisioning of secrets

authored by Kosyrev Serge and committed by Domen Kožar 3fa4e1e3 3385c85f

+40 -22
+40 -22
nixos/modules/services/continuous-integration/buildkite-agent.nix
··· 4 5 let 6 cfg = config.services.buildkite-agent; 7 - configFile = pkgs.writeText "buildkite-agent.cfg" 8 - '' 9 - token="${cfg.token}" 10 - name="${cfg.name}" 11 - meta-data="${cfg.meta-data}" 12 - hooks-path="${cfg.package}/share/hooks" 13 - build-path="${cfg.dataDir}" 14 - ''; 15 in 16 17 { ··· 39 type = types.listOf types.package; 40 }; 41 42 - token = mkOption { 43 - type = types.str; 44 description = '' 45 The token from your Buildkite "Agents" page. 46 ''; 47 }; 48 ··· 62 }; 63 64 openssh = 65 - { privateKey = mkOption { 66 - type = types.str; 67 description = '' 68 Private agent key. 69 ''; 70 }; 71 - publicKey = mkOption { 72 - type = types.str; 73 description = '' 74 Public agent key. 75 ''; 76 }; 77 }; ··· 84 home = cfg.dataDir; 85 createHome = true; 86 description = "Buildkite agent user"; 87 }; 88 89 environment.systemPackages = [ cfg.package ]; 90 91 systemd.services.buildkite-agent = 92 { description = "Buildkite Agent"; 93 wantedBy = [ "multi-user.target" ]; 94 after = [ "network.target" ]; ··· 97 HOME = cfg.dataDir; 98 NIX_REMOTE = "daemon"; 99 }; 100 preStart = '' 101 - ${pkgs.coreutils}/bin/mkdir -m 0700 -p ${cfg.dataDir}/.ssh 102 103 - echo "${cfg.openssh.privateKey}" > ${cfg.dataDir}/.ssh/id_rsa 104 - ${pkgs.coreutils}/bin/chmod 600 ${cfg.dataDir}/.ssh/id_rsa 105 - 106 - echo "${cfg.openssh.publicKey}" > ${cfg.dataDir}/.ssh/id_rsa.pub 107 - ${pkgs.coreutils}/bin/chmod 600 ${cfg.dataDir}/.ssh/id_rsa.pub 108 - ''; 109 110 serviceConfig = 111 - { ExecStart = "${pkgs.buildkite-agent}/bin/buildkite-agent start --config ${configFile}"; 112 User = "buildkite-agent"; 113 RestartSec = 5; 114 Restart = "on-failure"; ··· 116 }; 117 }; 118 }; 119 }
··· 4 5 let 6 cfg = config.services.buildkite-agent; 7 in 8 9 { ··· 31 type = types.listOf types.package; 32 }; 33 34 + tokenPath = mkOption { 35 + type = types.path; 36 description = '' 37 The token from your Buildkite "Agents" page. 38 + 39 + A run-time path to the token file, which is supposed to be provisioned 40 + outside of Nix store. 41 ''; 42 }; 43 ··· 57 }; 58 59 openssh = 60 + { privateKeyPath = mkOption { 61 + type = types.path; 62 description = '' 63 Private agent key. 64 + 65 + A run-time path to the key file, which is supposed to be provisioned 66 + outside of Nix store. 67 ''; 68 }; 69 + publicKeyPath = mkOption { 70 + type = types.path; 71 description = '' 72 Public agent key. 73 + 74 + A run-time path to the key file, which is supposed to be provisioned 75 + outside of Nix store. 76 ''; 77 }; 78 }; ··· 85 home = cfg.dataDir; 86 createHome = true; 87 description = "Buildkite agent user"; 88 + extraGroups = [ "keys" ]; 89 }; 90 91 environment.systemPackages = [ cfg.package ]; 92 93 systemd.services.buildkite-agent = 94 + let copy = x: target: perms: 95 + "cp -f ${x} ${target}; ${pkgs.coreutils}/bin/chmod ${toString perms} ${target}; "; 96 + in 97 { description = "Buildkite Agent"; 98 wantedBy = [ "multi-user.target" ]; 99 after = [ "network.target" ]; ··· 102 HOME = cfg.dataDir; 103 NIX_REMOTE = "daemon"; 104 }; 105 + 106 + ## NB: maximum care is taken so that secrets (ssh keys and the CI token) 107 + ## don't end up in the Nix store. 108 preStart = '' 109 + ${pkgs.coreutils}/bin/mkdir -m 0700 -p ${cfg.dataDir}/.ssh 110 + ${copy (toString cfg.openssh.privateKeyPath) "${cfg.dataDir}/.ssh/id_rsa" 600} 111 + ${copy (toString cfg.openssh.publicKeyPath) "${cfg.dataDir}/.ssh/id_rsa.pub" 600} 112 113 + cat > "${cfg.dataDir}/buildkite-agent.cfg" <<EOF 114 + token="$(cat ${toString cfg.tokenPath})" 115 + name="${cfg.name}" 116 + meta-data="${cfg.meta-data}" 117 + hooks-path="${pkgs.buildkite-agent}/share/hooks" 118 + build-path="${cfg.dataDir}/builds" 119 + bootstrap-script="${pkgs.buildkite-agent}/share/bootstrap.sh" 120 + EOF 121 + ''; 122 123 serviceConfig = 124 + { ExecStart = "${pkgs.buildkite-agent}/bin/buildkite-agent start --config /var/lib/buildkite-agent/buildkite-agent.cfg"; 125 User = "buildkite-agent"; 126 RestartSec = 5; 127 Restart = "on-failure"; ··· 129 }; 130 }; 131 }; 132 + imports = [ 133 + (mkRenamedOptionModule [ "services" "buildkite-agent" "token" ] [ "services" "buildkite-agent" "tokenPath" ]) 134 + (mkRenamedOptionModule [ "services" "buildkite-agent" "openssh" "privateKey" ] [ "services" "buildkite-agent" "openssh" "privateKeyPath" ]) 135 + (mkRenamedOptionModule [ "services" "buildkite-agent" "openssh" "publicKey" ] [ "services" "buildkite-agent" "openssh" "publicKeyPath" ]) 136 + ]; 137 }