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

Create separate signing keys for Git commits #54

Open
ChristopherA opened this issue Oct 26, 2023 · 6 comments
Open

Create separate signing keys for Git commits #54

ChristopherA opened this issue Oct 26, 2023 · 6 comments
Assignees
Labels

Comments

@ChristopherA
Copy link

GitHub commits can now be signed using SSH rather than PGP. Best practices is that it use a different ssh key then the authentication key. It would be very useful if github-keygen could do both and keep them separate.

This likely would require new naming convention for ssh keys. Current the convention is [email protected], but maybe should be [email protected] and [email protected].

GitHub-Keygen should also configure git global for signing, i.e.

git config --global user.signingkey "ssh-ed25519 <your key id>"

@dolmen
Copy link
Owner

dolmen commented Jan 3, 2024

Best practices is that it use a different ssh key then the authentication key.

Do you have more insights about this? Because I would be tempted instead to use the same key.

@ChristopherA
Copy link
Author

(Some context on my expertise, I'm the co-author and co-editor of TLS 1.0, active as a W3C Invited Expert to various emerging cryptographic protocols as well as involved with emerging IETF standards, and I've been in the cryptographic security industry for 30+ years .)

Yes, the recommendation by cryptographers and security professionals is to separate the usage of keys. Authentication keys (the default usage SSH keys) should be kept segregated from Signing keys (the newer SSH functionality), and from other uses (such as Authorization or Capability keys, which not really used by SSH, but plausible).

More specifically, this is the recommendation by NIST in https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf section 5.5:

5.2 Key Usage

In general, a single key shall be used for only one purpose (e.g., encryption, integrity authentication, key wrapping, random bit generation, or digital signatures). There are several reasons for this:

  1. The use of the same key for two different cryptographic processes may weaken the security provided by one or both of the processes.
  2. Limiting the use of a key limits the damage that could be done if the key is compromised.
  3. Some uses of keys interfere with each other. For example, consider a key pair used for both key transport and digital signatures. In this case, the private key is used as both a private key-transport key to decrypt the encrypted keys and as a private signature key to generate digital signatures. It may be necessary to retain the private key used for transport key beyond the cryptoperiod of the corresponding public key in order to decrypt the encrypted keys needed to access encrypted data. The private key used for signature generation shall be destroyed at the expiration of its cryptoperiod to prevent its compromise (see Section 5.3.6). In this example, the longevity requirements for the private key-transport key and
    the private digital-signature key contradict each other.

In the newer W3C international standards such as DID (for which I am a co-author) and Verified Credential (I am Invited Expert) requires explicit different "proof purposes" and "keyUsage" requirements. See: https://www.w3.org/TR/vc-data-integrity/#proof-purposes

You see these practices also exemplified for separation of SSH and PGP keys into FIDO2 devices.

The reason why you've not really seen much about this in SSH is that the SSH signing capability is only a couple of years old. SSH was used exclusively for authentication to connect to a server, so key separation was not required. However, the newer versions of SSH do now support key separation with a separate key usage, and verification of them by ~/.ssh/.allowed_signers file.

It is clear that GitHub does support both authentication and signing keys, as per https://github.blog/changelog/2022-08-23-ssh-commit-verification-now-supported/, however, most people use the same key for both. This is made worse as the githubusername.keys features shares only the authentication key of the user GitHub user, but requires API access to get the signing key. IMHO, there is an argument the authentication keys should be private between GitHub and the users, and instead they should only show the signing keys, as others need to rely on them.

I personally would like to see the practice of not only signed git commits, but also signing code releases with PGP keys be moved toward using SSH signatures instead. However, GitHub's practice of hiding the signing keys behind an API is problematic, as it encourages users attempting to automate signature verification add their signing keys to their authentication keys.

See also:

@dolmen dolmen changed the title Create separate signing keys for GitHub Create separate signing keys for Git commits Jan 4, 2024
@dolmen
Copy link
Owner

dolmen commented Jan 4, 2024

Thank you very much for this detailed information. I've not yet read any of the links, but thank you for this food for my mind. This is very appreciated. Also I'm glad to know that my little project has finally reached security circles.

From your explanation, I get confirmation that Git commit signing key are expected to have a different lifetime than the keys used for network authentication.

The purpose of this project has originally been to use separate keys for network authentication for each machine on which a GitHub user connects to the service. So not sharing keys between machines is a key feature.

But Git commit signing keys have different constraints such as a user wanting to use the same key on multiple machines.

So my inclination goes to continue to NOT support signing in github-keygen to keep the project focused on OpenSSH config setup and maintenance, because despites the project name being oriented towards key management, 95% of the code is about ~/.ssh/config management.

However, I also see more and more projects requiring signed commits (last example), so I'll have to enable signing for my own commits.

So once I'll be more familiar with the feature I intend to provide just guidance (documentation) on how to setup Git signing with SSH keys for github-keygen users: SSH key generation and Git setup.

IMHO, there is an argument the authentication keys should be private between GitHub and the users, and instead they should only show the signing keys, as others need to rely on them.

I totally agree. I consider the exposure of SSH authentication keys at githubusername.keys to be a security leak. This has been a major motivation for creating this project: as the public network key is more public than necessary (it should be private to my relationship with GitHub), I want to be sure to not leak it when connecting to other SSH services than GitHub.

@dolmen
Copy link
Owner

dolmen commented Jan 4, 2024

@ChristopherA
Copy link
Author

There also has been some discussion about some aspects of this problem in an issue at Github's docs repo:

github/docs#28577

@dolmen wrote:

I totally agree. I consider the exposure of SSH authentication keys at githubusername.keys to be a security leak. This has been a major motivation for creating this project: as the public network key is more public than necessary (it should be private to my relationship with GitHub), I want to be sure to not leak it when connecting to other SSH services than GitHub.

I'm trying to find the right place to raise this issue as well.

@dolmen
Copy link
Owner

dolmen commented Jan 10, 2024

@ChristopherA Thanks for your example of publishing signing keys on your GitHub account.

$ curl https://api.github.com/users/ChristopherA/ssh_signing_keys
[
  {
    "id": 184891,
    "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINTazxjqxsdh3Sv/7fxSTgr3qlCVByYoGDHHe428Fubp",
    "title": "eurynome.local/[email protected]",
    "created_at": "2023-10-26T06:28:34.882Z"
  },
  {
    "id": 219925,
    "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMU0/lvWurXvUcrvYNgfb02Ska0qpwC/yv22dvDIxxzh",
    "title": "kymindis.local/sign_id_ed25519_christophera@github 2024-01-04",
    "created_at": "2024-01-04T20:13:55.503Z"
  }
]
$ curl https://api.github.com/users/ChristopherA/keys
[
  {
    "id": 89661164,
    "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILC2xjpXdqx5Ur1845zpHedIkZn0/eNCFsWlBrZoUERO"
  },
  {
    "id": 92834190,
    "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMNOXm9gTvmGKttlmTchKqiQcqLObHgfABjSmGzZk4DY"
  }
]
$ curl https://github.com/ChristopherA.keys
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILC2xjpXdqx5Ur1845zpHedIkZn0/eNCFsWlBrZoUERO
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMNOXm9gTvmGKttlmTchKqiQcqLObHgfABjSmGzZk4DY

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

No branches or pull requests

2 participants