mirror of
https://github.com/NixOS/nix.git
synced 2025-04-15 13:47:34 +00:00
store URI: introduce multiple signatures support
Add a `secretKeyFiles` URI parameter in the store URIs receiving a coma-separated list of Nix signing keyfiles. For instance: nix copy --to "file:///tmp/store?secret-keys=/tmp/key1,/tmp/key2" \ "$(nix build --print-out-paths nixpkgs#hello)" The keys passed through this new store URI parameter are merged with the key specified in the `secretKeyFile` parameter, if any. We'd like to rotate the signing key for cache.nixos.org. To simplify the transition, we'd like to sign the new paths with two keys: the new one and the current one. With this, the cache can support nix configurations only trusting the new key and legacy configurations only trusting the current key. See https://github.com/NixOS/rfcs/pull/149 for more informations behind the motivation.
This commit is contained in:
parent
e76bbe413e
commit
e12369a68e
@ -29,8 +29,17 @@ BinaryCacheStore::BinaryCacheStore(const Params & params)
|
||||
, Store(params)
|
||||
{
|
||||
if (secretKeyFile != "")
|
||||
signer = std::make_unique<LocalSigner>(
|
||||
SecretKey { readFile(secretKeyFile) });
|
||||
signers.push_back(std::make_unique<LocalSigner>(
|
||||
SecretKey { readFile(secretKeyFile) }));
|
||||
|
||||
if (secretKeyFiles != "") {
|
||||
std::stringstream ss(secretKeyFiles);
|
||||
Path keyPath;
|
||||
while (std::getline(ss, keyPath, ',')) {
|
||||
signers.push_back(std::make_unique<LocalSigner>(
|
||||
SecretKey { readFile(keyPath) }));
|
||||
}
|
||||
}
|
||||
|
||||
StringSink sink;
|
||||
sink << narVersionMagic1;
|
||||
@ -270,9 +279,11 @@ ref<const ValidPathInfo> BinaryCacheStore::addToStoreCommon(
|
||||
stats.narWriteCompressedBytes += fileSize;
|
||||
stats.narWriteCompressionTimeMs += duration;
|
||||
|
||||
/* Atomically write the NAR info file.*/
|
||||
if (signer) narInfo->sign(*this, *signer);
|
||||
for (auto &signer: signers) {
|
||||
narInfo->sign(*this, *signer);
|
||||
}
|
||||
|
||||
/* Atomically write the NAR info file.*/
|
||||
writeNarInfo(narInfo);
|
||||
|
||||
stats.narInfoWrite++;
|
||||
|
@ -32,6 +32,9 @@ struct BinaryCacheStoreConfig : virtual StoreConfig
|
||||
const Setting<Path> secretKeyFile{this, "", "secret-key",
|
||||
"Path to the secret key used to sign the binary cache."};
|
||||
|
||||
const Setting<std::string> secretKeyFiles{this, "", "secret-keys",
|
||||
"List of comma-separated paths to the secret keys used to sign the binary cache."};
|
||||
|
||||
const Setting<Path> localNarCache{this, "", "local-nar-cache",
|
||||
"Path to a local cache of NARs fetched from this binary cache, used by commands such as `nix store cat`."};
|
||||
|
||||
@ -57,7 +60,7 @@ class BinaryCacheStore : public virtual BinaryCacheStoreConfig,
|
||||
{
|
||||
|
||||
private:
|
||||
std::unique_ptr<Signer> signer;
|
||||
std::vector<std::unique_ptr<Signer>> signers;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -110,3 +110,13 @@ nix store verify --store "$TEST_ROOT"/store0 -r "$outPath2" --trusted-public-key
|
||||
|
||||
# Content-addressed stuff can be copied without signatures.
|
||||
nix copy --to "$TEST_ROOT"/store0 "$outPathCA"
|
||||
|
||||
# Test multiple signing keys
|
||||
nix copy --to "file://$TEST_ROOT/storemultisig?secret-keys=$TEST_ROOT/sk1,$TEST_ROOT/sk2" "$outPath"
|
||||
for file in "$TEST_ROOT/storemultisig/"*.narinfo; do
|
||||
if [[ "$(grep -cE '^Sig: cache[1,2]\.example.org' "$file")" -ne 2 ]]; then
|
||||
echo "ERROR: Cannot find cache1.example.org and cache2.example.org signatures in ${file}"
|
||||
cat "${file}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user