Allow client to pass environment variables to FOD builder #590
Labels
No labels
Affects/CppNix
Affects/Nightly
Affects/Only nightly
Affects/Stable
Area/build-packaging
Area/cli
Area/evaluator
Area/fetching
Area/flakes
Area/language
Area/lix ci
Area/nix-eval-jobs
Area/profiles
Area/protocol
Area/releng
Area/remote-builds
Area/repl
Area/repl/debugger
Area/store
bug
Context
contributors
Context
drive-by
Context
maintainers
Context
RFD
crash 💥
Cross Compilation
devx
docs
Downstream Dependents
E/easy
E/hard
E/help wanted
E/reproducible
E/requires rearchitecture
imported
Language/Bash
Language/C++
Language/NixLang
Language/Python
Language/Rust
Needs Langver
OS/Linux
OS/macOS
performance
regression
release-blocker
stability
Status
blocked
Status
invalid
Status
postponed
Status
wontfix
testing
testing/flakey
Topic/Large Scale Installations
ux
No milestone
No project
No assignees
6 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lix-project/lix#590
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Is your feature request related to a problem? Please describe.
Currently there's no decent way of passing secrets to builders that need to be able to download files from sources that require authentication.
Current methods:
builtins.fetchTree
/builtins.fetchGit
- client-side fetching, blocks evaluation, restricted to git/github/gitlab etc..pkgs.fetch*
- FOD builder fetching, requires credentials on the filesystem (netrc
)The ideal solution would be #558, however that's still pretty far away.
Describe the solution you'd like
Nix 2.19 introduced a new experimental feature that I actually quite like, called
configurable-impure-env
(PR). This allows you to pass impure environmental variables to the daemon. I think it's a pretty decent simple solution until we can do #558.Example usage:
Open questions:
impure-env
require a user to be trusted?HTTP_PROXY
.--impure-env FOO=bar
(set explicitly) /--impure-env FOO
(inherit from env)Describe alternatives you've considered
We could just not do anything until #558 and keep passing credentials through
netrc
.Additional context
Happy to port this from Nix 2.19 myself if maintainers agree and the way we wanna implement this is clear.
Hello there,
I discussed this with few team members in private who are working in adjacent areas. While I agree / recognize that netrc is insufficient, we need more documentation / examples of where netrc fell short (scenarios, usecases, etc.) so that we can keep our priority on this topic updated and clear. Most of the workloads I work with private environments are, today, already possible with the current netrc capabilities, albeit with Nix code and sandbox impure paths.
Now, onto the feature, one problem with this sort of thing is what are the various policies we should apply, explain, advise to users with multi-tenant contexts (single tenant context is a special case of multi-tenancy here.)
For example, consider that you have a community builder as a remote builder, and you pass a GitHub authentication token as an impure environment variable, any operators of that community builder who are logging or watching for environments over there will be able to capture it, constituting a dangerous scenario.
More than an experimental feature, I think this is a
dangerous-feature
, because it is a super well-designed assault rifle pointed to the feet of our users. Now, with netrc, the potential for leakage also exist but is better understood with the experience we have with netrc, arguably also netrc forces people to design custom solutions based on sandbox impure paths which needs to be provisioned uniformly on any remote builder or environments you care about.So we are inclined towards implementing:
Some of the architectural work that is being conducted right now should provide the building blocks to achieve this, without paying the cost that CppNix is self-inflicting themselves with, all that technical debt.
Nonetheless, as you remarked, this will take a bit of time.
The position I would aim for is that I would prefer to see more energy spent on implementing the correct path rather than deal with impure-env that might be a distraction which solves a tiny surface of the problem statement.
That being said, I do believe that helping the scenario where you use impure sandbox paths which are shaped as a socket that you can ask for secrets (whether you put a Vault proxy behind or just a simple
socat
that sends back your secret) can be made more secure by helping the sandbox prove to the socket who they are. I'd like to see more towards identity-aware build contexts which can help for more than just obtaining temporary secrets to do things, but also signing, etc.Note that this is my opinion as a core team member, @jade who partaked in the thread may have a different one.
Exactly what I was looking into before discovering
configurable-impure-env
.However I couldn't figure out how to prove the build process that's requesting credentials is who it says it is. Without that I felt like it was just smoke and mirrors really, so I just went with the simpler solution.
This is something we could provide in our sandboxes, but we need probably a bit of help on how to design this "right" to ensure that we don't forget anyone for their workloads.
This issue was mentioned on Gerrit on the following CLs:
Ah, sorry. I pushed the port to Gerrit after having skimmed this too quickly, and drew wrong conclusions.
(It wasn't wasted effort, fwiw. It was useful as a quick workaround for a work project. Perhaps the patch floating around is useful in the same way to others.)
I was dealing with PHP specifically. Composer uses
~/.config/composer/auth.json
, or the same format JSON in aCOMPOSER_AUTH
variable. I was fillingCOMPOSER_AUTH
in aphp.mkComposerVendor
based derivation.But I think most language package managers lean towards a configuration file? The
COMPOSER_AUTH
env var feels like an outlier.Either way, I'm not sure if you're solving packager manager issues with netrc, but if you are, I'm curious what that looks like.
Docker, Kubernetes, systemd currently all lean towards offering secrets as plain files. If access is limited to the sandbox, does a socket gain anything? Is the idea to offer even finer grained access than per sandbox / per build?
(But also, precedent for files doesn't have much weight if there's no specific integration in the tools we intend to run. As long as the result is easy to work with, I guess.)
User/group policies make sense, but this reads like there are more ideas?
Wild idea might be to lock specific credentials down to specific FOD hashes, which might work with sufficiently powerful prefetch and foo2nix tooling, but it's probably too fine grained. Every update would require registering a new hash in configuration. Plus it'd probably make onboarding steep for new tools. I have a feeling a lot of people use the 'copy hash from nix error message' flow, which may limit what we can usefully match in policies. 🙃
https://systemd.io/CREDENTIALS/ talks a lot about
AF_UNIX
socket :).Files are fine as well. Sockets are the general case.
There are more ideas :), but I have no time to expand for now: I hope I can show various proof of concepts.
I'd like impure-env for setting
NIXPKGS_ALLOW_UNFREE=1
and there is seemingly no other way to run build unfree applications without passing--impure
every time.--impure
also seems overly broad just to set a single nixpkgs flag.Just commenting with since the issue so far only considers the auth use case.
this issue is about env vars making their way into builders, but
NIXPKGS_ALLOW_UNFREE
only affects evaluation. what you're asking is only superficially related.Right, this doesn't actually work with NixOS/nix either.