nodejs / TSC

The Node.js Technical Steering Committee
569 stars 127 forks source link

[meta] settle on a voting solution #1165

Open aduh95 opened 2 years ago

aduh95 commented 2 years ago

Every time we have to vote on a non-binary issue (where there are more options than "yes", "no", and "abstain"), we have to discuss what tool to use, and I think it'd be useful to have a "blessed" tool for voting.

I've proposed my own Caritat tool for the most recent vote, here are a few things I didn't like about it:

  1. The code is not controlled by the project.
  2. Only one individual was in power of closing the secret and revealing the ballots; that gives this individual a lot of power which I felt uncomfortable about.
  3. I've gotten feedback saying that the number of options was a bit overwhelming.

For those points, there are workarounds:

  1. Move the repo under the nodejs org.
  2. Distribute the trust. I have in mind a system where we would have a shared secret that can be rebuild only if a defined number of TSC members reveal their part of the key. @tniessen said he has another design in mind which I excited to hear about.
  3. Reduce the number of voting option to the web and Node.js CLI.

Whether we keep Caritat or not as a tool, I think we should use a system that uses git and GitHub to aggregate ballots. It's easy to audit, and it's probably fair to say everyone is comfortable with those tools already.

There are some settings we should tweak to improve the voting system:

What does everyone think?

jasnell commented 2 years ago

SGTM

Trott commented 2 years ago

I think @aduh95 should run with this. We can always revisit at a later date, but right now, they're invested and have a proposal and no one else seems to have strong concerns. 👍

tniessen commented 2 years ago

FWIW, if we do go with a cryptographic design, I'm still in favor of one that makes strong guarantees about distributed trust. We could look into Helios, but we probably don't want anonymous votes. I still like the idea of a web app that does all the magic in the browser using GitHub APIs.

@tniessen said he has another design in mind which I excited to hear about

This is an ad hoc design that I've only partially implemented, and it might be overengineered but I failed to come up with a simpler design that has the same (or better) security properties. It relies on Shamir's secret sharing (sharing the secret free coefficient of a polynomial), Diffie-Hellman (ECDH/X25519/X448), and symmetric encryption. It can optionally incorporate digital signatures (ECDSA/Ed25519/Ed448) in any of the steps to avoid the need of commit signing.

Short version > 1. _Offer_ phase: anyone who wants to help secure the vote (presumably at least the person initiating the vote) can offer a public key to be used for encryption, and for each such offered public key, each participant receives a point on a polynomial whose free coefficient is the private key. > 2. _Vote_ phase: anyone who wants to vote picks any number of subsets of offered public keys, a key pair, and for each selected set of public keys, derives bit sequences using their own private key and the offered public keys in that set, XORs the derived bit sequences to form a symmetric key, and uses the symmetric keys to encrypt their vote. > 3. _Reveal_ phase: depending on the degrees of the polynomials used in Step 1, a small number of participants reveal the points they received in Step 1, allowing everyone to compute the free coefficients of the polynomials used in Step 1, which are the private keys that were used to derive everyone's encryption keys, allowing everyone to decrypt everyone's votes. > > I don't want to go into too much detail yet. There are a few caveats regarding the choice of points on the polynomials in Step 1 and the key derivation in Step 2. > > Observations: > - No specific participant is required to interact in Step 1 or 3, the participation in those two phases is voluntary. > - Step 1 and Step 2 are not necessarily chronologically distinct. For example, each participant can offer a key right before they vote using subsets of previously offered keys, adding more options for the remaining participants. > - No participant is required to trust any particular other participant. > - The security is scalable in that, during Step 1, everyone can offer arbitrarily secure keys that require arbitrarily many participants to reveal the private key (in Step 3), and during Step 2, everyone can freely choose which keys they want to use. > - No single participant can reveal votes or prevent that votes are revealed (assuming more than one participant offers a public key in Step 1). > - The participants offering public keys in Step 1 are not required to participate in Step 3. > - Step 1 and Step 3 can be as simple as clicking a button on a website. > - A GitHub action could also automatically offer a public key in Step 1 to enhance security. Trusting GitHub is optional in that everyone could choose whether to use the offered key in Step 2. If we all trust GitHub, no human participant needs to do anything for Step 1, and everyone could exclusively use the key offered by the GitHub action in Step 2.

I am not saying we should use this (or any) cryptographic scheme, but if we do want to use any cryptographic scheme, it should have these (or similar) security properties. Happy to collaborate on design and/or implementation.

ljharb commented 2 years ago

If it’s not anonymous, this all seems a bit more complex than a signed and verified commit to a file in a voting repo (codeowners could be used to ensure that the only person changing their votes file is that person) - is there a reason that wouldn’t be sufficient?

tniessen commented 2 years ago

If it’s not anonymous, this all seems a bit more complex than a signed and verified commit to a file in a voting repo (codeowners could be used to ensure that the only person changing their votes file is that person) - is there a reason that wouldn’t be sufficient?

See https://github.com/nodejs/TSC/pull/1158#issuecomment-1033183907.

aduh95 commented 2 years ago
  • A GitHub action could also automatically offer a public key in Step 1 to enhance security. Trusting GitHub is optional in that everyone could choose whether to use the offered key in Step 2. If we all trust GitHub, no human participant needs to do anything for Step 1, and everyone could exclusively use the key offered by the GitHub action in Step 2.

I'm not sure this would be actually practical, I suppose we'd need to keep the associated private key somewhere – or we'd need to keep the GHA runner pending until the vote closes, but IIRC it would get killed by Github after 600 minutes.

Rest of it looks neat, and better than what I suggested :) I'll try to allocate some time to work on this soon-ish.

mhdawson commented 1 year ago

@aduh95 my take is that we may have settled on using your voting solution. Can this issue be closed?

aduh95 commented 1 year ago

@aduh95 my take is that we may have settled on using your voting solution. Can this issue be closed?

Most of it is implemented already, but I would still like to add automations and documentations to allow a vote to take place without me to set it up. I've started working on implementing the changes suggested by Tobias, I am planing to work on it during the holidays.

mhdawson commented 1 year ago

@aduh95, k thanks for the update.

mhdawson commented 1 year ago

@aduh95 just wondering if there is an update on this.

aduh95 commented 1 year ago

Yes I have some update! @stduhpf and I worked on a new version of Caritat taking into account the feedback received. Next steps are:

The technical choices we made that are arbitrary and can be discussed: