Using the Nix store to cache content with inputs that *don't* include the executed code?

Howdy –

I recently implemented a code-signing tool with several similarities to target/nix-fetchers – using the extraBuiltins plugin by @shlevy to be able to exec a helper which pulls content from a cache external to the Nix store. (I’m copying signatures into the Nix store, and referencing the copy that lives there in the plugin’s result, but the persistent mapping between {content-sha256,key-id}->signature is external).

This works, but using a separate store that needs to be shared between users (even if only between those users with access to the underlying keys) is unfortunate.

On the other hand, I don’t want to need to discard the cached signatures when the code that manages them changes – that code isn’t an input to the signature, after all; only the key ID and the content being signed impact the resulting signature, and while signing the same content with the same key more than once can have varying results, the first signature generated is guaranteed safe to reuse, thus allowing this to be used much as one would a more truly pure derivation.

Can the Nix store reasonably be used here – avoiding the need for an out-of-band cache – or am I trying to fit a round peg into a square hole?

(For those who are curious: There will eventually be a publicly-releasable version of this code; no promises on timing).

Hey,

The only way that I see to keep the input → output correspondence would be by using a derivation for the build. Otherwise like you said the correspondence has to be maintained externally.

Since nix is already being extended, another option might be to configure the nix extra-sandbox-paths to poke a hole in the sandbox and give access to the secret. For example you might run a gpg daemon and mount it’s socket to /nix/secret/gpg.sock. The main downside is that all the derivations now have potentially access to the secret, or the daemon that contains the secret.

Another idea would be to extend the nix language to introduce a new type of derivation, for which the output can be provided arbitrarily.

1 Like