Motivation
SSH pubkey distribution is adhoc and less (secure|correct|convenient) than it could be. GitHub is an ad hoc authority on mapping identities to SSH public keys, but the interaction could be better.
Examples
- github-auth
- bespoke curl commands or scripts used by the #pairwithme crowd
- keybase.io feature request to support SSH public keys
What I'm asking GitHub for
Broadly: a way to disambiguate the default or preferred key from the list of public keys returned for some other user.
Specifically: include the title
of an SSH public key if and only if title == username
in the results from the following endpoints:
- Web:
https://github.com/{username}.keys
- API:
https://api.github.com/users/{username}/keys
Both endpoints get us 99% of the way there:
$ curl https://github.com/jane.keys
ssh-rsa AAAAB3Nz…H1XW2Q==
ssh-rsa AAAAB3Nz…PxDECZ+N
$ curl https://api.github.com/users/jane/keys
[
{
"id": 7717412,
"key": "ssh-rsa AAAAB3Nz…H1XW2Q=="
},
{
"id": 10246619,
"key": "ssh-rsa AAAAB3Nz…PxDECZ+N"
}
]
The current design that omits title
is good. A title could contain a private email address or reveal information about my PC or network (e.g. GitHub for Mac - dalek1
or CI server
).
Security? Privacy? Think of the children.
-
Using either
default
or{username}
for the title of the special key reveals no new information to the caller beyond "this key is the special key". -
Continuing to omit
title
on all other keys has the same privacy and security guarantees as the current API behavior. -
Singling out one key as "the one I probably use to interactively SSH" is in practice no less secure than having it included at all.
Okay. But why change it?
Tools consuming the current API results must use all the keys, or bail out, or ask the end-user to disambiguate.
A common use of these APIs is quickly granting a GitHub user SSH access to a host by adding their pubkeys to authorized_keys
(e.g. github-auth). A utility operating with maximum convenience will add all of a GitHub user's keys which is less than ideal; operating with more caution it must prompt the user likely leading to the kind of out-of-band key exchange the utility is meant to eliminate. Manually revoking access is also easier: I find the key matching a GitHub username.
Associating an SSH key to an identity with the strong semantics of "I am jane and this is my SSH key" is another use case (see keybase-issue). Services like Keybase.io lack a trustable authority. Of the reasonable candidates for such an authority few have infrastructure that verifies the key; fewer still are used as often as GitHub is so key tampering could go undetected. From the discussion I'm unsure if Keybase's founders are interested in this, but other keybase-like services might.
Desired Behavior
- Convention that an SSH key with
title == username
is a user's default key - Web and REST API results include
title
on the default key only - The
title
of the default key returned is always the user's GitHub username
$ curl https://github.com/jane.keys
ssh-rsa AAAAB3Nz…H1XW2Q== jane
ssh-rsa AAAAB3Nz…PxDECZ+N
$ curl https://api.github.com/users/jane/keys
[
{
"id": 7717412,
"key": "ssh-rsa AAAAB3Nz…H1XW2Q==",
"title": "jane",
"default": true
},
{
"id": 10246619,
"key": "ssh-rsa AAAAB3Nz…PxDECZ+N"
}
]
Optional: UX under account settings to pick a default key
This, but see considerations.
Considerations
-
Users with a single key with
title != username
- they follow a different convention, like email address
- only used GitHub via GitHub for Windows or GitHub for Mac from a single computer
Depending on the tool a single key in the results may be enough disambiguation. For something like Keybase a stronger indication is probably desired. Probably best if API omitted
title
instead of inferring key is default. -
Users with multiple keys, one with
title == email
If
email
is the user's account email, GitHub could infer that this key is the default. Possibly too magical. Definitely more edge cases. -
Users with different key management schemes may use
title == username
to mean something different and find the inference undesirable nor wish to change their scheme. -
An account settings UI is eventually created to explicitly select default or preferred key
Does it change the keys title to username to keep with
title == username
convention? If not, thentitle
on the default key as returned by '/users/jane/keys' and '/user/keys' (when invoked by jane) would be different.
Bonus
Document what GitHub means by "verified key". The docs and blog posts I've found just state "verified keys" and I've inferred what that means. Would be nice if the API docs spelled it out.
REST API endpoint could include a last modified timestamp for at least the default key. A key unchanged for five years on an otherwise active account is a strong indicator that the key hasn't been tampered with. Similarly, a key updated yesterday may warrant caution. Tooling can consume the timestamp and act accordingly.