-
-
Notifications
You must be signed in to change notification settings - Fork 12
Document how to verify image signatures in an air-gapped environment #526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 5 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
d137d50
wip
dervoeti 372dcf7
Improved airgap image verification docs
dervoeti ed90c53
Fixes and wording improvements
dervoeti 649b1b2
Merge branch 'main' of https://github.com/stackabletech/documentation…
dervoeti 25f5b5a
Rewording / improved formatting
dervoeti 846fd19
reformulate
fhennig 3801cf1
Rewording / More explanations
dervoeti 2256b0d
Replaced "we"
dervoeti c18c9a0
Clarifications
dervoeti File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
26 changes: 0 additions & 26 deletions
26
modules/tutorials/examples/verify-signatures/kyverno-policy.yaml
This file was deleted.
Oops, something went wrong.
15 changes: 15 additions & 0 deletions
15
modules/tutorials/examples/verify-signatures/stackable-image-policy.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
apiVersion: policy.sigstore.dev/v1alpha1 | ||
kind: ClusterImagePolicy | ||
metadata: | ||
name: stackable-image-is-signed-by-github-actions | ||
spec: | ||
images: | ||
- glob: "**.stackable.tech/**" | ||
authorities: | ||
- keyless: | ||
url: https://fulcio.sigstore.dev | ||
identities: | ||
- issuer: https://token.actions.githubusercontent.com | ||
subjectRegExp: "https://github.com/stackabletech/.+/.github/workflows/build.yml@refs.+" | ||
ctlog: | ||
url: https://rekor.sigstore.dev |
53 changes: 38 additions & 15 deletions
53
modules/tutorials/pages/enabling_verification_of_image_signatures.adoc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,58 @@ | ||
= Enabling verification of image signatures | ||
|
||
Image signing is a security measure that helps ensure the authenticity and integrity of container images. Starting with SDP 23.7, all our images are signed https://docs.sigstore.dev/cosign/openid_signing/["keyless"]. By verifying these signatures, cluster administrators can ensure that the images pulled from Stackable's container registry are authentic and have not been tampered with. | ||
Since Kubernetes does not have native support for verifying image signatures yet, we will use a tool called https://kyverno.io/[Kyverno] in this tutorial. | ||
Image signing is a security measure that helps ensure the authenticity and integrity of container images. Starting with SDP 23.11, all our images are signed https://docs.sigstore.dev/cosign/openid_signing/["keyless"]. By verifying these signatures, cluster administrators can ensure that the images pulled from Stackable's container registry are authentic and have not been tampered with. | ||
Since Kubernetes does not have native support for verifying image signatures yet, we will use Sigstore's https://docs.sigstore.dev/policy-controller/overview/[Policy Controller] in this tutorial. | ||
|
||
IMPORTANT: Releases prior to SDP 23.7 do not have signed images. If you are using an older release and enforce image signature verification, Pods with Stackable images will be prevented from starting. | ||
IMPORTANT: Releases prior to SDP 23.11 do not have signed images. If you are using an older release and enforce image signature verification, Pods with Stackable images will be prevented from starting. | ||
|
||
== Installing Kyverno | ||
Kyverno can be easily installed via Helm: | ||
== Installing the Policy Controller | ||
The Policy Controller can be easily installed via Helm: | ||
|
||
[source,bash] | ||
---- | ||
helm repo add kyverno https://kyverno.github.io/kyverno/ | ||
helm repo add sigstore https://sigstore.github.io/helm-charts | ||
helm repo update | ||
helm install kyverno kyverno/kyverno -n kyverno --create-namespace | ||
helm install policy-controller sigstore/policy-controller | ||
---- | ||
|
||
Other installation methods and options to run Kyverno in a highly-available fashion are described in the https://kyverno.io/docs/installation/methods/[Kyverno documentation]. | ||
The default settings might not be appropriate for your environment, please refer to the https://artifacthub.io/packages/helm/sigstore/policy-controller[configurable values for the Helm chart] for more information. | ||
|
||
|
||
== Creating a policy to verify image signatures | ||
|
||
Now that Kyverno is installed, we can create a policy that verifies that all images provided by Stackable are signed by Stackable's CI pipeline (Github Actions): | ||
Now that the Policy Controller is installed, we can create a policy that verifies that all images provided by Stackable are signed by Stackable's CI pipeline (Github Actions): | ||
|
||
[source,yaml] | ||
include::example$verify-signatures/kyverno-policy.yaml[] | ||
include::example$verify-signatures/stackable-image-policy.yaml[] | ||
|
||
Apply this policy to the cluster by saving it as `stackable-image-policy.yaml` and running: | ||
[source,bash] | ||
---- | ||
kubectl apply -f stackable-image-policy.yaml | ||
---- | ||
|
||
Apply this policy to the cluster by saving it as `kyverno-policy.yaml` and running: | ||
If you used the default values for the Helm chart, policies will only be applied to namespaces labeled with `policy.sigstore.dev/include: "true"`. | ||
Add a label for the namespace where you deployed SDP: | ||
[source,bash] | ||
---- | ||
kubectl apply -f kyverno-policy.yaml | ||
kubectl label namespace stackable policy.sigstore.dev/include=true | ||
---- | ||
|
||
The policy will be applied to all namespaces in the cluster. It checks all newly created Pods that run any image matching the expression `docker.stackable.tech/+++*+++` (all images provided by Stackable) and ensures that these images have been signed by a Stackable Github Action (`https://github.com/stackabletech/+++*+++/.github/workflows/build.yml@refs/+++*+++`). If the signature of an image is invalid or missing, the policy will deny the pod creation. | ||
For a more detailed explanation of the policy options, please refer to the https://kyverno.io/docs/writing-policies/verify-images/sigstore/#keyless-signing-and-verification[Kyverno documentation]. | ||
If the `subject` field in the policy is changed to something like `https://github.com/test/+++*+++`, the policy will deny the creation of pods with Stackable images because the signature is no longer valid. | ||
The Policy Controller checks all newly created Pods in this namespace that run any image matching `+++**+++.stackable.tech/+++**+++` (this matches images provided by Stackable) and ensures that these images have been signed by a Stackable Github Action. If the signature of an image is invalid or missing, the policy will deny the pod creation. | ||
For a more detailed explanation of the policy options, please refer to the https://docs.sigstore.dev/policy-controller/overview/#configuring-image-patterns[Sigstore documentation]. | ||
If the `subjectRegExp` field in the policy is changed to something like `https://github.com/test/.+`, the policy will deny the creation of pods with Stackable images because the identity of the subject that signed the image (a Stackable Github Action Workflow) will no longer match the expression specified in the policy. | ||
|
||
== Verifying image signatures in an air-gapped environment | ||
As mentioned before, our images and Helm charts for SDP are signed keyless. Keyless signing is more complex than "classic" signing with a private and public key, but brings several https://www.chainguard.dev/unchained/benefits-of-keyless-software-signing[benefits]. It's also in line with Kubernetes, https://kubernetes.io/docs/tasks/administer-cluster/verify-signed-artifacts/[which uses keyless signing as well]. | ||
|
||
Describing the whole flow with all the components is out of scope for this documentation, so we will try to provide a summary of the most important parts instead: + | ||
To verify that an image has been signed by Stackable, customers check that the image has a valid signature and that this signature was created by Stackable's CI (Github Actions). More specifically, they check that the identity of the signer is one of Stackable's Github Actions workflows and that this identity has been confirmed by a trusted authority (Github in that case). The role of the Sigstore project https://github.com/sigstore/fulcio[Fulcio] is to issue a certificate for exactly that: + | ||
"This Fulcio instance confirms that this signature was created by `https://github.com/stackabletech/docker-images/.github/workflows/release.yml@refs/tags/23.11.0` and `https://token.actions.githubusercontent.com` confirmed that identity". | ||
fhennig marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
By default, the public Fulcio instance hosted by Sigstore is used for this, which is what we do at Stackable as well. | ||
|
||
That means customers wanting to verify these image signatures need to trust the Fulcio instance, which issues the certificates that attest the identity of the signer. The root of trust for Sigstore components like the public Fulcio instance is distributed by a framework called https://docs.sigstore.dev/signing/overview/#root-of-trust[The Update Framework (TUF)]. Thankfully, the whole initialization of the root of trust via TUF is handled by the Policy Controller. | ||
fhennig marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
The problem for air-gapped environments is that expiration of keys is built into TUF. That means, to verify image signatures continuously, the Policy Controller needs an up-to-date version of the root of trust. In a environment with internet access, it can just connect to Sigstore's TUF repository and get the latest contents. In an air-gapped environment, this is not possible. It is possible, however, to specify a TUF mirror that is reachable from the air-gapped environment, as explained https://docs.sigstore.dev/policy-controller/overview/#configuring-trustroot-for-custom-tuf-root[here]. This mirror could for example serve the contents of https://tuf-repo-cdn.sigstore.dev via HTTPS. Another way is to provide a base64 encoded, gzipped tarball of the TUF repository, as explained https://docs.sigstore.dev/policy-controller/overview/#configuring-trustroot-for-custom-tuf-repository[here]. Remember that in both cases the contents of the TUF repository need to be updated regularly. The Sigstore TUF repository is hosted at https://tuf-repo-cdn.sigstore.dev/ and the contents are also available https://github.com/sigstore/root-signing/tree/main/repository/repository[on github]. | ||
fhennig marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
You can then refer to the newly created `TrustRoot` (which is configured to use the TUF mirror) in the policy via the `trustRootRef` attribute, as shown https://docs.sigstore.dev/policy-controller/overview/#configuring-verification-against-different-sigstore-instances[in the Policy Controller's documentation]. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.