we’re proud to announce that conex, in an initial version, is now live! You can receive signed updates of the opam-repository. A quick guide:
To setup opam with conex on your machine, you need to install conex (and/or conex-mirage-crypto, see below) - currently only available as opam package (sorry about the bootstrap problem - hopefully it will be integrated into opam at some time).
Instead of “conex_verify_mirage_crypto”, you can as well use “conex_verify_openssl” (fewer dependencies, calls out to OpenSSL as the cryptographic provider, is slower).
Then you can run opam repo add conex-robur ``https://conex.robur.coop`` 1 sha256=ad5eb0e4a77abfbc6c1bb5661eba46049404e0222588dd059c87f12436d41a28. Thereafter you can opam repo remove default, and then you’re only using signed metadata. The “1” is the quorum of root keys for signatures to be valid, the “sha256=ad5eb0e4a77abfbc6c1bb5661eba46049404e0222588dd059c87f12436d41a28” is the hash of the public root key.
The opam.ocaml.org servers, which deliver the opam-repository by default, are operated on scaleway machines – and we couldn’t find any documentation of how this service is run and who has which privileges on it.
…you possibly didn’t look very hard; it’s in the ocaml/infrastructure repo:
Only @mtelvers and I have full access to that host, for obvious reasons of privilege minimization.
It wasn’t immediately obvious how to make this the default in all switches, but after poking around the manual a bit I came up with this that worked on opam 2.4.1:
Add the new repo to all switches, and make it the default for newly created switches (this doesn’t change the default in existing switches yet): opam repository add conex-robur --set-default --all-switches
Then remove the default repo from all switches: opam repo remove default --all-switches
And now there is only a conex-robur repo in all the switches.
Is this right, or is there a better way?
Would opam plugins be useful meanwhile? (I think the duniverse/opam-monorepo tools work that way). Then the path won’t depend on which switch you used to install it. IIUC this is a flag that can be set on the opam package and a naming convention.
Thanks for your pointer. Sorry I missed that, I was looking at opam.ocaml.org, not on GitHub repositories.
Only @mtelvers and I have full access to that host, for obvious reasons of privilege minimization.
That sounds fine, but I couldn’t find that information in the page you linked.
Also, I’m curious – there’s on the one side the host, on the other side the software and build pipeline it serves – so certainly there are other people who’re able to influence what is being served (again, I have no clue where these build pipelines and docker images are living, who hosts them, who can modify / update them). And here we’re deep down in the supply chain and potential trouble.
EDIT: for conex.robur.coop, the binary that is running has been build reproducible. So anyone can reproduce the exact same binary. What is missing is an attestation that what you get from conex.robur.coop is actually produced by the binary I said it would be. If anyone has experience how to setup attestation with such a service, let’s talk
There’s a limit to what we can document, especially when the interested readership is less than the number of fingers on my hand
But to be clear, your concerns are valid: the opam.ocaml.org server was never intended to be this grand central point in the OCaml software supply chain that it has become. I’ve just been very conservative about making changes to it due to its unfortunate importance in keeping the ecosystem ticking along.
Efforts like yours to start from the opam repository “source of truth” and construct alternative views are really important, as well as adding to the metadata identity base. My main feedback is that it would be good to figure out how to get this “into production” alongside opam next year, but also that it would be nice to support other emerging industry standards like SBOMs which would make integration into upstream package managers or Docker easier.
My main concern is the additional operational complexity: I remember when we turned on “Docker trusted images” and it was like a disaster zone of CIs breaking due to random key errors, and it never became the default. Very hard to debug. If you show a hash to a user in a CLI, your user experience is already dead
What binary? Is the binary a build scheduler? If so, it might be at least good to start down the SLSA path, although that is a lot of work:
Level 1 ( SLSA • Security levels ) would be generating a JSON document in the SLSA • Provenance format. Practically speaking, for robur I would expect that means exposing a REST API get_provenance: build_id → provenance_document, and the first day can just be the “RunDetails” schema describing the build infrastructure.
As someone who has reviewed this space for my own needs, all of that is pointless to expose to end-users until you can get to Level 2. That is, having a level of trust around the signing process. Normally that means a sibling trusted execution environment + HSM where the signing takes place and humans can’t tamper with it nor gain access to its keys. But the quorum in your doc implies bitwise reproducibility, so Level 2 may be a no-op if you have two independent systems that can publish to a public ledger.
On top of that, to @avsm ‘s point, the provenance/attestations should be transparent to the end-user. With the above in place, one possibility is to attach the identifiers for the provenance into opam-repository automatically as part of the approval process, and then having the opam client verify the attestation automatically. As a bonus, the opam client after verification can spit out the verification materials into a SBOM if the end-user needs it.
Anyway, that was my two cents. I appreciate the excellent work so far!