Skip to content
This repository was archived by the owner on Feb 26, 2024. It is now read-only.
This repository was archived by the owner on Feb 26, 2024. It is now read-only.

Considerations for listing signer identities in the gemspec #64

@rochlefebvre

Description

@rochlefebvre

In the current RFC draft, we mention on a few occasions that the signer's email address must be listed in the gemspec's email field before generating a signature. Issues #57 and #58 briefly touch on the subject as well. I'm unsure if this requirement is well explained anywhere, or whether it's 100% required. I thought I would capture some reasoning on including vs. omitting a signer identity in the gem itself.

Since anyone can acquire a Fulcio certificate and upload a signature into Rekor, it's up to RubyGems to filter or ignore unauthoritative signatures: we only want to validate signatures from gem maintainers. In broad terms, either the gem itself enumerates who may sign it, or an external authority like Rubygems.org does.

Enumerating signing identities in the gem

Once a gem's digest is computed and then signed, any subsequent modifications invalidates the signature, by design. If we ask maintainers to list the identities of allowed signers (e.g. email address, profile URI, or some other form of username) in the gemspec, then no one may add themselves to the list afterwards. This attestation of authorship can't be removed or reassigned by anyone, not even rubygems.org. It is immune to any subsequent compromise.

As long as the signing certificate's subject figures in that list, then anyone verifying an associated signature should accept its authenticity.

The first time a maintainer wishes to sign their work, they will need to determine what identity to sign their work as, and they will need to input this identity into the gemspec, perhaps manually. We'll need to think of ways to configure this ahead of (or as part of) a gem build or gem signatures --sign operation. Perhaps a one-time gem signatures --enroll command prompts the user to authenticate with an identity provider and then adds the resulting identity to a local config resource?

Pros

  • works without any changes to the gem repository
  • the signer may no longer be a maintainer in the future, but their signature will still be recognized as valid for that version

Cons

  • impossible to add new signers once a gem is built
  • point of confusion and failure when adding a new maintainer to a gem

rubygems.org as the authority for authorized gem signers

If we don't want to force maintainers to identify themselves in the gemspec, then the gem repository is the next logical gatekeeper. The repository could provide a list of recognized gem maintainers for each version, or list them for a given point in time. This information should persist even as maintainers leave a gem, or if their rubygems.org account gets deleted. To my knowledge, the repository does not currently maintain nor expose this kind of historical maintainer info.

Whether this list is exposed via an API or is downloaded by gem clients (like the specs files under ~/.gem/specs), this requires non-trivial changes to rubygems.org to provide this info.

Also, a compromised repository could legitimize fraudulent signatures in certain cases.

Pros

  • no need to declare signing identities in a gemspec
  • having external control over who is allowed to sign a gem version could be considered a feature?

Cons

  • requires changes in rubygems.org, otherwise signatures are kinda useless.
  • a compromised rubygems.org may allow fraudulent signatures to appear valid
  • per-gem allowed signer lists need to be made available to gem clients at install time (API calls, new spec indexes, etc)

Recommendation

I suggest we try the gemspec approach first, especially in the M1 timeframe. The repository approach is more complex and feels more vulnerable to forgery and to issues with availability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions