I have forked a project’s source code on GitHub. The program takes a private key as an input and that key must never leave the client. If I want to share a pre-built executable as a release it is essential that I can prove beyond reasonable doubt that it is built from the published source.

I have learned about how to publish the releases by using a Workflow in the GitHub actions such that GitHub itself will build the project and then repare a release draft with the built files as well as the file hashes…

However, I noticed that the release is first drafted, and at that point I have the option to manually swap the executable and the hashes. As far as I can tell, a user will not be able to tell if I swapped a file and its corresponding hashes. Or, is there a way to tell?

One potential solution that I have found is that I can pipe the output of the hashing both to a file that is stored and also to the publicly visible logs by using “tee”. This will make it such that someone can look through the logs of the build process and confirm that the hashes match the hashes published in the release.

Like this:

I would like to know whether:

  • There is already some built-in method to confirm that a file is the product of a GitHub workflow

  • The Github Action logs can easily be tampered by the repo owner, and the hashes in the logs can be swapped, such that my approach is still not good enough evidence

  • If there is another, perhaps more standard method, to prove that the executable is built from a specific source code.

  • prcrst@lemmy.world
    link
    fedilink
    arrow-up
    26
    ·
    1 year ago

    I don’t know whether github actions output can be tampered with by you, but the only actually reliable way (that I know of) to prove that your binaries correspond to a certain state of the sourcecode is to support reproducible builds (See e.g. https://reproducible-builds.org/).

    All other methods require trust (in either the developer or w.r.t. github actions towards github).

    The drawback is of course, that to verify whether your binaries are good, someone needs to rebuild the software, but it is a good tool to build and maintain trust in your signed binaries, especially if they deal with sensitive information like private keys.

    • torturedllama@lemmy.nz
      link
      fedilink
      arrow-up
      10
      ·
      1 year ago

      An important point to add for someone who hasn’t heard of reproducible builds before: The key difference to a normal build process is that it is 100% deterministic i.e. it produces exactly the same output every time.

      You might think that most built processes would be like this by default, however this is not the case. Compilers and linkers usually have some non-deterministic values that they put in the final binary such as timestamps. For a build to be deterministic these sources of variation must be disabled or mocked to be a repeatable value (i.e. not based on the actual compile time).

      • prcrst@lemmy.world
        link
        fedilink
        arrow-up
        5
        ·
        1 year ago

        True, while I think the page that I linked explains the concept well, it might not be easy to digest for someone who is new to software development.

        But then again, if you handle cryptographic materiel, you better learn fast 😃

    • Max
      link
      fedilink
      arrow-up
      2
      ·
      1 year ago

      All other methods require trust (in either the developer or w.r.t. github actions towards github).

      Hopefully some day I will be able to create reproducible builds independently of github. But I am thinking that their workflows are reproducible builds, correct? So, anyone should be able to fork the project and run the workflow and it will build the program in the same way. I am O.K with the user needing to trust GitHub on this - it really is me who I worry about. I don’t want to tell someone that they have to trust me. I want to be able to remove blind trust from my own personal contribution. The program itself is built on top of many dependencies, so the user is also implicitly trusting a large amount of maintainers.

      The drawback is of course, that to verify whether your binaries are good, someone needs to rebuild the software, but it is a good tool to build and maintain trust in your signed binaries, especially if they deal with sensitive information like private keys.

      In my specific scenario I’m forking a community project (a crypto wallet) that the maintainers no longer want to maintain nor share PR access to. I’m adding a patch to fix some broken hard-coded endpoints. So what I want to be able to do is to transparently say “Here is my very simple commit that you can read, and here is the executable in case you want to download the fixed wallet but are not technically savvy enough to build it”. I don’t have any reputation in this community, nor do I share my identity. I would prefer to be able to remove the element of trust. Asking trusted members of the community to build from source and verify the checksums would be nice, but I don’t think it is such a simple thing to ask in this case.

      (My instance won’t fetch content from lemmy.world, I’m not sure why… That’s why I switched to this account)

      • prcrst@lemmy.world
        link
        fedilink
        arrow-up
        5
        arrow-down
        1
        ·
        1 year ago

        But I am thinking that their workflows are reproducible builds, correct?

        A reproducible build is more than an automated build. It is a build process which enables any third party to build a binary that is bit-by-bit identical (see https://reproducible-builds.org/docs/definition/).

        So if I would build a specific release/commit of your application on my PC (given an identical development environment, i.e. same version dependencies, compiler, etc.) it MUST result in a bit-by-bit identical binary to the one you built on your development machine and the one the github workflows built.

        All these binaries would result in the same hash (and thus be verifiable by the same signature files).

        “Here is my very simple commit that you can read, and here is the executable in case you want to download the fixed wallet but are not technically savvy enough to build it”

        Other than a signed binary from a trusted developer/organization, there is (IMHO) no way for a non-tech savvy user to gauge the trustworthiness of a binary they download from the internet, and even then a signing key might have been lost or broken (see the recent Microsoft debacle w.r.t. AD signing key misuse).

        • Max
          link
          fedilink
          arrow-up
          3
          ·
          1 year ago

          Thanks a lot. I have been evangelized by you and the other commenters. I see now that reproducible builds is the solution.

          I now understand better the value of reproducible builds, and the more I think about it the more I realize that it is very bad that something as sensitive as a crypto wallet executable that does not follow the reproducible build standard has been going around. I do trust that the devs are not being malicious, but it is essential to have a good way to verify. Even the original github workflow is failing to build now, and new flags need to be passed to npm while building due to some openssl changes, so I’m not sure that anyone can actually reproduce the build today and get the same hash.

          I’ll read more about how to do it properly, and I’ll try to create a Reproducible Build fork if I can actually pull it off.