You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a theoretically elegant way of passing capabilities around. Because of its advanced nature, it will probably only be used by advanced users like Matrix AI, or other people who really care about security.
A file descriptor is a kernel object representing/and acting like a file. But it doesn't exist on the filesystem. It's not a "named" file.
myprogramthatneedssecret --password-file /path/to/the/secret/file # we saw this with step-ca
# now with process substitution/redirection, we get a magical file descriptor
myprogramthatneedssecret --password-file <(pk secrets get blah)
Now technically this just really makes use of the shell. There's no magic supplied by polykey.
So this is elegant because it really is a principle of least privilege.
There's no secret floating around in the environment variables, nor in the filesystem, nor in the clipboard. The file descriptor is created and ONLY accessible by the program in which it was passed to. There's no way for any other program to read that file descriptor (unless they are able to break the kernel).
If another program wanted to read it, it could not. Firstly because there's no "name" for this file descriptor. The name that myprogramthatneedssecret knows is not a universal name. It's a name only local to that specific process.
Now this also allows myprogramthatneedssecret to pass that file descriptor. It is possible to use UDS to pass file descriptors between processes.
One thing though, this makes the fd read-once. It's a "single-use" place. That's good and bad. What if you wanted to be able to read multiple times? It is not possible unless you are using ZSH:
myprogramthatneedssecret --password-file =(pk secrets get blah)
However this is not as secure as before, because ZSH creates a file at /tmp, and uses that as the real file, to allow random access and repeated reads.
Also the other thing is, the file descriptor is readable as long as the myprogramthatneedssecret keeps the file descriptor open. As soon as the program closes, or explicitly closes the file descriptor, the file is not readable.
Now because we are using the shell, the idea that the descriptor is only readable by myprogramthatneedssecret is not entirely true.
But this is all because it is the shell that is doing the magic.
What if Polykey was doing the magic?
Then it would be possible to ensure absolute security of the file descriptor.
How would this work? 2 ways:
Passing directly from parent to child
Via UDS
For parent to child, this is actually similar to the environment variable situation. So you would "run" the process, while having opened an anonymous pipe, and subsequently piping the secret into the pipe and assigning to a file descriptor. However this requires passing some address in the same process space to the child process so it knows what number is the file descriptor relating to the secret. This is explained here: https://stackoverflow.com/a/21512395
This won't work for alot of programs. Because they were not designed to receive parameters referring a file descriptor number.
For UDS, this could work as well, but again relies on the idea that the receiving program knows how to use the socket. Furthermore the socket has to exist on the filesystem.
Which is why this is theoretically elegant, but practically difficult to do. Unless we are the ones writing the target program as well. So in the case of Matrix OS, this is the case where we could potentially use UDS or other stuff.
For normal use cases, it appears the process substitution/redirection is the best way to do it if you want to use file descriptors. The important idea is to realize that the secret is still readable on the filesystem if the other process knew the PID of the shell managing it, and if the fd hasn't been fully read yet, because it's a read-once fd. And also it needs to be running under the authority of the same user that is running the shell.
The text was updated successfully, but these errors were encountered:
Created by robbie-cronin
File Descriptor
This is a theoretically elegant way of passing capabilities around. Because of its advanced nature, it will probably only be used by advanced users like Matrix AI, or other people who really care about security.
A file descriptor is a kernel object representing/and acting like a file. But it doesn't exist on the filesystem. It's not a "named" file.
Now technically this just really makes use of the
shell
. There's no magic supplied by polykey.So this is elegant because it really is a principle of least privilege.
There's no secret floating around in the environment variables, nor in the filesystem, nor in the clipboard. The file descriptor is created and ONLY accessible by the program in which it was passed to. There's no way for any other program to read that file descriptor (unless they are able to break the kernel).
If another program wanted to read it, it could not. Firstly because there's no "name" for this file descriptor. The name that
myprogramthatneedssecret
knows is not a universal name. It's a name only local to that specific process.Now this also allows
myprogramthatneedssecret
to pass that file descriptor. It is possible to use UDS to pass file descriptors between processes.One thing though, this makes the fd read-once. It's a "single-use" place. That's good and bad. What if you wanted to be able to read multiple times? It is not possible unless you are using ZSH:
However this is not as secure as before, because ZSH creates a file at
/tmp
, and uses that as the real file, to allow random access and repeated reads.Also the other thing is, the file descriptor is readable as long as the
myprogramthatneedssecret
keeps the file descriptor open. As soon as the program closes, or explicitly closes the file descriptor, the file is not readable.Now because we are using the shell, the idea that the descriptor is only readable by
myprogramthatneedssecret
is not entirely true.Because you can do this:
And in a separate program to output
cat /proc/PID/fd/3
wherePID
is what is echoed from the above script.The fd however is limited to
r-x------
and so it is only readable any program acting under the same user authority.But this is all because it is the shell that is doing the magic.
What if Polykey was doing the magic?
Then it would be possible to ensure absolute security of the file descriptor.
How would this work? 2 ways:
For parent to child, this is actually similar to the environment variable situation. So you would "run" the process, while having opened an anonymous pipe, and subsequently piping the secret into the pipe and assigning to a file descriptor. However this requires passing some address in the same process space to the child process so it knows what number is the file descriptor relating to the secret. This is explained here: https://stackoverflow.com/a/21512395
This won't work for alot of programs. Because they were not designed to receive parameters referring a file descriptor number.
For UDS, this could work as well, but again relies on the idea that the receiving program knows how to use the socket. Furthermore the socket has to exist on the filesystem.
Which is why this is theoretically elegant, but practically difficult to do. Unless we are the ones writing the target program as well. So in the case of Matrix OS, this is the case where we could potentially use UDS or other stuff.
For normal use cases, it appears the process substitution/redirection is the best way to do it if you want to use file descriptors. The important idea is to realize that the secret is still readable on the filesystem if the other process knew the PID of the shell managing it, and if the fd hasn't been fully read yet, because it's a read-once fd. And also it needs to be running under the authority of the same user that is running the shell.
The text was updated successfully, but these errors were encountered: