-
-
Notifications
You must be signed in to change notification settings - Fork 159
[RFC 0141] Private Derivations #141
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
Changes from all commits
4cc35c3
f246892
ee44986
73c4e53
6e6ad6f
a49426f
2246c73
742196c
a51bfd8
a62c605
2f389aa
f94d972
328362a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| --- | ||
| feature: private-derivations | ||
| start-date: 2023-02-03 | ||
| author: poscat | ||
| co-authors: (find a buddy later to help out with the RFC) | ||
| shepherd-team: (names, to be nominated and accepted by RFC steering committee) | ||
| shepherd-leader: (name to be appointed by RFC steering committee) | ||
| related-issues: (will contain links to implementation PRs) | ||
| --- | ||
|
|
||
| # Summary | ||
| [summary]: #summary | ||
|
|
||
| This RFC proposes to add a special type of derivation called private derivation, which, upon being built, will have their file permissions set to 000/111 instead of the usual 444/555. | ||
|
|
||
| # Motivation | ||
| [motivation]: #motivation | ||
|
|
||
| In short: This RFC mainly concerns with how to safely manage credentials using nix (as opposed to using impure methods like manually copying them over) on NixOS. | ||
|
|
||
| The world readability of nix store means that, to safely store credentials, they must first somehow be encrypted before written into the store. They also need to be decrypted before the services are started. | ||
|
|
||
| This is less than ideal because one needs to setup a key (which is stored as plaintext on disk) on every machine just to prevent unauthorized users from seeting the credentials. | ||
|
|
||
| Furthermore, if encryption is done before the evaluation of the system configuration (as is the case with [agenix](https://github.com/ryantm/agenix) and [sops-nix](https://github.com/Mic92/sops-nix)), then the nixos module system cannot be utilized to generate configs that contain credentials and one must write them manually. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you mean the right thing but the module system can handle that the credentials are in files but most config files do not handle this to well. |
||
|
|
||
| All of this can be prevented if we added the ability to make derivation outputs as not readable by anyone other than root, by setting the file mode to 111 (directories and executables) or 000 (regular files). We can then use a trustworthy credential manager, for example systemd with its `LoadCredential=`, to distribute these derivations to the consumers safely. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about substituter and caches? |
||
|
|
||
| # Detailed design | ||
| [design]: #detailed-design | ||
|
|
||
| We propose adding a `noReadAccess` option to `builtins.derivation`, which, when set to true, makes this derivation a private derivation. | ||
|
|
||
| The only difference between a private derivation and a normal derivation, apart | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How to handle backwards compatibility?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, what is the main challenge of backwards compatibility? A machine with outdated nix versions trying to build private derivations?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should look into how content-addressed paths are implemented, since they also change the store model. |
||
| from the hash, is that upon instantiation and after building, the read bit of | ||
| the `.drv` file and the output path will be removed (recursively). | ||
|
|
||
|
|
||
| ## Credential Managers | ||
|
|
||
| In our design, the responsibility of access control is to be delegated to a separate process called the credential manager, which is a process with | ||
| the `CAP_DAC_OVERRIDE` capability. This frees us from further bloating the store model. | ||
|
|
||
| # Examples and Interactions | ||
| [examples-and-interactions]: #examples-and-interactions | ||
|
|
||
| ## Intended usage in NixOS modules | ||
| On NixOS there are many modules where configurations that might contain sensitive | ||
| information get written into nix store in plaintext (for example the wpa_supplicant module). Private derivations can solve this issue by | ||
|
|
||
| 1. Writing a helper function `writeTextPrivate` that functions similar to | ||
| `writeText`, but instead outputs a private derivation | ||
| 2. Replace the `writeText` function with `writeTextPrivate` inside the module | ||
| 3. Use `LoadCredential=` to load the private derivation | ||
| 4. Replace the derivation output path with `%d/<credName>` (see systemd.exec) | ||
|
|
||
| # Drawbacks | ||
| [drawbacks]: #drawbacks | ||
|
|
||
| - Adding private derivations further complicates the nix store model. | ||
| - In the intended use case, the credential remains plaintext at all time, and while the resulting derivation is unreadable, the inputs aren't. | ||
| This means the necessary materials that can be used to reconstruct the credential are exposed during build until the inputs are | ||
| garbage collected. A dedicated attacker can in theory monitor for file system changes, save the inputs before they are being GC'd | ||
| and later reconstruct the final derivation. | ||
|
|
||
| # Alternatives | ||
| [alternatives]: #alternatives | ||
|
|
||
| - Supporting more complicated ACLs as described in [this](https://github.com/NixOS/nix/issues/8) Nix issue. | ||
| - Storing private derivations in a separate store path, for example | ||
| `/nix/private-store` that have its executable bit removed so that the hashes | ||
| are not visible to non-root users. | ||
|
|
||
| # Unresolved questions | ||
| [unresolved]: #unresolved-questions | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about starting a build to access this path? It could just copy out the value. Or would private derivations not be able to be used as input to other derivations? But in that case how would you use these in NixOS? (Maybe the path can be referenced in a build but the actual contents isn't available? That would probably require sandboxing.)
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the path can be referenced but the contents are not accessible during build. This is possible because the build is carried out by
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would be good to explicitly list this in the RFC. Along with other security properties such as |
||
|
|
||
| ## Binary caches and copying | ||
| How do we prevent the attacker from using `nix copy` to simply copy out the | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is more general: how to prevent copying derivations onto machines with older nix versions or caches?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm, I'm not very familiar with how store and copying works. Do we need assistance on the receiving end or is it just like |
||
| private derivation to another machine? | ||
|
|
||
| What changes are needed for binary cache providers such as `nix-serve` to handle | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and hydra, harmonia, etc |
||
| private derivations? | ||
|
|
||
| ## Leaking metadata | ||
| The hash is still exposed to the attacker, which opens up some possible attacks. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how to prevent leaking credentials in build logs?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They definitely might leak, but for the usual use case, which is to write some string into a file like |
||
| How does this impact the security? | ||
|
|
||
| ## Content-Addressed paths | ||
| It is not yet known how this might interact with content addressed paths. | ||
|
|
||
| # Future work | ||
| [future]: #future-work | ||
|
|
||
| What future work, if any, would be implied or impacted by this feature | ||
| without being directly part of the work? | ||
Uh oh!
There was an error while loading. Please reload this page.