-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
[RFC 0143] Nix Store ACLs #143
base: master
Are you sure you want to change the base?
Conversation
You may want to have a look at https://gist.github.com/edolstra/afa5a41d4acbc0d6c8cccfede7fd4792 and its implementation (https://github.com/edolstra/nix/tree/acls). The core of that proposal is to maintain the closure invariant that if a user can read path P, they can read the paths in the closure of P. There is no |
This RFC is open for shepherd nominations! (It already was but we never asked for nominations explicitly...) |
This RFC has not acquired enough shepherds. This typically shows lack of interest from the community. In order to progress a full shepherd team is required. Consider trying to raise interest by posting in Discourse, talking in Matrix or reaching out to people that you know. If not enough shepherds can be found in the next month we will close this RFC until we can find enough interested participants. The PR can be reopened at any time if more shepherd nominations are made. |
I am not sure whether this is a good thing to prioritize at this moment, but I do want to get here eventually. I nominate myself, |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/avoiding-information-leakage-in-multi-host-deployments/29926/3 |
I'd gladly nominate myself as a shepherd (with a conflict of interest warning as this comes from a client project for Tweag, so there shouldn't be only Tweagers in the shepherd team). @edolstra, I'd also nominate yourself if you're willing since you're both knowledgeable and interested in that problem space |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/tweag-nix-dev-update-51/30870/1 |
@thufschmitt what is the status of this RFC? Is there anything that is needed to move it towards FCP? |
Sorry for the long silence. It's ongoing, although for $REASONS it's hard to find a time to gather the team. |
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.
Left an army of comments :)
Overall: I like the broad direction quite a lot, but there is a handful of things to iron out and details to clarify
rfcs/0143-nix-store-acls.md
Outdated
# Detailed design | ||
[design]: #detailed-design | ||
|
||
Change the implementation of the Nix daemon (and, potentially, nix-serve, depending on the chosen "Remote Store" implementation) to store access control lists as metadata, automatically update them when users provide proof that they have the necessary source, and allow `trusted-user`s to manipulate those ACLs manually. |
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.
Change the implementation of the Nix daemon (and, potentially, nix-serve, depending on the chosen "Remote Store" implementation) to store access control lists as metadata, automatically update them when users provide proof that they have the necessary source, and allow `trusted-user`s to manipulate those ACLs manually. | |
Change the implementation of the Nix daemon to store access control lists as metadata, automatically update them when users provide proof that they have the necessary source, and allow `trusted-user`s to manipulate those ACLs manually. |
I don't think we need to care about nix-serve
for this (unless it's already implemented?)
rfcs/0143-nix-store-acls.md
Outdated
|
||
This should ensure that this change is as seamless as possible for the users: they will still always be able to execute `nix build` or similar for derivations where they have access to all the sources, substituting as much as possible, as though nothing had changed. | ||
The only major difference would be that `/nix/store` itself is now not readable. | ||
If a user needs to be able to access some store paths without having access to their sources (e.g. for proprietary software where sharing the artifacts is ok but sharing the sources isn't), such access can be granted explicitly by the administrators (`trusted-user`'s). |
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.
This might not matter too much, but shouldn't anyone with access to the path be allowed to share it further?
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.
(it looks like that's what L53 implies too)
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.
This might not matter too much, but shouldn't anyone with access to the path be allowed to share it further?
Yes, indeed
rfcs/0143-nix-store-acls.md
Outdated
When the relevant config option (perhaps `acl`) is enabled, this ACL (access control list) is enforced, meaning that only users on that list, or belonging to groups on that list, can read the store path, execute files from it, or use it as a dependency in their derivations. | ||
We also add a less strict mode (`selective-acl`) in which derivations are only protected if they are marked as such. |
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.
It's not clear at which level these options acts: the first paragraph seems to talk about a specific path (with one access-control list), while the second one seems to be global to the store
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.
If I understand it correctly:
- Setting
acl=true
(as a global store option) means that every path MUST have an attached ACL (which is enforced) - Setting
selective-acl=true
means that paths CAN have an attached ACL, and will be world-readable otherwise
Is that it?
For paths external to the Nix sandbox (added via `nix store add-{file,path}`, paths in the Nix language, `builtins.fetch*`, or flake sources), we add the user to the list when they send the path to the daemon. | ||
We might need to add a flag (like `--protect`) for the selective ACL mode. | ||
|
||
For derivations themselves (.drv files), we add the user to the list when they send the derivation to the daemon. |
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.
Probably irrelevant here, but this is somewhat reminescent of the mechanism for allowing access to paths in pure eval mode
For derivations themselves (.drv files), we add the user to the list when they send the derivation to the daemon. | ||
|
||
For derivation outputs, we add user to the list when the user requests to realise the derivation and has access to the transitive dependencies, including the sources. |
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.
Does that mean that it's possible for someone to register a derivation without having access to its closure? How would that work?
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.
Yes, that would be theoretically possible; after all, derivations (.drv
files) are pretty much just regular files added to the store, and one can add such files without having access to the closure.
rfcs/0143-nix-store-acls.md
Outdated
## Local store | ||
|
||
For a local store, we keep a list of local (POSIX) users who have access to each store path as path metadata. | ||
When the relevant config option (perhaps `acl`) is enabled, this ACL (access control list) is enforced, meaning that only users on that list, or belonging to groups on that list, can read the store path, execute files from it, or use it as a dependency in their derivations. | ||
We also add a less strict mode (`selective-acl`) in which derivations are only protected if they are marked as such. | ||
|
||
For paths external to the Nix sandbox (added via `nix store add-{file,path}`, paths in the Nix language, `builtins.fetch*`, or flake sources), we add the user to the list when they send the path to the daemon. | ||
We might need to add a flag (like `--protect`) for the selective ACL mode. | ||
|
||
For derivations themselves (.drv files), we add the user to the list when they send the derivation to the daemon. | ||
|
||
For derivation outputs, we add user to the list when the user requests to realise the derivation and has access to the transitive dependencies, including the sources. | ||
|
||
When `selective-acl` is enabled, protected paths should not be readable by anyone during the build. | ||
Necessary permissions are granted after the build. | ||
|
||
There also should be a way to enable the protection for selective ACLs (perhaps `nix store access protect`), and explicitly grant (`nix store access grant`) or revoke (`nix store access revoke`) access of certain user or group to each individual path. | ||
Naturally, this should only be available to `trusted-user`s and users who have access to this path already (either because they are on the ACL, or they belong to a group on the ACL). |
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.
This whole section is a bit weird since the LocalStore
doesn't have any notion of user (nor trusted-users
).
Maybe this could be reorganized as
- We add the following API to the store interface to manipulate ACLs with the following invariants: …
- The local store implements it by setting filesystem-level ACLs (without any mention of access control)
- The remote store adds some access control by enforcing blah, blah, and blah.
|
||
If this list is set, the Nix daemon (or other store implementation) should be notified that the path/derivation is supposed to be protected (perhaps using a new worker protocol command), and after the build is completed, the ACLs should be set appropriately (only the users specified in the `__permissions` list should have access to the path). | ||
|
||
### Nix Daemon/local store implementation |
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.
### Nix Daemon/local store implementation | |
### Nix Daemon/remote store implementation |
?
## Remote stores | ||
|
||
For remote stores, this problem is a bit more difficult since sending all the inputs to the remote store every time a dependency has to be downloaded is really expensive. | ||
There should be a protocol to establish proof-of-source, as in proof that the client has access to all the sources of a derivation, before that derivation output is provided. |
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.
IIRC attic has a similar problem, and some solution to it. It would be nice to see how they handle it (maybe Cachix has it too)
rfcs/0143-nix-store-acls.md
Outdated
No actual building occurs. | ||
|
||
Now, Alice and Bob want to share the resulting binaries (but not the sources) with Carol. | ||
They can add a `__permissions = [ "alice" "bob" "carol" ];` and re-build the derivation (nothing will get re-built, only the permissions will be updated). |
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.
nothing will get re-built, only the permissions will be updated
Re. my comment about whether __permissions
should affect the hash: This means that it doesn't. If you go that way it should be spelled out explicitly
|
||
- This change requires significant refactoring of many Nix components; | ||
- Implementing ACLs will impose a performance penalty. Hopefully this penalty will not be too bad, and also since ACLs are entirely optional this shouldn't affect users who don't need it; | ||
- Short secrets in the store can be brute-forced, since the hash of the content is known, unless [RFC 97] is also implemented. |
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 would be a bit stronger here (or somewhere else), and highlight that this isn't a good mechanism for storing secrets
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'd say it depends on what is meant by "secrets"; after all, the only reason to have ACLs in the first place is to have some information which is only accessible to a select group, and thus "secret" in some sense. Of course, it should be highlighted that this is intended for "secret" (proprietary or otherwise protected) source-code and build artifacts, rather than runtime secrets such as credentials.
2023-10-10 Meeting 1Attendees: @balsoft @edolstra @thufschmitt @infinisil
|
2023-11-07 Meeting 2Attendees: @infinisil @edolstra @Ericson2314 @thufschmitt @balsoft Notes
Action items
|
I see FUSE mentioned in the discussion here. I'd like to note that on macOS FUSE is hard to set up (you have to mangle with System Integrity Protection stuff), so it would not work for people who just need Nix. ACLs on the other hand are supported pretty much everywhere. |
I would rather not support macOS than support I feature that I feel is in the wrong direction. macOS Nix talking to Linux Nix still can get benefits. (Adding more detail/polish to a few things I said in the meeting) I am a proponent of Capability-based security as generally better, and in particular "the Nix way" giving the shared overlaps with functional programming, etc. While it is possible have some capability system and then set and unset file ACLs based on that, the result amplifies reads into writes (O(1) share capability becomes O(files in closure) The order I am thinking of is:
A basic theme here is that with the exception of the rootless daemon, which is almost finished, I think most of the work doesn't need to happen with Nix itself. I think its is more of an integration-y / dev-ops exercise in making various bits of software continue working as we take away more and more permissions. And dev work probably goes into separate little high-privilege daemons (like the GC roots scanner that comes with the rootless daemon), not the "main bulk" of Nix. |
@Ericson2314 this is giving up on an existing batteries-included cross-platform implementation in favour of a hypothetical build-your-own-cake Linux-only one. As much as I like your final vision, I don't see it happening any time soon (if ever). |
As always, we want to make sure Nix is going in the right direction. Some experimental features are alright, but also nicely self contained. NixOS/nix#9287 looks pretty deeply involved some some core interfaces, making a lot more code away of Unix users for example. For me, the more deeply entwined something is, the higher the bar is that it be for sure in the "right" direction. |
I'm sorry to have to say this, but I feel strongly that the Nix team does not have the bandwidth to work on this concept. It vastly complicates the Nix model, which we simply can't afford, considering the state of the other unfinished projects. For what it's worth, the existence of a proof of concept PR doesn't change anything about that, because usually the responsibility to actually complete the project falls on the Nix team, which has to respond to issues, fix bugs and generally put in a lot of effort to make sure invariants are upheld. In this case those a security properties. Nothing to sneeze at. I very much appreciate @Ericson2314's suggestion to explore what can be done by simplifying and decoupling what we already have, which is actually feasible now, because it does not require any changes to the model. @thufschmitt No such implementation exists, because we can not support it. I urge the Nix team to focus on finalizing existing projects first and postpone this RFC until we have time to consider a significant feature like this |
2023-11-21 Meeting 3Attendees: @infinisil, @thufschmitt, @edolstra, @balsoft
|
2023-12-19 Meeting 4Attendees: @infinisil, @thufschmitt, @edolstra, @balsoft
|
Drafted due to no progress being possible at the moment, particularly in light of @roberth 's comment and steering committee discussions. |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/secrets-in-nix-suck-and-how-to-fix-them/43822/5 |
Summary
This RFC proposes a system of Access Control Lists in the Nix Store, allowing multiple users to share software in a single store without exposing it to each other.
Rendered