I've the script which loads the SSH key from the variable (as part of script in CI environment) in order to not keep the private file in the public repository, however ssh-add complains about the wrong permissions (and it seems it's not possible to bypass it). So my approach is to find the method of changing the permission of anonymous pipe which is created on the fly.

For example:

$ stat <(:)
  File: ‘/dev/fd/63’
  Size: 0           Blocks: 0          IO Block: 512    fifo
Device: 397f3928h/964639016d    Inode: 818277067   Links: 0
Access: (0660/prw-rw----)  Uid: (  501/  kenorb)   Gid: (   20/   staff)
Access: 2015-10-10 22:33:30.498640000 +0100
Modify: 2015-10-10 22:33:30.498640000 +0100
Change: 2015-10-10 22:33:30.498640000 +0100
 Birth: 2015-10-10 22:33:30.498640000 +0100

shows 0660 permission. I've checked my umask and it seems it has nothing to do with that.

Here is a simple test (on OS X, which by default has 0660):

$ ssh-add <(cat ~/.ssh/id_rsa)
Permissions 0660 for '/dev/fd/63' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.

On Linux it seems to work, because it's 0500 by default. Where this permission is controlled from?

To clarify, I'm not looking to change the permission of any file, as I'd like to use an anonymous pipe.

The question is:

How do I temporary change the permission of a pipe?

  • 1
    A FIFO is a named pipe. You're having a problem because you have an (anonymous) pipe, not a FIFO. – Gilles 'SO- stop being evil' Oct 11 '15 at 21:09

So far I've found the following workaround using named FIFO:

$ mkfifo -m 600 fifo
$ cat ~/.ssh/id_rsa >fifo | ssh-add fifo
Identity added: fifo (fifo)

where the option -m sets the FIFO permission.


You may be able to wrap ssh-add in a program which does a chmod on the /dev/fd/N path or fchmod on the file descriptor.

For example, on a Linux machine where I don't get any complaint from ssh-add using the default permissions, I'm able to reproduce the error by doing this:

perl -e 'chmod 0777, $ARGV[0];exec "ssh-add", $ARGV[0];' <(cat ~/.ssh/id_rsa)

If that reproduces the problem, then this should solve it:

perl -e 'chmod 0600, $ARGV[0];exec "ssh-add", $ARGV[0];' <(cat ~/.ssh/id_rsa)

The chmod is supplied with a pathname like /proc/self/fd/11 but it changes the permissions on the actual pipe inode (since chmod doesn't work on symlinks). This should have the same effect, but using fchmod:

perl -e 'open P, "<", $ARGV[0]; chmod 0600, \*P;close P;exec "ssh-add", $ARGV[0];' <(cat ~/.ssh/id_rsa)

This one should have the same effect, using fchmod and taking advantage of the fact that the pathname is in a predictable format to avoid the extra open:

perl -e '$ARGV[0] =~ m,^(?:/proc/self|/dev)/fd/(\d+)\z, and $^F=$1 and open P, "<&=$1" and chmod 0600, \*P;exec "ssh-add", $ARGV[0];' <(cat ~/.ssh/id_rsa)

Those perl scripts would look less ugly as C programs; converting them is simple once you identify one that works in your target environment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.