-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Pluggable authentication #9857
base: master
Are you sure you want to change the base?
Pluggable authentication #9857
Conversation
|
||
template<typename T> | ||
std::optional<T> readOptional(const StoreDirConfig & store, WorkerProto::ReadConn conn) | ||
{ | ||
auto tag = readNum<uint8_t>(conn.from); | ||
switch (tag) { | ||
case 0: | ||
return std::nullopt; | ||
case 1: | ||
return WorkerProto::Serialise<T>::read(store, conn); | ||
default: | ||
throw Error("Invalid optional tag from remote"); | ||
} | ||
} | ||
|
||
|
||
template<typename T> | ||
void writeOptional(const StoreDirConfig & store, WorkerProto::WriteConn conn, const std::optional<T> & x) | ||
{ | ||
if (!x.has_value()) { | ||
conn.to << uint8_t{0}; | ||
} else { | ||
conn.to << uint8_t{1}; | ||
WorkerProto::Serialise<T>::write(store, conn, *x); | ||
} | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you have the same code in serialize.hh
?
template<typename T> | ||
DECLARE_WORKER_SERIALISER(std::vector<T>); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can make a partial template specialization like this for std::optional
, and then you won't need the std::optional<auth::AuthData>
instance. (Can also turn std::optional<TrustedFlag>
into one for just TrustedFlag
too.)
I used to have that but I removed it because I only had the special-cases instances at the time, but now we do have a use case for it.
Separate from the low level protocol minutiae, I think I've considered solving the same problem in a different way, which is having a user-specific remote builder for fixed output derivations. See #9344 |
Client-side building would be great but is a much bigger project (and probably wouldn't work on platforms like macOS). |
I don't think it's that big of a project. It's just a client side build + use daemon to add to store. (And the current I think for fixed-output derivations without references it should work on macOS just fine. Since there are no references, there is no need to do fake roots / make |
3487e19
to
703871a
Compare
601d98e
to
e1143f1
Compare
Nix can now read authentication data from ~/.local/share/nix/auth/*. The files in that directory have the format: protocol=https host=my-cache.example.org username=alice password=blabla Also, the Nix daemon can now call back to the client to get authentication data from the client (if it's trusted). This makes it possible to have the daemon substitute from an authenticated binary cache, with the authentication coming from the client. Issue NixOS#8635.
This is similar to 'git credential fill', i.e. it tries to fill an authentication request using the configured authentication sources. Mostly useful for testing.
e1143f1
to
47c8fe6
Compare
Triaged during the Nix maintainers meeting on 2024-02-16.
To discuss |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2024-02-16-nix-team-meeting-minutes-124/39870/1 |
This looks great! I have one question:
Could we also do this for the steps:
- uses: DeterminateSystems/nix-installer-action@main
# this step sets some AWS_ env vars
- uses: aws-actions/configure-aws-credentials@main
with:
role-arn: my-role
# This doesn't work as nix-daemon cant access the env vars
- run: nix copy --to s3://my-bucket Instead you need to massage the credentials into a |
Team meeting notes:
|
Sorry I need to clarify on my previous comment:
but setting an s3 bucket as a substituter e.g.:
doesn't work as the nix daemon doesn't have access to my local environment variables or my So it would be cool if we can use the solution for the https substituter for the s3 substituter as well? Edit: I think it's not that easy actually. As all the credential logic is in the AWS SDK itself... So maybe this is not feasible |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/2024-02-19-nix-team-meeting-minutes-126/40308/1 |
Forwarding can now be disabled entirely, enabled for trusted users, or enabled for all users.
Some status updates:
|
Some thoughts:
|
IMO this goes in the wrong direction. Introduces lots of complexity to the Nix codebase. Instead, I suggest working on making fetchers as a whole pluggable. The complexity around I comment motivated by the exchange in #10567. cc @roberth |
I'm sympathetic to that.
This has security implications; any Nixpkgs package (or otherwise) could then steal credentials, by doing a builtin fetch with a malicious fetching plugin. The beauty of fixed-output derivations is that they sandbox the fetching logic, preventing this. |
/* Set up authentication tunneling for builtin:fetchurl. FIXME: | ||
maybe we want to support this for arbitrary fixed-output | ||
derivations. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/* Set up authentication tunneling for builtin:fetchurl. FIXME: | |
maybe we want to support this for arbitrary fixed-output | |
derivations. */ | |
/* Set up authentication tunneling for builtin:fetchurl. | |
We generally do not want to pass credentials to arbitrary | |
fixed output derivations, because that makes it possible | |
for any dependency (however deep down) to steal them. */ |
We'd need to come up with a scheme to safely pass authorization (with letter z) to specific derivations in such a way that the user controls where their credentials go; perhaps through some sort of unforgeable token that's passed around explicitly in expressions? Something for another day.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OT: notably we can't store the unforgeable token in the drv itself, because that would expose it to be read with readFile foo.drvPath
.
This seems to be another instance where we should be tracking transient derivation metadata, just like we should have been doing with meta.timeout
or perhaps the licenses.
Motivation
This PR makes several improvements to HTTP authentication in Nix:
auth-sources
setting. For instance, addingextra-auth-sources = git-credential-libsecret
allows Nix to obtain usernames/passwords from the KDE/Gnome keyrings.builtin:nix
toauth-sources
), which reads usernames/passwords from files in~/.local/share/nix/auth
. The advantage over thenetrc
authentication source (now known asbuiltin:netrc
) is that it has a file per secret, which makes it easier for scripts/installers to add authentication data.$SSH_ASKPASS
) and store this in the configuredauth-sources
for future use.--substituters http://my-cache
, the daemon will trigger the client to ask the user for the username/password for that cache.builtin:fetchurl
requests authentication from the parent (outside of the sandbox), so e.g.Context
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.