Skip to content

Instantly share code, notes, and snippets.

@toolbear
Last active March 13, 2023 11:45
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?
GitHub as an authority for SSH public keys

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

  1. github-auth
  2. bespoke curl commands or scripts used by the #pairwithme crowd
  3. 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

  1. Convention that an SSH key with title == username is a user's default key
  2. Web and REST API results include title on the default key only
  3. 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, then title 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment