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

Support for GitHub Deployment Keys #59

Merged
merged 6 commits into from
Feb 19, 2021
Merged

Support for GitHub Deployment Keys #59

merged 6 commits into from
Feb 19, 2021

Conversation

mpdude
Copy link
Member

@mpdude mpdude commented Feb 13, 2021

This builds on the suggestions of @shaunco in #38 to support GitHub Deployment Keys that are scoped to single repositories.

When connecting to GitHub, the SSH client must fetch the right SSH key from the agent. Otherwise, the connection will be terminated with the error message

fatal: Could not read from remote repository.
Please make sure you have the correct access rights and the repository exists.

The idea is that each deployment key (which is passed as a secret) uses a key comment field like Deploy key for git@github.com:owner/repo.

After keys are loaded into the agent, the key comments are scanned. If they match /\bgithub.com[:/](.*)(?:\.git)?\b/, two things happen:

  1. A Git config setting is written that uses url.<base>.insteadof.

This config will make git requests to URLs starting with either https://github.com/owner/repo or git@github.com/owner/repo be redirected to a made-up URL like git@...some.hash...:owner/repo.

  1. A SSH config entry is written that works for the made-up hostname ...some.hash... and will redirect it back to github.com, applying the right SSH key.

To choose the right SSH key, we're using the fact that the key identity (as returned from ssh-add -L) can be used as well. This way, we can still avoid having to write private keys to disk at all.

@mpdude mpdude mentioned this pull request Feb 13, 2021
@mpdude mpdude merged commit 4d06ea6 into master Feb 19, 2021
@mpdude mpdude deleted the mapped-deploy-keys branch February 19, 2021 13:37
@shaunco
Copy link
Contributor

shaunco commented Feb 21, 2021

I can't get this working for go or pip... it also requires me to update about 20 deploy keys in my various repos to have the required comment field 😩

I will try to dig in to this later this week.

@@ -175,6 +176,33 @@ try {
console.log("Keys added:");
child_process.execSync('ssh-add -l', { stdio: 'inherit' });

child_process.execFileSync('ssh-add', ['-L']).toString().split(/\r?\n/).forEach(function(key) {
let parts = key.match(/\bgithub.com[:/](.*)(?:\.git)?\b/);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This regex ensures this will only work for github.com. A few of the people commenting on #38 and other issues mentioned pulling from other services. #38 explicitly had support for bitbucket, Azure DevOps, and others.

Copy link
Member Author

@mpdude mpdude Feb 22, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a deliberate and defensive measure to keep this feature scoped to GitHub, for now. Also, I was unsure what URLs for other services might look like and whether we'd need to adapt the parsing regex for them.

I don't know how widespread the restriction is to have deploy keys limited to one repo. A quick Google search turns up that at least BitBucket seems not to have this restriction.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why I just had a separate list of URLs rather than trying to parse them out of certificate comments that are out of my control.

dist/index.js Show resolved Hide resolved

let ownerAndRepo = parts[1];
let sha256 = crypto.createHash('sha256').update(key).digest('hex');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This obfuscates things when debugging/troubleshooting, which is why I had gone with the pseudo-host format.

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

Successfully merging this pull request may close these issues.

2 participants