I am building a CI infrastructure which consists of nix remote builders aka workers. I want those workers to be shared between different projects, teams and repositories (e.q. github actions or gh self-hosted runners having remote builders configured via nix.conf).
I want worker clients to only be able to build nix derivations or download their cached build result from remote builder’s store. For example. projectFoo
has built a derivation which result is located in /nix/store/<hash>-foo
, then projectBar
should only be able to request building its own derivation, I don’t want it to be able to download <hash>-foo
derivation’s result.
I’ve built a PoC which configures remote builder on a worker host like this:
let
# ref: https://github.com/nix-community/infra/blob/399542c1116422a0f37735ccd8c47ad8cf016762/modules/shared/remote-builder.nix
nix-ssh-wrapper = pkgs.writeShellScript "nix-ssh-wrapper" ''
case $SSH_ORIGINAL_COMMAND in
"nix-daemon --stdio")
exec ${config.nix.package}/bin/nix-daemon --stdio
;;
*)
echo "Access only allowed for using the nix remote builder" 1>&2
exit
esac
'';
in
{
users.users.remote-builder = {
isNormalUser = true;
openssh.authorizedKeys.keys = [
''restrict,command="${nix-ssh-wrapper}" ssh-ed25519 <pubkey>''
];
group = "nogroup";
};
nix.settings.allowed-users = [ "remote-builder" ];
}
However I’m somewhat anxious that this setup would allow to poison store or traverse it. Due to lack of documentation on nix-daemon protocol I’m not sure what exactly allowed-users
can and can’t do. It’s clear that they can’t make builder substitute with a substituter untrusted by the builder host but some other parts of attach surface are not clear. For example, is it possible to get nix store contents via nix-daemon --stdio
and fetch whatever all other builder’s client have built?