forked from lix-project/lix
fetchGit and flake: add publicKeys list input
This adds publicKeys as an optional fetcher input attribute to flakes and builtins.fetchGit to provide a nix interface for the json-encoded `publicKeys` attribute of the git fetcher. Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
This commit is contained in:
parent
6df32889a5
commit
098f0615c9
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
- `builtins.fetchTree` is now marked as stable.
|
- `builtins.fetchTree` is now marked as stable.
|
||||||
|
|
||||||
|
|
||||||
- The interface for creating and updating lock files has been overhauled:
|
- The interface for creating and updating lock files has been overhauled:
|
||||||
|
|
||||||
- [`nix flake lock`](@docroot@/command-ref/new-cli/nix3-flake-lock.md) only creates lock files and adds missing inputs now.
|
- [`nix flake lock`](@docroot@/command-ref/new-cli/nix3-flake-lock.md) only creates lock files and adds missing inputs now.
|
||||||
|
@ -29,3 +28,5 @@
|
||||||
|
|
||||||
- The flake-specific flags `--recreate-lock-file` and `--update-input` have been removed from all commands operating on installables.
|
- The flake-specific flags `--recreate-lock-file` and `--update-input` have been removed from all commands operating on installables.
|
||||||
They are superceded by `nix flake update`.
|
They are superceded by `nix flake update`.
|
||||||
|
|
||||||
|
- Commit signature verification for the [`builtins.fetchGit`](@docroot@/language/builtins.md#builtins-fetchGit) is added as the new [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches).
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "fetchers.hh"
|
#include "fetchers.hh"
|
||||||
#include "finally.hh"
|
#include "finally.hh"
|
||||||
#include "fetch-settings.hh"
|
#include "fetch-settings.hh"
|
||||||
|
#include "value-to-json.hh"
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
@ -140,8 +141,13 @@ static FlakeInput parseFlakeInput(EvalState & state,
|
||||||
attrs.emplace(state.symbols[attr.name], (long unsigned int)attr.value->integer);
|
attrs.emplace(state.symbols[attr.name], (long unsigned int)attr.value->integer);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw TypeError("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
|
if (attr.name == state.symbols.create("publicKeys")) {
|
||||||
state.symbols[attr.name], showType(*attr.value));
|
experimentalFeatureSettings.require(Xp::VerifiedFetches);
|
||||||
|
NixStringContext emptyContext = {};
|
||||||
|
attrs.emplace(state.symbols[attr.name], printValueAsJSON(state, true, *attr.value, pos, emptyContext).dump());
|
||||||
|
} else
|
||||||
|
throw TypeError("flake input attribute '%s' is %s while a string, Boolean, or integer is expected",
|
||||||
|
state.symbols[attr.name], showType(*attr.value));
|
||||||
}
|
}
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "registry.hh"
|
#include "registry.hh"
|
||||||
#include "tarball.hh"
|
#include "tarball.hh"
|
||||||
#include "url.hh"
|
#include "url.hh"
|
||||||
|
#include "value-to-json.hh"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
@ -125,6 +126,10 @@ static void fetchTree(
|
||||||
attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean});
|
attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean});
|
||||||
else if (attr.value->type() == nInt)
|
else if (attr.value->type() == nInt)
|
||||||
attrs.emplace(state.symbols[attr.name], uint64_t(attr.value->integer));
|
attrs.emplace(state.symbols[attr.name], uint64_t(attr.value->integer));
|
||||||
|
else if (state.symbols[attr.name] == "publicKeys") {
|
||||||
|
experimentalFeatureSettings.require(Xp::VerifiedFetches);
|
||||||
|
attrs.emplace(state.symbols[attr.name], printValueAsJSON(state, true, *attr.value, pos, context).dump());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
state.debugThrowLastTrace(TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
state.debugThrowLastTrace(TypeError("fetchTree argument '%s' is %s while a string, Boolean or integer is expected",
|
||||||
state.symbols[attr.name], showType(*attr.value)));
|
state.symbols[attr.name], showType(*attr.value)));
|
||||||
|
@ -427,6 +432,42 @@ static RegisterPrimOp primop_fetchGit({
|
||||||
With this argument being true, it's possible to load a `rev` from *any* `ref`
|
With this argument being true, it's possible to load a `rev` from *any* `ref`
|
||||||
(by default only `rev`s from the specified `ref` are supported).
|
(by default only `rev`s from the specified `ref` are supported).
|
||||||
|
|
||||||
|
- `verifyCommit` (default: `true` if `publicKey` or `publicKeys` are provided, otherwise `false`)
|
||||||
|
|
||||||
|
Whether to check `rev` for a signature matching `publicKey` or `publicKeys`.
|
||||||
|
If `verifyCommit` is enabled, then `fetchGit` cannot use a local repository with uncommitted changes.
|
||||||
|
Requires the [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches).
|
||||||
|
|
||||||
|
- `publicKey`
|
||||||
|
|
||||||
|
The public key against which `rev` is verified if `verifyCommit` is enabled.
|
||||||
|
Requires the [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches).
|
||||||
|
|
||||||
|
- `keytype` (default: `"ssh-ed25519"`)
|
||||||
|
|
||||||
|
The key type of `publicKey`.
|
||||||
|
Possible values:
|
||||||
|
- `"ssh-dsa"`
|
||||||
|
- `"ssh-ecdsa"`
|
||||||
|
- `"ssh-ecdsa-sk"`
|
||||||
|
- `"ssh-ed25519"`
|
||||||
|
- `"ssh-ed25519-sk"`
|
||||||
|
- `"ssh-rsa"`
|
||||||
|
Requires the [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches).
|
||||||
|
|
||||||
|
- `publicKeys`
|
||||||
|
|
||||||
|
The public keys against which `rev` is verified if `verifyCommit` is enabled.
|
||||||
|
Must be given as a list of attribute sets with the following form:
|
||||||
|
```nix
|
||||||
|
{
|
||||||
|
key = "<public key>";
|
||||||
|
type = "<key type>"; # optional, default: "ssh-ed25519"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Requires the [`verified-fetches` experimental feature](@docroot@/contributing/experimental-features.md#xp-feature-verified-fetches).
|
||||||
|
|
||||||
|
|
||||||
Here are some examples of how to use `fetchGit`.
|
Here are some examples of how to use `fetchGit`.
|
||||||
|
|
||||||
- To fetch a private repository over SSH:
|
- To fetch a private repository over SSH:
|
||||||
|
@ -501,6 +542,21 @@ static RegisterPrimOp primop_fetchGit({
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- To verify the commit signature:
|
||||||
|
|
||||||
|
```nix
|
||||||
|
builtins.fetchGit {
|
||||||
|
url = "ssh://git@github.com/nixos/nix.git";
|
||||||
|
verifyCommit = true;
|
||||||
|
publicKeys = [
|
||||||
|
{
|
||||||
|
type = "ssh-ed25519";
|
||||||
|
key = "AAAAC3NzaC1lZDI1NTE5AAAAIArPKULJOid8eS6XETwUjO48/HKBWl7FTCK0Z//fplDi";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Nix will refetch the branch according to the [`tarball-ttl`](@docroot@/command-ref/conf-file.md#conf-tarball-ttl) setting.
|
Nix will refetch the branch according to the [`tarball-ttl`](@docroot@/command-ref/conf-file.md#conf-tarball-ttl) setting.
|
||||||
|
|
||||||
This behavior is disabled in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
This behavior is disabled in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||||
|
|
|
@ -169,14 +169,14 @@ void doCommitVerification(const Path repoDir, const Path gitDir, const std::stri
|
||||||
&& k.type != "ssh-ed25519"
|
&& k.type != "ssh-ed25519"
|
||||||
&& k.type != "ssh-ed25519-sk"
|
&& k.type != "ssh-ed25519-sk"
|
||||||
&& k.type != "ssh-rsa")
|
&& k.type != "ssh-rsa")
|
||||||
warn("Unknow keytype: %s\n"
|
warn("Unknown keytype: %s\n"
|
||||||
"Please use one of\n"
|
"Please use one of\n"
|
||||||
"- ssh-dsa\n"
|
"- ssh-dsa\n"
|
||||||
"- ssh-ecdsa\n"
|
" ssh-ecdsa\n"
|
||||||
"- ssh-ecdsa-sk\n"
|
" ssh-ecdsa-sk\n"
|
||||||
"- ssh-ed25519\n"
|
" ssh-ed25519\n"
|
||||||
"- ssh-ed25519-sk\n"
|
" ssh-ed25519-sk\n"
|
||||||
"- ssh-rsa", k.type);
|
" ssh-rsa", k.type);
|
||||||
allowedSigners += "* " + k.type + " " + k.key + "\n";
|
allowedSigners += "* " + k.type + " " + k.key + "\n";
|
||||||
}
|
}
|
||||||
writeFile(allowedSignersFile, allowedSigners);
|
writeFile(allowedSignersFile, allowedSigners);
|
||||||
|
@ -201,7 +201,7 @@ void doCommitVerification(const Path repoDir, const Path gitDir, const std::stri
|
||||||
}
|
}
|
||||||
re += "]";
|
re += "]";
|
||||||
if (status == 0 && std::regex_search(output, std::regex(re)))
|
if (status == 0 && std::regex_search(output, std::regex(re)))
|
||||||
printTalkative("Commit signature verification on commit %s succeeded", rev);
|
printTalkative("Signature verification on commit %s succeeded", rev);
|
||||||
else
|
else
|
||||||
throw Error("Commit signature verification on commit %s failed: \n%s", rev, output);
|
throw Error("Commit signature verification on commit %s failed: \n%s", rev, output);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue