Skip to content
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

Filesystem Egress & Ingress - Authority Flow Push/Pull Automation #835

Open
CMCDragonkai opened this issue Oct 22, 2024 · 2 comments
Open
Labels
development Standard development

Comments

@CMCDragonkai
Copy link
Member

CMCDragonkai commented Oct 22, 2024

Specification

Polykey currently supports a variety of CLI commands that can interact the local filesystem and the vault filesystem.

However some proposed authority flow automations aren't fully automated without some additional features. Otherwise we will be stuck in step-wise HITL flows.

Let's take an immediate example we have in our team.

The nix 2.0 commands make use of access tokens to pull/clone authenticated repositories. It relies on the access-tokens configuration which may come from multiple places:

  • /etc/nix/nix.conf
  • ~/.config/nix/nix.conf
  • NIX_CONFIG='extra-access-tokens = github.com=<PAT>' nix ...

This represents an egress point, as authority has been delegated to a particular gestalt, and now it has to be executed somehow.

However execution of the authority is predicated on an ingress/egress. The secret access token needs to be put into the relevant location for it to be used by the nix 2.0 commands.

image

This involves either push/pull depending on the situation and contexts.

Push

Interactive push means that polykey is used to push secrets into the appropriate location. Used interactively it means injecting the secret during the interactive execution of nix commands like so:

# this set the `NIX_CONFIG` environment variable based on the value of `NIX_CONFIG` file in the `nix` vault, here it can be quite precise because you can just use `extra-access-tokens = ...`
polykey secrets env nix:/NIX_CONFIG nix build

It's also important to point out, that push can push to the relevant configuration file. We use file as the level of granularity, rather than being able to push into a specific location in the file. Doing at lower than file granularity would require vault schemas to be developed first #76.

A simple way to do this would be:

# this just copies the contents of `nix:/nix.conf` into `~/.config/nix/nix.conf` - which means the vault file would also contain other configuration data, and not just the secrets, this makes it a bit indiscriminate - and not as precise
polykey secrets cat nix:/nix.conf > ~/.config/nix/nix.conf
nix build

We know that in this case, this would be as if a delegated authority was offramped into a user-space filepath, which itself due to how nix works would be usable in sudo environment with sudo -E because of how the nix.conf values is looked up:

> sudo -E env | grep XDG_CONFIG_DIRS
XDG_CONFIG_DIRS=/etc/xdg:/home/cmcdragonkai/.nix-profile/etc/xdg:/nix/profile/etc/xdg:/home/cmcdragonkai/.local/state/nix/profile/etc/xdg:/etc/profiles/per-user/cmcdragonkai/etc/xdg:/nix/var/nix/profiles/default/etc/xdg:/run/current-system/sw/etc/xdg

> sudo env | grep XDG_CONFIG_DIRS                           
XDG_CONFIG_DIRS=/etc/xdg:/root/.nix-profile/etc/xdg:/nix/profile/etc/xdg:/root/.local/state/nix/profile/etc/xdg:/etc/profiles/per-user/root/etc/xdg:/nix/var/nix/profiles/default/etc/xdg:/run/current-system/sw/etc/xdg

Which mean sudo -E would preserve usage of nix commands, and not require pushing to /root/.config/nix/nix.conf.

As of now, push is possible interactively, but not automatically - not without further automation built into push-automation. That would be job of wasm plugins for "scripting PK", however on the other hand, scripting PK is doable in any scripting language just by calling it.

Note that a file-watching interface is more of off-ramp automation or on-ramp automation, and we can consider any automation scripting to be a high level construct.

Pull

When the origin of change, or locus of control is coming from the authorized system/user, then it is necessary for that system to pull the secret out of PK.

The IPC used in this case is commonly: shell-out, file descriptor, filesystem.

For example, the nix.conf supports the include and !include directive (the !include ensures an error if the file doesn't exist).

It looks like:

!include /run/keys/someconfig

This transcludes the contents into the nix.conf through the file path. That other file can then have:

extra-access-tokens = github.com=<PAT>

I haven't actually tried this yet, and I'm exploring the integration here for our platform configuration. But I suspect this means the nix command being executed would then try to read that /run/keys/someconfig and thus whether that is successful would then depend on the file permissions of /run/keys/someconfig and the user/group of the user running nix. And that reveals something interesting, which is that once we offramp the secret, we are bridging from Polykey authority delegation to the offramp's permission-control which in this case is unix filesystem permissions. This cross-over is kind of like a train cargo going from one gauge to another gauge. The rules are changed, and in the context of trying to keep things as high level as possible, you'd want to minimise the ambient authority and ensure POLP by making sure that the file path there is only readable by that relevant nix command execution scenarios that you intend fo rit.

This is a pull flow because the locus of control is on the nix side, reading the secrets from via the filesystem IPC.

In order to achieve this, PK can do a few things:

  1. It can provide a pseudo filesystem interface, a user-space fuser mount. This was talked about in Pseudo file systems interface #169.
  2. A HITL can read out the data from PK, and then put it into the relevant file path. This would be more similar to sops-nix: https://github.com/Mic92/sops-nix. Where there is an intermediate cache. This is actually more of a pull via CLI call, then push to a file path on the real filesystem requiring an intermediate orchestrator.

So in terms of what to implement here:

Automation Plugins/Scripting

We need to decide how exactly do we want to do custom logic integrated into PK. As a WASM plugin? Or do we just consider it out of scope for PK, and something you would compose with your favorite shell script (as the orchestration layer).

But automation plugins/scripting - and official designated way to do this would be how file-watching gets implemented if it is required, and automated egress/write to file on change. A sort of foreign reference that cascades updates in SQL. In that sense we are automating change management too.

Pseudo Filesystem Mounts versus Temporary File Paths

Pseudo filesystem mounts is quite flaky, they are never simple to create. It also creates a problem where the mount is only available as long as PK agent is running. Furthermore, we then have to say, are we mounting the entire vault, or just a single file path? I guess both are possible. Is it like bind mounting or mounting a vault as a drive? Does that mean anything can read the mount - or dependent on filesystem permissions now... how would that work?

Temporary file paths is more like a push automation - write to a special file path - and then expect the puller to read from the file path instead.

This part needs some expansion.

Additional context

Older issues discussing these concepts. These are now cancelled to be superseded by this issue, as this issue can combine the architecture together.

Initial discussion regarding access tokens for nix 2.0:

Tasks

  1. ...
  2. ...
  3. ...
@CMCDragonkai CMCDragonkai added the development Standard development label Oct 22, 2024
Copy link

linear bot commented Oct 22, 2024

@CMCDragonkai
Copy link
Member Author

#171 lists a few other situations where file-watching automation from a push-flow perspective makes sense:

  • ~/.ssh/... - all the key files there and ~/.ssh/authorized_keys
  • ~/.aws/credentials
  • ~/.netrc

These would all benefit as push-flow automation compared to pull-flow. Technically of these can do pull-flow if you want the locus of control from the program itself. But it would depend entirely on whether those programs can "pull" by reading the file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
development Standard development
Development

No branches or pull requests

1 participant