I have a set of objectives for PGP certificate uses, and have developed what what I think is a reasonable plan as a solution. What I'm wondering is:
Have I overlooked something important that requires, or strongly suggests, a change in my solution?
The question doesn't address the maintenance of the proposed collection of keys, or "best practices" for generation, backup, etc. All I'm interested in here is what traps I've set for myself, or security holes I've created, i.e., evaluate the plan itself.
I have perused many sources about using PGP keys and subkeys, most of which I cannot now point to, as it's been a long-term research issue and, expecting to find concrete answers, I didn't save my trail. There are opinions all across the board about using multiple subkeys of a single primary key for assorted purposes versus using multiple single-purpose dedicated primary keys. Two, opposing, views that I do recall, are from Alex Cabal and Alan Eliasen. (A debate I've not, yet, evaluated myself.)
As a second, interconnected issue, there seems to have been some debate (though all rather dated) about the use of elliptic curve keys and their "usefulness" due to lack of implementations in the wild that can handle them.
There are no known unusual threats present. State/well-funded actors have not targeted the business or me personally. There is no extraordinary business competition likely to target the business or its code base. The normal threats of random hackers, script-kiddies, etc. are always present, of course. The principle protections sought are code provenance and data integrity and verification. A side objective is to promote, by example, the adoption of PGP, and encourage more people, and businesses, to begin using PGP as the rule rather than the exception. Keeping the perceived usage as uncomplicated helps, I think, further that goal, and keeping the number of visible subkeys to a minimum on PGP certificates would seem to increase the "simple to use" perceptions.
I want to set up a system, or collection of PGP certificates, to support the following objectives:
- PGP key for signing commits to GitHub in the name of my business (code provenance)
- PGP key for SSH access to the business' account on GitHub (security and convenience)
- PGP key for the business to sign software releases and distributions, on or off GitHub (code integrity)
- PGP key for the business as a digital identity - email etc. - for encryption and signing primarily
- Create a separation of concerns between code creation, code distribution, and the "business as an entity", such that the keys can be used to:
- Sign commits to other repositories
- SSH access to other accounts, GitHub or otherwise
- Sign distributions not 100% sourced in-house
- Digitally sign documents not related to code at all
- Create a digital identity for the business as an entity that is not tied to the code, GitHub, or its software
- The ability to "retire" or replace any of the keys used above without affecting the others
- Apply a similar set of PGP keys where the identity is my person rather than the business.
In addition, I'd prefer to utilize elliptical curve (Curve25519/Ed25519) as close to exclusively as possible. Of course it is possible that there will be an occasion where I have to use RSA, and a method to gracefully "fall back" to RSA seems advisable. It is my hope, however, that all the activities for which I use a PGP key will be able to handle elliptical curves and the RSA functionality is never needed.
To meet these objectives, I have developed a pair of parallel plans. One for "identities" and the other to provide the "fall back" option.
For the identity plan, initially, I think a few distinct PGP certificates is workable, and meets the divisions given above:
- A certificate for the business, as an entity, with the ability to certify, sign, authenticate and encrypt.
- All UIDs are only for the business, with none connected to me, or any other employee
- None of the subkeys are used for signing software, git commits, distributions, or otherwise
- None of the subkeys are used for authentication on GitHub, or other code repositories
- A certificate used exclusively to sign software released by the business
- The signature is meant to indicate that the business is the distribution point for that package
- The signature also allows verifying the integrity of that package
- What the original source of the software might be is not part of the "signing"
- What channel is used for distribution shouldn't matter
- Whether it is source code or a binary blob also doesn't matter
- The certificate has no subkeys with auth or encrypt usage available
- This certificate is certified by the business-identity certificate above
- A third certificate used for GitHub
- The certificate has no encrypt usage subkeys
- The auth and sign usage is in two separate subkeys
- The auth subkey is only used to access the GitHub account of the business
- Any future access to other repositories would use a different, new, subkey
- The signing subkey is used to sign git commits and merges only, not releases on GitHub
- This certificate is certified by the business-identity AND the code-signing certificates above
- A new employee making commits would need a certificate, identical in all ways but the UID(s), to this one.
- A separate certificate could be made by an employee able to act on behalf of the business
- Functionally this would be identical to the first certificate, with the UIDs identifying them as part of the business, but not the business itself (either by name, or title - such as 'sales' or 'cfo'
- This certificate would be certified by the business-identity certificate.
Although it might be a bit extreme, I think a similar division of the first three certificates above, in my own name, for personal use is workable, and useful. Until there is other employees involved in the software process it seems rational for my personal certificates to certify the business certificate of the same purpose. At the moment, if the business signs a distribution, or release, it is "me" doing the signing under the authority of the business. Having my personal code-signing certificate as certifying the business one helps to make that connection. Should someone else become the responsible party, the certificate would need to be replaced anyway (a private key shared by two people is not "private" any longer). In that case, they could use some personal certificate to certify the new business code-signing key.
This arrangement of certificates seems to make explicit the connections between the purpose of the key and the identity of the business. It also leaves options available to accommodate the realities of the business world where mergers, splits, acquisitions, and dissolution happen on a daily basis.
The second half of the plan I developed, which accommodates a graceful "fall back" to RSA when, and if, needed has these guidelines for every PGP certificate made:
- The master key will be an ECC key (Ed25519)
- The master key will be
[C]enabled only, no
- The first subkey (automatically made) will:
- Use the same key type as the master ECC (Curve25519/Ed25519)
- Be single-purpose:
[SA]even though allowed
- The purpose chosen depends on what the key's use case is
[A]for certificates which are primarily for SSH, or similar uses
[S]for certificates which are primarily for providing digital signatures
[E]for certificates which are primarily general-purpose usage for individuals, (most likely used for email and other communications and I prefer to encourage encryption when I can)
[S]for general-purpose certificates for business-entities where the need to "sign" things, and communications, likely outweigh the need to encrypt the communications.
- Be set as expired as soon as it is made
- Additional subkeys (there will always be at least one set) are:
[SA]even though allowed
- Be the same key-type as the master key, ECC (Curve25519/Ed25519)
- Set with an expiry in the 6-12 month range (depending on use and exposure, etc.)
- Have an additional subkey made, with the same usage, and the opposite key-type RSA-4096
- The additional subkey is set as expired as soon as it is made
As an extra layer of "fall back" capability, each certificate made above is complimented by an additional certificate, with the same set of subkeys, usages, and expirations. The differences are: 1) that where the first one has ECC subkeys the second one has RSA subkeys, 2) the ECC subkeys are set as expired rather than the RSA subkeys, and 3) the certificate itself is also set as expired (making the unexpired RSA subkeys unusable anyway). To help make the "fall back" graceful, both keys certify the other, and any certificates I use to certify the ECC version will also certify the RSA version. Also anytime I use the ECC certificate to certify a connected certificate, such as the code-signing certificate above, I also use the RSA twin certificate to certify the same certificate. (Thus, each "certification" involves four signatures: each of the two "certifying" keys signing each of the two "certified" keys, not counting that it's actually the UID(s) that are signed.)
Having all but one subkey of any given usage expired forces client programs to "select" the one usable key, whether or not it is the most recent one for that usage. If I encounter a situation where I must use RSA, I can unexpire the relevant subkey without loosing previously made signatures, etc. In the event that I am forced to switch to an RSA master key (unlikely, in my thinking), I also have one available, which is counter-certified by the already in-use ECC key that is it's twin.
If, somehow, the secret key for the in-use subkey become compromised, I still have the originally created subkey as a last resort. I can revoke the compromised subkey(s) and retrieve the original subkey and continue operations. That subkey remains un-imported on my keyring, or even exported to the keyservers, and stored offline with the same security as the primary secret key itself. Better, I believe, would be to revoke the compromised key and issue a new subkey with the same usage and type under the same master key.
From a daily-use stand point, the active keyring only has the subkeys that are made for the certificates purpose (both the ECC and RSA subkeys) from the ECC master key. The master key itself, the automatically created first subkey, and the complete RSA twin master keyset remain on the backup media.
By way of demonstration, and to make explicit exactly what the plan looks like in action, I've generated a set of PGP certificates. I then used GnuPG to list the keys, and signatures from various view-points. First is the key generation system, which knows all, called "as-generated'. Second is how they would be imported into my keyring, ECC certs only, and limited subkeys, called "in-keyring". Third is what would be publicly available from the keyservers, called "keyserver". All six (three views with and without signatures) listings have been posted in a Gist so that they can be viewed to "see what I mean" if necessary. (I wanted to include them here, but it seemed way to long to include in the question.)
So, this wall of text supports one question:
Have I overlooked something important that requires, or strongly suggests, a change in my solution, and should it have been done a better way?