You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dangerzone currently relies on a container image to do the conversion work. This image is shipped as part of the application packages (.msi.dmg, .rpm, .deb files, depending on the platform).
This has a few disadvantages:
There is no way to update the image unless we issue a new release. This is problematic because:
It makes us issue new releases "just" to upgrade the security of the container ;
The image can get out of date, and have security breaches. Old versions are still installable, but they contain an un-patched container image ;
Including the images inside the packages inflates their size ;
Having images included in the packages doesn't comply with the Debian policy, making it a roadblock for inclusion in upstream Debian.
Rather than including the images in the application packages, they will be published to a registry, and dangerzone will be checking for new images as part of its update mechanism (only if enabled by the client - opt in).
Note
Slim Versions
We are thinking about having two different kind of versions:
"Full" versions, which will contain the original container image ; and
"Slim" versions, containing everything except the container image itself
(thanks Ethan for the idea)
Overview
Here a general high level overview how what will be done:
Releaser standpoint:
Container images will be built nightly by Github Actions, and published to the GitHub Container Registry (abbreviated to "ghcr" for the rest of this text).
They will not be tagged as latest by default. Their tag will have a format like YYYYMMDD-<version>-g<commit>, e.g., 20241219-0.8.0-77-g06a9117.
Achieving SLSA level 3 is trivially possible (link). In practice, we can't rely on just SLSA 3, but it's a good to have.
When we would like to update the container image, we will:
Get the hash of the container image we want to ship ;
Hop on our signer machines, and build the image by our own means.
Check that the produced image matches the one published in the nightlies (see the section on reproducible builds for more info)
Verify attestations, checking for the provenance of the image.
Sign the container image and tag it to be the latest one in the ghcr (see Sign container images #1036 for details). While doing so, the previous attestations will remain there, and have a signature on top. This will make it available for download.
We can sign the container image using our YubiKeys, as we already do for releases.
Client standpoint:
In addition to checking for new "releases" (see design doc), check if new images are available, either by looking GitHub's Package API (docs), or directly GitHub's container registry API.
When a new image is available tagged as latest, check its signature against a known key (embedded in the application package)
Download the new image using {docker,podman} pull
(Optional ?) Verify that the image has been built by GitHub, for our organization and from a specified workflow. This double verification will help in the (admittedly catastrophic) scenario where our HSM becomes compromised.
Reproducible Builds
Because we don't want to put too much trust in the Github Container Registry (and in general in the Microsoft Github ecosystem), having reproducible containers is important for us.
With reproducible builds, it's possible to ensure that a local build of a container image is the same as one built on a different infrastructure. For Dangerzone, reproducibility is currently implemented in a WIP branch, as part of this « Independent Container Updates ».
Note
It's not easy to check that the image digests match due to different file timestamps. However, we can use diffoci in order to check everything else (file contents, permissions) and ignore timestamps.
In order to either publish data to the container registry or retrieve information, we might want to use a tool to do that for us.
Container registries follow the Manifest v2 specification, and as such client side tools exist. We quickly wrote a simple script (that needs some more information) able to download following the Cosign Bundle Spec. It's not clear yet if we should write something or if something already exist in python to do that for us.
Tool comparison
We are currently not sure which tool we should use to verify signatures and attestations. There is an array of options available. Here is a summary of their capabilities:
* Size before compression ¹ Following the Cosign Bundle Spec ² Following the Cosign Signature Spec ³ At the time of writing, cosign doesn't embed a way to verify the attestations produced by the Cosign Bundle Spec. without tools to interact with the container registry on the side. As such a small gymnastic is currently required. It's possible to track the progress on this effort here. ⁴ sigstore-python provides ways to sign attestations using a DSSE, but doesn't include ways to interact with container registries
A rust library also exists (sigstore-rs) but we kept it out because it's described as "under active development and will not be considered stable until the 1.0 release." I'll add a note about it.
Future work
Keyless signing
Sigstore provides a way to sign without using keys, that they call "Keyless Signing". This builds on top of OIDC providers (think GitHub or Microsoft accounts), and does the following:
Login to an OIDC provider
Generate a key pair from it:
privKey: temporary signing key, that never hits the disk
pubKey: derived from the public key
Apply the signature
Publish the pubKey to the certificate transparency log
We might want to use keyless signing in the future, where images could be signed by multiple identities.
These identities could be defined at the time of the release, effectively embedding the trust model in the published package. For instance, we could embed a rule stating that container updates should be coming from either apyrgio@github or almet@github.
Edit: added issue content (@almet)
Edit 2: clarified the fact we're adding signatures on top of attestations, and that we are not using HSMs
The text was updated successfully, but these errors were encountered:
Dangerzone currently relies on a container image to do the conversion work. This image is shipped as part of the application packages (
.msi
.dmg
,.rpm
,.deb
files, depending on the platform).This has a few disadvantages:
Rather than including the images in the application packages, they will be published to a registry, and dangerzone will be checking for new images as part of its update mechanism (only if enabled by the client - opt in).
Note
Slim Versions
We are thinking about having two different kind of versions:
(thanks Ethan for the idea)
Overview
Here a general high level overview how what will be done:
Releaser standpoint:
Container images will be built nightly by Github Actions, and published to the GitHub Container Registry (abbreviated to "ghcr" for the rest of this text).
latest
by default. Their tag will have a format likeYYYYMMDD-<version>-g<commit>
, e.g.,20241219-0.8.0-77-g06a9117
.When we would like to update the container image, we will:
latest
one in the ghcr (see Sign container images #1036 for details). While doing so, the previous attestations will remain there, and have a signature on top. This will make it available for download.Client standpoint:
latest
, check its signature against a known key (embedded in the application package){docker,podman} pull
Reproducible Builds
Because we don't want to put too much trust in the Github Container Registry (and in general in the Microsoft Github ecosystem), having reproducible containers is important for us.
With reproducible builds, it's possible to ensure that a local build of a container image is the same as one built on a different infrastructure. For Dangerzone, reproducibility is currently implemented in a WIP branch, as part of this « Independent Container Updates ».
Note
It's not easy to check that the image digests match due to different file timestamps. However, we can use
diffoci
in order to check everything else (file contents, permissions) and ignore timestamps.See #188 for details on the matter.
Interaction with Container Registries
In order to either publish data to the container registry or retrieve information, we might want to use a tool to do that for us.
Container registries follow the Manifest v2 specification, and as such client side tools exist. We quickly wrote a simple script (that needs some more information) able to download following the Cosign Bundle Spec. It's not clear yet if we should write something or if something already exist in python to do that for us.
Tool comparison
We are currently not sure which tool we should use to verify signatures and attestations. There is an array of options available. Here is a summary of their capabilities:
*
Size before compression¹
Following the Cosign Bundle Spec²
Following the Cosign Signature Spec³
At the time of writing,cosign
doesn't embed a way to verify the attestations produced by the Cosign Bundle Spec. without tools to interact with the container registry on the side. As such a small gymnastic is currently required. It's possible to track the progress on this effort here.⁴
sigstore-python provides ways to sign attestations using a DSSE, but doesn't include ways to interact with container registriesFuture work
Keyless signing
Sigstore provides a way to sign without using keys, that they call "Keyless Signing". This builds on top of OIDC providers (think GitHub or Microsoft accounts), and does the following:
privKey
: temporary signing key, that never hits the diskpubKey
: derived from the public keypubKey
to the certificate transparency logWe might want to use keyless signing in the future, where images could be signed by multiple identities.
These identities could be defined at the time of the release, effectively embedding the trust model in the published package. For instance, we could embed a rule stating that container updates should be coming from either
apyrgio@github
oralmet@github
.Edit: added issue content (@almet)
Edit 2: clarified the fact we're adding signatures on top of attestations, and that we are not using HSMs
The text was updated successfully, but these errors were encountered: