github-upload-action-secrets: support for ssh-keygen and deploy keys#2192
github-upload-action-secrets: support for ssh-keygen and deploy keys#2192allisonkarlitskaya merged 6 commits intomainfrom
Conversation
allisonkarlitskaya
left a comment
There was a problem hiding this comment.
Note: I considered to do things in this order:
- upload new deploy key
- update secret
- delete old deploy keys
So that any uses in the middle would work, but this is silly, and also pointless, because if a workflow is already running, it will keep using the old key...
One outstanding thing I want to make very very sure of is that the method that we're using to generate the key is getting high-quality random data.
88b75b4 to
a7bcfdb
Compare
|
Here's a working use of the automatically-generated/uploaded node-cache key: cockpit-project/cockpit#16068 |
martinpitt
left a comment
There was a problem hiding this comment.
Nice! With such a script and then collecting all the concrete cases in an Ansible playbook in cockpituous, my "codify/automate knowledge" concern will be completely addressed. Thanks!
|
Ok, so, choose your poison: key = Ed25519PrivateKey.generate()
public = key.public_key().public_bytes(Encoding.OpenSSH, PublicFormat.OpenSSH)
private = key.private_bytes(Encoding.PEM, PrivateFormat.OpenSSH, NoEncryption())or with tempfile.TemporaryDirectory() as dir:
key=f'{dir}/link-to-fd3-and-fd4'
yes_r, yes_w = os.pipe()
priv_r, priv_w = os.pipe()
publ_r, publ_w = os.pipe()
try:
os.symlink(f'/proc/self/fd/{priv_w}', f'{key}')
os.symlink(f'/proc/self/fd/{publ_w}', f'{key}.pub')
ssh_keygen = subprocess.Popen(
['ssh-keygen', '-t', 'ed25519', '-N', '', '-q', '-f', key],
stdin=yes_r, stdout=open('/dev/null', 'w'),
pass_fds = (publ_w, priv_w))
os.write(yes_w, b'y\n')
public = os.read(publ_r, 1024)
private = os.read(priv_r, 1024)
finally:
for fd in (yes_r, yes_w, priv_r, priv_w, publ_r, publ_w):
os.close(fd)or with tempfile.TemporaryDirectory() as dir:
key = f'{dir}/link-to-fd3-and-fd4'
os.symlink(f'/proc/self/fd/3', f'{key}')
os.symlink(f'/proc/self/fd/4', f'{key}.pub')
process = subprocess.Popen(f'ssh-keygen -t ed25519 -N "" -q -f {key} 3>&1 4>&2 &>/dev/null', shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
private, public = process.communicate(b'y\n')My personal preference is the pure library approach, but I understand that you have reservations about that. Second place is the "shell abuse" approach, I guess? Lucky that we have public/private and also stdout/stderr. Seems that the number 2 is popular! |
|
@allisonkarlitskaya Thanks for working these out! If nothing else, that's a nice reference to point to in the future. Undoubtedly 1 is the nicest (my previous review was blurred by that encrypt() mis-reading), 2 "OMG please no", and I find 3 actually quite clever. Not too big to understand/read, and doesn't require thinking about crypto or keeping up with SSH key format changes (which did happen not too long ago. So I feel like 2 > 1 > 3, but I would not veto 1 either -- after all, these are not long-lived, so if they stop working because reasons, we can always adjust the implementation. |
a7bcfdb to
a65720b
Compare
8b3b90e to
c51fe38
Compare
martinpitt
left a comment
There was a problem hiding this comment.
One tiny rebase error, but this looks good. Many thanks for figuring this out! 💯
Make sure --receiver refers to a valid org or repository.
Get rid of `-d` option as an alias for `--dry-run` and use `-n`, instead.
Add new --ssh-keygen and --directory options, exactly one of which must be specified. --directory gets you the old functionality of uploading a directory worth of files as named secrets. --ssh-keygen is a new feature which generates an SSH keypair and directly uploads the private half as a secret (with the given name), with the public key printed to stdout.
c51fe38 to
f6aac40
Compare
When used in combination with --ssh-keygen, instead of printing it to stdout, upload the public half of the generated key to be used as a deploy key on the named repository.
The old name was much too long, and it wasn't 100% accurate, since we can now also upload to environments.
00efa9e to
1de96a8
Compare
No description provided.