<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Flux – security</title><link>https://deploy-preview-2413--fluxcd.netlify.app/tags/security/</link><description>Recent content in security on Flux</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Thu, 09 Nov 2023 00:00:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-2413--fluxcd.netlify.app/tags/security/index.xml" rel="self" type="application/rss+xml"/><item><title>Blog: Second Flux Security Audit has concluded</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/11/flux-security-audit/</link><pubDate>Thu, 09 Nov 2023 00:00:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/11/flux-security-audit/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2023/11/flux-security-audit/featured-image_hudd23c93a0b637265205ddee09c3d9da3_82354_640x0_resize_box_3.png" width="640" height="185"/>
&lt;p>Precisely 2 years after
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/">performing our first security Audit&lt;/a>,
we had the chance to put Flux through a second audit this year, again
facilitated by the CNCF and the
&lt;a href="https://ostif.org/" target="_blank">Open Source Technology Improvement Fund&lt;/a>.
&lt;a href="https://www.trailofbits.com/" target="_blank">Trail of Bits&lt;/a> partnered with us this time
to make Flux even more secure. Flux passed the &amp;ldquo;General Availability&amp;rdquo;
milestone earlier this year and the focus was on the features shipped in
the Flux GA release.&lt;/p>
&lt;p>The Flux maintainers and community are very grateful for the work put
into this by everyone and the opportunity to grow and improve as a
project. Thanks to Trail of Bits, notably Maciej Domański, Sam Alws, Sam Greenup and Jeff Braswell, who have always been extremely responsive during the process.&lt;/p>
&lt;p>&lt;img src="featured-image.png" alt="TOB, CNCF, OSTIF">&lt;/p>
&lt;h2 id="no-new-cves">No new CVEs&lt;/h2>
&lt;p>Good news first: No new CVEs have been published for Flux in response to
this second audit. Trail of Bits highlight that they found Flux was &amp;ldquo;well
structured and generally written defensively&amp;rdquo; and the &amp;ldquo;audit uncovered
only low- and informational-severity findings&amp;rdquo;, 10 in total. 8 of the
discovered issues have been fixed as of publication of this announcement. From the remaining two issues to be fixed, one is in the process of being resolved and for the other one we have decided to accept the very low risk due to reasons mentioned in the report.&lt;/p>
&lt;p>The assessment was kicked off with a list of 23 questions to be answered,
circling around potential data leaks, security documentation, access
control or denial of service vulnerabilities. Since the focus was on the
GA components, the following parts of Flux have been put under scrutiny:&lt;/p>
&lt;ul>
&lt;li>source-controller&lt;/li>
&lt;li>kustomize-controller&lt;/li>
&lt;li>notification-controller&lt;/li>
&lt;li>Flux CLI&lt;/li>
&lt;li>The &lt;code>pkg&lt;/code> library, and &lt;code>git/gogit/fs&lt;/code> in particular&lt;/li>
&lt;/ul>
&lt;h2 id="details-on-the-discovered-issues">Details on the discovered issues&lt;/h2>
&lt;p>You will find the full report
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux-security-report-with-review-2023.pdf">here&lt;/a>. The following table shows all the findings together with links to the pull requests fixing them:&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Issue&lt;/th>
&lt;th>Severity&lt;/th>
&lt;th>Fix&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1: SetExpiration does not set the expiration for the given key&lt;/td>
&lt;td>low&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/source-controller/pull/1185" target="_blank">source-controller#1185&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2: Inappropriate string trimming function&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/notification-controller/pull/590" target="_blank">notification-controller#590&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3: Go’s default HTTP client uses a shared value that can be modified by other components&lt;/td>
&lt;td>low&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/pull/4182" target="_blank">flux2#4182&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>4: Unhandled error value&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/pull/4181" target="_blank">flux2#4181&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5: Potential implicit memory aliasing in for loops&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/source-controller/pull/1257" target="_blank">source-controller#1257&lt;/a>,
&lt;a href="https://github.com/fluxcd/notification-controller/pull/627" target="_blank">notification-controller#627&lt;/a>,
&lt;a href="https://github.com/fluxcd/flux2/pull/4329" target="_blank">flux2#4329&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>6: Directories created via os.MkdirAll are not checked for permissions&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>n/a&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>7: Directories and files created with overly lenient permissions&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/pkg/pull/663" target="_blank">pkg#663&lt;/a>,
&lt;a href="https://github.com/fluxcd/pkg/pull/681" target="_blank">pkg#681&lt;/a>,
&lt;a href="https://github.com/fluxcd/source-controller/pull/1276" target="_blank">source-controller#1276&lt;/a>,
&lt;a href="https://github.com/fluxcd/kustomize-controller/pull/1005" target="_blank">kustomize-controller#1005&lt;/a>,
&lt;a href="https://github.com/fluxcd/flux2/pull/4380" target="_blank">flux2#4380&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>8: No restriction on minimum SSH RSA public key bit size&lt;/td>
&lt;td>informational&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/pull/4177" target="_blank">flux2#4177&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>9: Flux macOS release binary susceptible to dylib injection&lt;/td>
&lt;td>low&lt;/td>
&lt;td>in progress&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10: Path traversal in SecureJoin implementation&lt;/td>
&lt;td>undetermined&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/pkg/pull/650" target="_blank">pkg#650&lt;/a>,
&lt;a href="https://github.com/go-git/go-billy/pull/31" target="_blank">go-git/go-billy#31&lt;/a>,
&lt;a href="https://github.com/go-git/go-billy/pull/34" target="_blank">go-git/go-billy#34&lt;/a>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>In addition to the pull requests linked above we also enabled security
and quality CI checks through CodeQL via
&lt;a href="https://github.com/fluxcd/flux2/issues/4121" target="_blank">flux2#4121&lt;/a> to prevent any avoidable regressions.&lt;/p>
&lt;h2 id="conclusion-and-next-steps">Conclusion and next steps&lt;/h2>
&lt;p>From our perspective as Flux maintainers, 2 years feel like a lifetime. We added lots of new features and fixed even more bugs in that timeframe. That&amp;rsquo;s why we
are particularly grateful that CNCF and OSTIF gave us the opportunity to
let a team of security experts assess Flux another time. We are proud
of having been able to learn from the first assessment and kept on making
Flux more and more secure over these past 2 years, leading to only low-
and informational-severity security findings within the GA components of
Flux.&lt;/p>
&lt;p>Our
&lt;a href="https://fluxcd.io/roadmap/#flux-helm-ga-q3-2023" target="_blank">next milestone&lt;/a> is the general availability of Flux’s Helm features and the subsequent general availability of the remaining Flux components. If you are interested in contributing to this, we are very much looking forward to working with you. We welcome contributions in helping resolve issues of the road, additional comments on our security posture and also
welcome contributions in the form of extending our fuzzing
infrastructure. Finally, if you have any additional security feedback,
please come and talk to us.&lt;/p>
&lt;p>Again we would like to thank the Cloud Native Computing Foundation for
sponsoring the audit, the Open Source Technology Improvement Fund for
the coordination and Trail of Bits for the careful review and advice
during the audit period.&lt;/p>
&lt;p>We are happy and proud to be part of this community!&lt;/p></description></item><item><title>Blog: Verify the integrity of the Helm Charts stored in OCI-compliant registries as OCI artifacts</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/11/verify-the-integrity-of-the-helm-charts-stored-as-oci-artifacts-before-reconciling-them-with-flux/</link><pubDate>Mon, 14 Nov 2022 10:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/11/verify-the-integrity-of-the-helm-charts-stored-as-oci-artifacts-before-reconciling-them-with-flux/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/11/verify-the-integrity-of-the-helm-charts-stored-as-oci-artifacts-before-reconciling-them-with-flux/_hu6c20d1d06ecc89706fad13ea2ad1710b_87991_8c0395bfd31e0d29f1f54ba50a78c50f.png" width="640" height="897"/>
&lt;p>Cosign integration was one of the most important features we shipped in the Flux
&lt;a href="https://github.com/fluxcd/flux2/releases/tag/v0.35.0" target="_blank">v0.35 release&lt;/a>. After that, we wrote a
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/">blog post&lt;/a> which explains how to use the feature with
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/ocirepositories/">OCIRepository&lt;/a> resources which enables fetching OCI artifacts from container registries. If you haven&amp;rsquo;t read it yet, we highly encourage you to go and check it out first.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 509px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/11/verify-the-integrity-of-the-helm-charts-stored-as-oci-artifacts-before-reconciling-them-with-flux/_hu6c20d1d06ecc89706fad13ea2ad1710b_87991_a5ed55b10233131aecbda548f64b38f4.png" width="499" height="700">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>Flux v0.36.0 allows you to prove the authenticity of
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/helmcharts/">HelmChart&lt;/a> resources with the help of the &lt;code>cosign&lt;/code> integration. Here we will demonstrate how to use the cosign integration to verify the integrity of the Helm charts stored in OCI-compliant registries as OCI artifacts.&lt;/p>
&lt;blockquote class="twitter-tweet">&lt;p lang="en" dir="ltr">Not at &lt;a href="https://twitter.com/hashtag/kubecon?src=hash&amp;amp;ref_src=twsrc%5Etfw">#kubecon&lt;/a> so I had time to prepare Flux and Flagger releases. Flagger v1.24 comes with signed releases &amp;amp; OCI Helm charts. Flux v0.36 adds support for verifying Helm charts with Cosign. &lt;a href="https://t.co/6MYwzfMA3W">https://t.co/6MYwzfMA3W&lt;/a>&lt;/p>&amp;mdash; Stefan Prodan (@stefanprodan) &lt;a href="https://twitter.com/stefanprodan/status/1585710554018037761?ref_src=twsrc%5Etfw">October 27, 2022&lt;/a>&lt;/blockquote>
&lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8">&lt;/script>
&lt;p>Starting with Helm
&lt;a href="https://helm.sh/blog/storing-charts-in-oci/" target="_blank">v3.8.0&lt;/a>, Helm supports the OCI registry as a one of the storage option for Helm charts as an alternative to Helm repositories. The
&lt;a href="https://helm.sh/docs/helm/helm/" target="_blank">Helm CLI&lt;/a> can push and pull Helm charts to and from OCI-compliant registries.&lt;/p>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> Prior to Helm v3.8.0, OCI support was experimental. To use it there, you need to enable the feature by setting the &lt;code>HELM_EXPERIMENTAL_OCI&lt;/code> environment variable to &lt;code>1&lt;/code>.
&lt;/div>
&lt;p>As we store Helm charts in OCI-compliant registries as OCI artifacts, we can now use the cosign integration to sign and verify them. Also, thanks to Flux, you can reconcile resources such as plain-text Kubernetes YAML manifests, Terraform modules, etc. from OCI-compliant registries with the help of &lt;code>OCIRepository&lt;/code> resources. You can achieve the same thing for Helm charts with
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/helmrepositories/#helm-oci-repository">HelmRepository&lt;/a> resources. This means that you can store Helm charts in OCI-compliant registries as OCI artifacts and use Flux to reconcile them like the following:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#0e84b5;font-weight:bold">---&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>source.toolkit.fluxcd.io/v1beta2&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>HelmRepository&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>podinfo&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">namespace&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>default&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;oci&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m0s&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>oci://ghcr.io/stefanprodan/charts&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> &lt;p>Here you can review the complete registries lists that support the OCI artifact specification:
&lt;a href="https://conformance.opencontainers.org/#distribution-spec" target="_blank">OCI-Conformant Products&lt;/a>.&lt;/p>
&lt;p>You will notice that when you open the list, DockerHub is not included into the list but it will be added soon because they recently announced OCI Artifacts support, and you can read more about it from
&lt;a href="https://www.docker.com/blog/announcing-docker-hub-oci-artifacts-support/" target="_blank">here&lt;/a>.&lt;/p>
&lt;/div>
&lt;p>Let&amp;rsquo;s jump right into the details of how we can actually use it.&lt;/p>
&lt;p>We will deploy
&lt;a href="https://prometheus.io/" target="_blank">Prometheus&lt;/a> by using its community
&lt;a href="https://github.com/prometheus-community/helm-charts" target="_blank">Helm charts&lt;/a> stored as OCI artifacts in OCI registry. Recently, Prometheus&amp;rsquo; community started to publish their Helm charts to OCI registries and sign them with cosign using the
&lt;a href="https://github.com/sigstore/cosign/blob/main/KEYLESS.md" target="_blank">keyless&lt;/a> approach, you can learn more the process
&lt;a href="https://github.com/prometheus-community/helm-charts/pull/2631" target="_blank">here&lt;/a>. Then we are going to verify it with &lt;em>cosign&lt;/em> and configure Flux to verify the Helm chart&amp;rsquo;s signatures before they are downloaded and reconciled. As the Prometheus community signed their Helm Charts without providing a key pair, we do not need to specify any key in the HelmChart resource&amp;rsquo; &lt;code>provider.cosign&lt;/code> spec to enable keyless verification for Flux.&lt;/p>
&lt;blockquote>
&lt;p>For the sake of simplicity, we&amp;rsquo;ve deployed Prometheus alone but if you want to learn more about installing the Prometheus stack including Grafana, Alertmanager, etc., please refer to the official Flux
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/guides/monitoring">page&lt;/a> that can help you to do that.&lt;/p>
&lt;/blockquote>
&lt;p>You need three things to complete this demo;&lt;/p>
&lt;ul>
&lt;li>&lt;em>cosign&lt;/em> CLI
&lt;ul>
&lt;li>
&lt;a href="https://docs.sigstore.dev/cosign/installation/" target="_blank">https://docs.sigstore.dev/cosign/installation/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>A Kubernetes cluster
&lt;ul>
&lt;li>
&lt;a href="https://kind.sigs.k8s.io/#installation-and-usage" target="_blank">https://kind.sigs.k8s.io/#installation-and-usage&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;em>Flux&lt;/em> CLI
&lt;ul>
&lt;li>
&lt;a href="https://fluxcd.io/flux/cmd/" target="_blank">https://fluxcd.io/flux/cmd/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s start by creating a simple Kubernetes cluster:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kind create cluster
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Use the Flux CLI to do pre-flight checks:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux check --pre
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>► checking prerequisites
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>✔ Kubernetes 1.25.3 &amp;gt;&lt;span style="color:#666">=&lt;/span>1.20.6-0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>✔ prerequisites checks passed
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If the checks are successful, you can install Flux on the cluster.&lt;/p>
&lt;p>Let&amp;rsquo;s install Flux on it - if you need to use other options, check out the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/installation/">installation page&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">GITHUB_USER&lt;/span>&lt;span style="color:#666">=&lt;/span>developer-guy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">GITHUB_TOKEN&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#bb60d5">$GITHUB_TOKEN&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>flux bootstrap github &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --owner&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#bb60d5">$GITHUB_USER&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --repository&lt;span style="color:#666">=&lt;/span>flux-cosign-helm-oci-demo &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --branch&lt;span style="color:#666">=&lt;/span>main &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --path&lt;span style="color:#666">=&lt;/span>./clusters/my-cluster &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --personal
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> Don’t forget to change the values with your own details!
&lt;/div>
&lt;p>As we stick to GitOps practices, we only create files that contain the &lt;code>HelmRepository&lt;/code> and &lt;code>HelmRelease&lt;/code> resources. After committing and pushing those changes into the upstream repository, Flux will watch for changes and use them as source-of-truth for the configuration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>git clone git@github.com:developer-guy/flux-cosign-helm-oci-demo.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">cd&lt;/span> flux-cosign-helm-oci-demo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s create the &lt;em>HelmRepository&lt;/em> resource first:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>flux create &lt;span style="color:#007020">source&lt;/span> helm prometheus-community &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --url&lt;span style="color:#666">=&lt;/span>oci://ghcr.io/prometheus-community/charts &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --interval&lt;span style="color:#666">=&lt;/span>10m &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --export &amp;gt; ./clusters/my-cluster/prometheus-community-helmrepository.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, let&amp;rsquo;s move on with creating the &lt;em>HelmRelease&lt;/em> resource:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>flux create helmrelease prometheus &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --source&lt;span style="color:#666">=&lt;/span>HelmRepository/prometheus-community &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --chart&lt;span style="color:#666">=&lt;/span>prometheus &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --interval&lt;span style="color:#666">=&lt;/span>10m &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --release-name prometheus &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --target-namespace&lt;span style="color:#666">=&lt;/span>monitoring &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --create-target-namespace &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --export &amp;gt; ./clusters/my-cluster/prometheus-helmrelease.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and run the following command to add the &lt;code>verify&lt;/code> section to the &lt;em>HelmRelease&lt;/em> resource&amp;rsquo; &lt;code>.spec.chart.spec&lt;/code> section to enable keylesss verification:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>yq e &lt;span style="color:#4070a0">&amp;#39;.spec.chart.spec|=({&amp;#34;verify&amp;#34;: { &amp;#34;provider&amp;#34;: &amp;#34;cosign&amp;#34; } } +.)&amp;#39;&lt;/span> ./clusters/my-cluster/prometheus-helmrelease.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command above will add the following part to the &lt;code>HelmRelease&lt;/code> resource&amp;rsquo;s &lt;code>.spec.chart.spec&lt;/code> section:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">verify&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">provider&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>cosign&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>then, commit and push the changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>git commit -m &lt;span style="color:#4070a0">&amp;#34;Add prometheus HelmRelease and HelmRepository resources&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git push
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After a couple of seconds, Flux will have applied these changes. Now let&amp;rsquo;s check the status of them:&lt;/p>
&lt;blockquote>
&lt;p>Or, you can trigger the reconciliation immediately by running the simple command: &lt;code>flux reconcile source git flux-system&lt;/code>&lt;/p>
&lt;/blockquote>
&lt;p>For the &lt;em>HelmRepository&lt;/em> resource:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux get sources helm
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME REVISION SUSPENDED READY MESSAGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-community False True Helm repository is ready
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For the &lt;em>HelmRelease&lt;/em> resource:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux get helmreleases
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME REVISION SUSPENDED READY MESSAGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus 15.18.0 False True Release reconciliation succeeded
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If everything is fine, you can check the pods in the &lt;code>monitoring&lt;/code> namespace:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ kubectl get pods -n monitoring
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY STATUS RESTARTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-alertmanager-54b7d7cf45-2b7zf 2/2 Running &lt;span style="color:#40a070">0&lt;/span> 115s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-kube-state-metrics-67f68d64bb-vlmvd 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 115s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-node-exporter-46gm6 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 115s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-pushgateway-596cd99697-t79zt 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 115s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>prometheus-server-c458cf6f9-nvstw 2/2 Running &lt;span style="color:#40a070">0&lt;/span> 115s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Great! Now, you have installed Prometheus with Flux by using the Helm chart stored in the OCI registry and verified it with &lt;em>cosign&lt;/em>.&lt;/p>
&lt;p>We can assume that the Helm chart&amp;rsquo;s signature is verified as we let it be deployed in a cluster but let&amp;rsquo;s do have double check and check the status of the &lt;em>HelmRelease&lt;/em> to see whether the verification is successful or not:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ kubectl get helmcharts -n flux-system flux-system-prometheus -ojsonpath&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#39;{.status.conditions[?(@.type==&amp;#34;SourceVerified&amp;#34;)]}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#666">{&lt;/span>&lt;span style="color:#4070a0">&amp;#34;lastTransitionTime&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;2022-11-09T13:27:38Z&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;message&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;verified signature of version 15.18.0&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;observedGeneration&amp;#34;&lt;/span>:1,&lt;span style="color:#4070a0">&amp;#34;reason&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;Succeeded&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;status&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;True&amp;#34;&lt;/span>,&lt;span style="color:#4070a0">&amp;#34;type&amp;#34;&lt;/span>:&lt;span style="color:#4070a0">&amp;#34;SourceVerified&amp;#34;&lt;/span>&lt;span style="color:#666">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That&amp;rsquo;s super cool! Because Flux is going to add a condition to the HelmChart resource&amp;rsquo;s status section to show the verification status. If the verification is successful, it will add a condition like the one above.&lt;/p>
&lt;h2 id="diy-do-it-yourself-approach">DIY (Do it yourself) Approach&lt;/h2>
&lt;p>The Prometheus community Helm charts only serve as an example. Here is how you can do the same thing with your own Helm charts.&lt;/p>
&lt;ol>
&lt;li>Create a Helm chart&lt;/li>
&lt;li>Package the Helm chart as .tar.gz file&lt;/li>
&lt;li>Login to the OCI-compliant registry that you want to use to store your Helm chart&lt;/li>
&lt;li>Push the Helm chart as OCI artifact&lt;/li>
&lt;/ol>
&lt;p>Let&amp;rsquo;s create a sample directory that will contain our Helm chart:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>mkdir -p helm-oci-demo
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">cd&lt;/span> helm-oci demo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now package the Helm chart as .tar.gz file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span> helm create nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s package the Helm chart as .tar.gz file:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>helm package nginx
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, let&amp;rsquo;s login to the OCI-compliant registry that you want to use to store your Helm chart. In this example, we&amp;rsquo;ll be using the GitHub Container Registry (ghcr.io):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">echo&lt;/span> &lt;span style="color:#bb60d5">$GHCR_PAT&lt;/span> | helm registry login ghcr.io -u &lt;span style="color:#bb60d5">$USER&lt;/span> --password-stdin
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> Don’t forget to change the values with your own details!
&lt;/div>
&lt;p>At this point, we are ready to push the Helm chart as OCI artifact:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ helm push nginx-0.1.0.tgz oci://ghcr.io/&lt;span style="color:#bb60d5">$USER&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Pushed: ghcr.io/developer-guy/nginx:0.1.0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Digest: sha256:21f92cbd63ab495d8fc44d54dabc4815c88d37697b3f8b757ca8e51ef178a2e7
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>So, the Helm chart is pushed to the OCI registry. It&amp;rsquo;s time to sign it with &lt;em>cosign&lt;/em>. As
&lt;a href="https://github.com/sigstore/cosign#sign-a-container-and-store-the-signature-in-the-registry" target="_blank">cosign recommends&lt;/a> we should always sign images based on their digests (@sha256:) rather than a tag. So, we should grab the digest from the command output above which is &lt;code>21f92cbd63ab495d8fc44d54dabc4815c88d37697b3f8b757ca8e51ef178a2e7&lt;/code> in this case, and use that digest while signing the image:&lt;/p>
&lt;p>As we saw the keyless approach before, let&amp;rsquo;s try the key-based approach this time. To do that, we should create public/private key pairs first:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cosign generate-key-pair
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command will generate two files, a &lt;code>cosign.pub&lt;/code> which is a publickey and &lt;code>cosign.key&lt;/code> which is a private key pair and store them in the current directory directory.&lt;/p>
&lt;p>Now, let&amp;rsquo;s sign the image with the private key:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cosign sign --key cosign.key ghcr.io/&lt;span style="color:#bb60d5">$USER&lt;/span>/nginx@21f92cbd63ab495d8fc44d54dabc4815c88d37697b3f8b757ca8e51ef178a2e7
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Cool! Now we have signed the image with the private key. Let&amp;rsquo;s check the signature:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cosign verify --key cosign.key ghcr.io/&lt;span style="color:#bb60d5">$USER&lt;/span>/nginx@21f92cbd63ab495d8fc44d54dabc4815c88d37697b3f8b757ca8e51ef178a2e7
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Yay! It&amp;rsquo;s verified. But in order to make the public key accessible by Flux, we need to create a Kubernetes secret to store the public key:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kubectl -n flux-system create secret generic cosign-pub &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --from-file&lt;span style="color:#666">=&lt;/span>cosign.pub&lt;span style="color:#666">=&lt;/span>cosign.pub
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, we can use it in our Flux configuration. The rest of the steps are the same as the previous section. For the sake of simplicity, we won&amp;rsquo;t repeat them here other than the &lt;em>HelmRepository&lt;/em> and &lt;em>HelmRelease&lt;/em> resources&amp;rsquo; creation steps.&lt;/p>
&lt;p>Let&amp;rsquo;s create the &lt;em>HelmRepository&lt;/em> resource first:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>flux create &lt;span style="color:#007020">source&lt;/span> helm &lt;span style="color:#bb60d5">$USER&lt;/span>-charts&lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --url&lt;span style="color:#666">=&lt;/span>oci://ghcr.io/&lt;span style="color:#bb60d5">$USER&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --interval&lt;span style="color:#666">=&lt;/span>10m &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --export &amp;gt; ./clusters/my-cluster/nginx-helmrepository.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s move on with creating the &lt;em>HelmRelease&lt;/em> resource:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>flux create helmrelease nginx &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --source&lt;span style="color:#666">=&lt;/span>HelmRepository/&lt;span style="color:#bb60d5">$USER&lt;/span>-charts &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --chart&lt;span style="color:#666">=&lt;/span>nginx &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --interval&lt;span style="color:#666">=&lt;/span>10m &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --release-name nginx &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --target-namespace&lt;span style="color:#666">=&lt;/span>default &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --export &amp;gt; ./clusters/my-cluster/nginx-helmrelease.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Don&amp;rsquo;t forget to run the following command to add the &lt;code>verify&lt;/code> section to the &lt;em>HelmRelease&lt;/em> resource&amp;rsquo; &lt;code>.spec.chart.spec&lt;/code> section to enable verification:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>yq e &lt;span style="color:#4070a0">&amp;#39;.spec.chart.spec|=({&amp;#34;verify&amp;#34;: { &amp;#34;provider&amp;#34;: &amp;#34;cosign&amp;#34;, &amp;#34;secretRef&amp;#34;: { &amp;#34;name&amp;#34;: &amp;#34;cosign-pub&amp;#34; } } } +.)&amp;#39;&lt;/span> ./clusters/my-cluster/nginx-helmrelease.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This command above will add the following part to the &lt;code>HelmRelease&lt;/code> resource&amp;rsquo;s &lt;code>.spec.chart.spec&lt;/code> section:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">verify&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">provider&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>cosign&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">secretRef&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>cosign-pub&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That&amp;rsquo;s all you need to do folks!&lt;/p>
&lt;p>Congratulations! You have successfully signed your Helm chart with &lt;em>cosign&lt;/em> with key-based approach and used it with Flux.&lt;/p></description></item><item><title>Blog: Prove the Authenticity of OCI Artifacts</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/</link><pubDate>Mon, 17 Oct 2022 12:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/flux-protects-you-against-ssca-featured_hu638e60bae9093dc1de73ef6cbce0e94b_71651_640x0_resize_box_3.png" width="640" height="860"/>
&lt;p>Software supply chain attacks are one of the most critical risks threatening today&amp;rsquo;s software and have begun to collapse like a dark cloud over the software industry. For the Flux family of projects we are taking precautions against these threats. Apart from implementing security features and best practices, it is important to us to educate our users. You can find all Flux&amp;rsquo;s security articles
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/tags/security/">here&lt;/a>. Today we will talk about a new security feature.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 531px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/flux-protects-you-against-ssca-featured_hu638e60bae9093dc1de73ef6cbce0e94b_71651_0x700_resize_box_3.png" width="521" height="700">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>Let&amp;rsquo;s start with a brief historical explanation of how we got to this point. It all started with the following sentence:&lt;/p>
&lt;div class="pageinfo pageinfo-primary">
&lt;p>Flux should be able to distribute and reconcile Kubernetes configuration packaged as OCI artifacts.&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>
&lt;a href="https://github.com/fluxcd/flux2/tree/main/rfcs/0003-kubernetes-oci" target="_blank">RFC-0003: Flux OCI support for Kubernetes manifests&lt;/a>&lt;/em>.&lt;/p>
&lt;/blockquote>
&lt;/div>
&lt;p>From then on, the Flux community worked hard and brought this feature with
&lt;a href="https://github.com/fluxcd/flux2/releases/tag/v0.32.0" target="_blank">Flux v0.32&lt;/a>. So with that, you can store and distribute various sources such as Kubernetes manifests, Kustomize overlays, and Terraform modules as OCI (Open Container Initiative) artifacts with
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/cmd/flux_push_artifact/#flux-push-artifact">Flux CLI&lt;/a> and tell Flux to reconcile your sources that are stored in OCI Artifacts, and Flux will do that for you. 🕺🏻&lt;/p>
&lt;p>But this only covered the first stage of the entire implementation. There is more than that. ☝️&lt;/p>
&lt;p>One of the most exciting features of this RFC is the
&lt;a href="https://github.com/fluxcd/flux2/tree/main/rfcs/0003-kubernetes-oci#verify-artifacts" target="_blank">verification of artifacts&lt;/a>. But why, what is it, is it really necessary or just a hype thing? This is a long topic that we need to discuss. Suppose you store the cluster desired state as OCI artifacts in a container registry. How can you be one hundred percent sure that the resources that Flux reconciles are the same as the resources that you&amp;rsquo;ve pushed to the OCI registry? This is where the verification of artifacts comes into play. But, how can we do that? 🤔&lt;/p>
&lt;p>Thanks to the
&lt;a href="https://www.sigstore.dev" target="_blank">Sigstore&lt;/a> community we have a great set of services and tools for signing and verifying authenticity. One of the tools is
&lt;a href="https://docs.sigstore.dev/cosign/overview" target="_blank">cosign&lt;/a> which can be used for container signing, verification, and storage in an OCI registry. We will use it to verify the authenticity of the OCI Artifacts in Flux. Starting with
&lt;a href="https://github.com/fluxcd/flux2/releases/tag/v0.35.0" target="_blank">v0.35&lt;/a>, Flux comes with support for verifying OCI artifacts signed with Sigstore Cosign. Documentation for setting it up can be found
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/cheatsheets/oci-artifacts/#signing-and-verification">here&lt;/a>.&lt;/p>
&lt;p>Let&amp;rsquo;s jump right into the details of how we can actually use it.&lt;/p>
&lt;p>We will deploy
&lt;a href="https://cert-manager.io/docs/" target="_blank">cert-manager&lt;/a> by storing its manifests in OCI registry packaged as an OCI Artifacts, using the &lt;em>Flux CLI&lt;/em>. Then we are going to sign it with &lt;em>cosign&lt;/em> and configure Flux to verify the artifacts’ signatures before they are downloaded and reconciled.&lt;/p>
&lt;p>You need three things to complete this demo;&lt;/p>
&lt;ul>
&lt;li>&lt;em>cosign&lt;/em> CLI
&lt;ul>
&lt;li>
&lt;a href="https://docs.sigstore.dev/cosign/installation/" target="_blank">https://docs.sigstore.dev/cosign/installation/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>A Kubernetes cluster
&lt;ul>
&lt;li>
&lt;a href="https://kind.sigs.k8s.io/#installation-and-usage" target="_blank">https://kind.sigs.k8s.io/#installation-and-usage&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;em>Flux&lt;/em> CLI
&lt;ul>
&lt;li>
&lt;a href="https://fluxcd.io/flux/cmd/" target="_blank">https://fluxcd.io/flux/cmd/&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;p>Let&amp;rsquo;s start by creating a simple Kubernetes cluster:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kind create cluster
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s install Flux on it - if you need to use other options, check out the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/installation/">installation page&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">GITHUB_USER&lt;/span>&lt;span style="color:#666">=&lt;/span>developer-guy
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">export&lt;/span> &lt;span style="color:#bb60d5">GITHUB_TOKEN&lt;/span>&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#bb60d5">$GITHUB_TOKEN&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>flux bootstrap github &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --owner&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#bb60d5">$GITHUB_USER&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --repository&lt;span style="color:#666">=&lt;/span>flux-cosign-demo &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --branch&lt;span style="color:#666">=&lt;/span>main &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --path&lt;span style="color:#666">=&lt;/span>./clusters/my-cluster &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --personal
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>⚠️ Note: Don’t forget to change the values with your own details!&lt;/p>
&lt;/blockquote>
&lt;p>First we download the cert-manager install manifests from GitHub:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>curl -sSLO https://github.com/cert-manager/cert-manager/releases/download/v1.9.1/cert-manager.yaml
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>
&lt;a href="https://github.com/cert-manager/cert-manager/releases/tag/v1.9.1" target="_blank">https://github.com/cert-manager/cert-manager/releases/tag/v1.9.1&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>Next we push the manifests to GitHub container registry with &lt;em>Flux CLI&lt;/em>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>mkdir -p ./manifests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> cp cert-manager.yaml ./manifests
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ flux push artifact oci://ghcr.io/&lt;span style="color:#bb60d5">$GITHUB_USER&lt;/span>/manifests/cert-manager:v1.9.1 &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --path&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;./manifests&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --source&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;https://github.com/cert-manager/cert-manager.git&amp;#34;&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --revision&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#4070a0">&amp;#34;v1.9.1/4486c01f726f17d2790a8a563ae6bc6e98465505&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>► pushing artifact to ghcr.io/developer-guy/manifests/cert-manager:v1.9.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>✔ artifact successfully pushed to ghcr.io/developer-guy/manifests/cert-manager@sha256:d1fb0442865148a4e9b4c3431c71d8e44af56c3eb658ea495c5ec48d48c6638b
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Before signing the OCI artifact with Cosign, we need to create a set of key pairs, a public and private one:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cosign generate-key-pair
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>This command above outputs two files to disk: &lt;code>cosign.pub&lt;/code> and &lt;code>cosign.key&lt;/code>. The cosign.pub file is the public key and the cosign.key file is the private key. You can use the cosign.pub file to verify the container image and the cosign.key file to sign the container image.&lt;/p>
&lt;/blockquote>
&lt;p>To let Flux to verify the signature of the OCI artifact, we should create a secret that contains the public key::&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>kubectl -n flux-system create secret generic cosign-pub &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --from-file&lt;span style="color:#666">=&lt;/span>cosign.pub&lt;span style="color:#666">=&lt;/span>cosign.pub
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, let&amp;rsquo;s sign it:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ cosign sign --key cosign.key ghcr.io/&lt;span style="color:#bb60d5">$GITHUB_USER&lt;/span>/manifests/cert-manager:v1.9.1
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Enter password &lt;span style="color:#007020;font-weight:bold">for&lt;/span> private key:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>Pushing signature to: ghcr.io/developer-guy/manifests/cert-manager
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>As we stick into the GitOps practices, we should create a file that contains the &lt;em>OCIRepository&lt;/em> resource, then commit and push those changes into the upstream repository that Flux watches for changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>git clone git@github.com:developer-guy/flux-cosign-demo.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#007020">cd&lt;/span> flux-cosign-demo
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s create a secret with the GitHub token:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux create secret oci ghcr-auth &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --url&lt;span style="color:#666">=&lt;/span>ghcr.io &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --username&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#70a0d0">${&lt;/span>&lt;span style="color:#bb60d5">GITHUB_USER&lt;/span>&lt;span style="color:#70a0d0">}&lt;/span> &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --password&lt;span style="color:#666">=&lt;/span>&lt;span style="color:#70a0d0">${&lt;/span>&lt;span style="color:#bb60d5">GITHUB_TOKEN&lt;/span>&lt;span style="color:#70a0d0">}&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>► oci secret &lt;span style="color:#4070a0">&amp;#39;ghcr-auth&amp;#39;&lt;/span> created in &lt;span style="color:#4070a0">&amp;#39;flux-system&amp;#39;&lt;/span> namespace
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Configure Flux to pull the cert-manager artifact, verify its signature and apply its contents:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cat &lt;span style="color:#4070a0">&amp;lt;&amp;lt; EOF | tee ./clusters/my-cluster/cert-manager-sync.yaml
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">apiVersion: source.toolkit.fluxcd.io/v1beta2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">kind: OCIRepository
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">metadata:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> name: cert-manager
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> namespace: flux-system
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">spec:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> interval: 5m
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> url: oci://ghcr.io/${GITHUB_USER}/manifests/cert-manager
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> ref:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> semver: &amp;#34;*&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> secretRef:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> name: ghcr-auth
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> verify:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> provider: cosign
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> secretRef:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> name: cosign-pub
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">---
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">apiVersion: kustomize.toolkit.fluxcd.io/v1beta2
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">kind: Kustomization
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">metadata:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> name: cert-manager
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> namespace: flux-system
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">spec:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> interval: 1h
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> timeout: 5m
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> sourceRef:
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> kind: OCIRepository
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> name: cert-manager
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> path: &amp;#34;.&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> prune: true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0"> wait: true
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0">EOF&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Let&amp;rsquo;s commit and push these changes:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>git add .
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git commit -m&lt;span style="color:#4070a0">&amp;#34;Add cert-manager OCIRepository and Kustomization&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>git push
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>After couple of seconds for Flux will have applied these changes. Now let&amp;rsquo;s check the status of them:&lt;/p>
&lt;blockquote>
&lt;p>Or, you can trigger the reconcilation immediately by running the simple command: &lt;em>flux reconcile source git flux-system&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;p>For &lt;em>Kustomization&lt;/em> resources:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux get kustomizations
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME REVISION SUSPENDED READY MESSAGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cert-manager v1.9.1/d1fb0442865148a4e9b4c3431c71d8e44af56c3eb658ea495c5ec48d48c6638b False True Applied revision: v1.9.1/d1fb0442865148a4e9b4c3431c71d8e44af56c3eb658ea495c5ec48d48c6638b
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>flux-system main/14f1e66 False True Applied revision: main/14f1e66
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>For &lt;em>OCIRepository&lt;/em> resources:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ flux get sources oci
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME REVISION SUSPENDED READY MESSAGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cert-manager v1.9.1/d1fb0442865148a4e9b4c3431c71d8e44af56c3eb658ea495c5ec48d48c6638b False True stored artifact &lt;span style="color:#007020;font-weight:bold">for&lt;/span> digest &lt;span style="color:#4070a0">&amp;#39;v1.9.1/d1fb0442865148a4e9b4c3431c71d8e44af56c3eb658ea495c5ec48d48c6638b&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>If you see the status of the &lt;em>OCIRepository&lt;/em> is &lt;code>True&lt;/code>, it means that Flux has successfully verified the signature of the container image. Because Flux adds a condition with the following attributes to the OCIRepository’s &lt;code>.status.conditions&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>type: SourceVerified&lt;/li>
&lt;li>status: &amp;ldquo;True&amp;rdquo;&lt;/li>
&lt;li>reason: Succeeded&lt;/li>
&lt;/ul>
&lt;p>If the verification fails, Flux will set the &lt;code>SourceVerified&lt;/code> status to &lt;code>False&lt;/code> and will not fetch the artifact contents from the registry. If you see the status of the &lt;em>Kustomization&lt;/em> is &lt;code>True&lt;/code>, it means that Flux has successfully applied the manifests that are stored in the container image.&lt;/p>
&lt;p>Let&amp;rsquo;s check the status of the &lt;em>cert-manager&lt;/em> deployment:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>$ kubectl get pods --namespace cert-manager
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME READY STATUS RESTARTS AGE
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cert-manager-cainjector-857ff8f7cb-l469h 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 76s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cert-manager-d58554549-9fbgj 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 76s
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>cert-manager-webhook-76fdf7c485-9v82g 1/1 Running &lt;span style="color:#40a070">0&lt;/span> 76s
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="furthermore">Furthermore&lt;/h2>
&lt;p>As we can store &lt;em>Helm Charts&lt;/em> in OCI registries with the release of Helm
&lt;a href="https://helm.sh/blog/storing-charts-in-oci/" target="_blank">v3.8.0&lt;/a> which means that we can also sign them with &lt;em>cosign&lt;/em> and verify them with Flux. The Flux community is already working on it and want to add support for verifying the Helm charts stored in OCI registries as OCI Artifacts in the next releases of Flux. You can follow the progress of this feature in the following issue:
&lt;a href="https://github.com/fluxcd/source-controller/issues/914" target="_blank">fluxcd/source-controller#914&lt;/a>.&lt;/p>
&lt;p>The Sigstore community is aware of the risks and the toil of managing public/private key pairs, so cosign offers another mode for signing and verification called
&lt;a href="https://github.com/sigstore/cosign/blob/main/KEYLESS.md" target="_blank">Keyless&lt;/a>, which do not require managing any keys manually. Flux also supports that. If you omit the &lt;code>.verify.secretRef&lt;/code> field, Flux will try to verify the signature using the Keyless mode. It&amp;rsquo;s worth mentioning keyless verification is an experimental feature, using custom root CAs or self-hosted Rekor instances are currently not supported.&lt;/p></description></item><item><title>Blog: May 2022 Security Announcement</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/05/may-2022-security-announcement/</link><pubDate>Tue, 10 May 2022 08:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/05/may-2022-security-announcement/</guid><description>
&lt;h2 id="tldr">tl;dr&lt;/h2>
&lt;p>The Flux Team has found three security vulnerabilities in
Flux, and we strongly advise you to upgrade your clusters as soon as you
can.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>CVE&lt;/th>
&lt;th>Advisory&lt;/th>
&lt;th>Severity&lt;/th>
&lt;th>Affected versions&lt;/th>
&lt;th>&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>CVE-2022-24817&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-vvmq-fwmg-2gjc" target="_blank">Improper kubeconfig validation allows arbitrary code execution&lt;/a>&lt;/td>
&lt;td>Critical&lt;/td>
&lt;td>&lt;code>&amp;lt; 0.29.0 &amp;gt;= v0.1.0&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>CVE-2022-24877&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-j77r-2fxf-5jrw" target="_blank">Improper path handling in Kustomization files allows path traversal&lt;/a>&lt;/td>
&lt;td>Critical&lt;/td>
&lt;td>&lt;code>&amp;lt; v0.29.0&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>CVE-2022-24878&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-7pwf-jg34-hxwp" target="_blank">Improper path handling in Kustomization files allows for denial of service&lt;/a>&lt;/td>
&lt;td>High&lt;/td>
&lt;td>&lt;code>&amp;lt; v0.29.0 &amp;gt;= v0.19.0&lt;/code>&lt;/td>
&lt;td>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>Breaking changes to be aware of in the upgrade process:
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/05/april-2022-update/#latest-flux-release-series-is-029">0.29&lt;/a>,
&lt;a href="https://github.com/fluxcd/flux2/discussions/2567" target="_blank">0.28&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/03/february-update/#latest-flux-is-027">0.27&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/01/january-update/#flux-v026-more-secure-by-default">0.26&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/december-update/#a-flurry-of-flux-releases">0.24 - 0.21&lt;/a>.&lt;/p>
&lt;p>If you cannot immediately update or are hard pressed for time and need a
work-around for now, please see the CVE advisories linked above for more
information.&lt;/p>
&lt;h2 id="some-background">Some Background&lt;/h2>
&lt;p>Last week the Flux Security Team disclosed three new vulnerabilities
which affect v0.28 and older versions, and have a greater impact in
multi-tenancy deployments.&lt;/p>
&lt;p>The reason why the impact is greater in multi-tenancy deployments is due
to the way that Flux/GitOps works. Flux tends to operate like a cluster
admin, having permissions to apply any changes to a cluster, regardless
of their scope - at namespace or cluster levels. Users having access to
a source repository, or simply having access to create/alter Flux
objects within a cluster can instruct Flux to apply such changes, which
in single tenancy effectively means that such users have cluster admin
permissions to the target clusters. The caveat being that using Flux you
can add additional security controls between the user and the target
cluster, for example, before each change is merged into a repository
Pull Requests must be created requiring peer reviews. The Open GitOps
community started defining and codifying this further - have a look
&lt;a href="https://opengitops.dev/blog/sec-gitops/" target="_blank">at
this blog post&lt;/a> if
you want to know more.&lt;/p>
&lt;p>In multi-tenant environments, users with similar permissions can only
affect part of a cluster, or an isolated cluster in a group of clusters.
Therefore, if a user can gain escalated privileges (or deny service) at a Flux
level, it will have an impact way larger than on single-tenant clusters, as
the users can impact more than just themselves.&lt;/p>
&lt;p>At time of writing, we are unaware of any public exploits in the wild,
and therefore have no reason to believe such vulnerabilities have been
actively exploited.&lt;/p>
&lt;h2 id="the-advisories-in-detail">The advisories in detail&lt;/h2>
&lt;h3 id="cve-2022-24817httpsgithubcomfluxcdflux2securityadvisoriesghsa-vvmq-fwmg-2gjc---kubeconfig-validation">
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-vvmq-fwmg-2gjc" target="_blank">CVE-2022-24817&lt;/a> - Kubeconfig Validation&lt;/h3>
&lt;p>At the beginning of the Flux2&amp;rsquo;s journey we implemented a feature to apply
state to remote clusters. It enables users to have a management cluster
in which Flux is installed, which then applies changes to other
clusters, making it ideal for some multi-tenancy scenarios in which high
isolation across tenants is needed.&lt;/p>
&lt;p>The connection between the management cluster and the target clusters is
done by referencing a Kubernetes secret containing a kubeconfig, which is set at the &lt;code>spec.KubeConfig&lt;/code> field in
either &lt;code>Kustomization&lt;/code> or &lt;code>HelmRelease&lt;/code> objects.&lt;/p>
&lt;p>One interesting thing about kubeconfigs is that they are quite
extensible. You can for example define an executable which will then be
automatically called by &lt;code>kubectl&lt;/code> every time it requires a new on-demand
access token. An example of this in action is
&lt;a href="https://github.com/kubernetes-sigs/aws-iam-authenticator" target="_blank">aws-iam-authenticator&lt;/a>,
which enables AWS users to authenticate against AWS and then use the
returning JWT tokens to access their EKS clusters. Once the token expires,
the process happens again. All that is managed by &lt;code>kubectl&lt;/code> behind the scenes
without user intervention.&lt;/p>
&lt;p>The problem here is that first, the use of executables in kubeconfigs
was enabled by default. Meaning that a malicious tenant would be able to
craft a malicious kubeconfig which could lead to privilege escalation
within the cluster.&lt;/p>
&lt;p>As a solution, we decided to disable this feature by default. It can
still be enabled at a cluster level via a new flag
&lt;code>--insecure-kubeconfig-exec&lt;/code> being sent to the controller binary.&lt;/p>
&lt;p>For cluster admins considering this feature, we also recommend the use
of AppArmor and SELinux profiles to enforce at Kernel level what
binaries could be executed.&lt;/p>
&lt;h3 id="cve-2022-24877httpsgithubcomfluxcdflux2securityadvisoriesghsa-j77r-2fxf-5jrw---kustomization-path-traversal">
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-j77r-2fxf-5jrw" target="_blank">CVE-2022-24877&lt;/a> - Kustomization Path Traversal&lt;/h3>
&lt;p>Flux allows users to lean on Kustomize features to make their lives
easier as they go on about declaring the state of their clusters. Some
of those features could result in sensitive data from the pod filesystem
to be exposed into the target cluster, which could lead to a malicious
tenant being privy to anything sensitive that may exist in the
controller&amp;rsquo;s filesystem or attached volumes (e.g. token).&lt;/p>
&lt;p>The mitigation for the path traversal was to create stronger bounds,
enforcing that all &lt;code>kustomize&lt;/code> operations happen within such bounds or
result in error.&lt;/p>
&lt;h3 id="cve-2022-24878httpsgithubcomfluxcdflux2securityadvisoriesghsa-7pwf-jg34-hxwp---kustomization-denial-of-service">
&lt;a href="https://github.com/fluxcd/flux2/security/advisories/GHSA-7pwf-jg34-hxwp" target="_blank">CVE-2022-24878&lt;/a> - Kustomization Denial of Service&lt;/h3>
&lt;p>Whilst working on the mitigation of the previous CVE, we have noticed
that in some scenarios a specially crafted &lt;code>kustomization.yaml&lt;/code> could lead
to the &lt;code>kustomize-controller&lt;/code> to enter into an endless loop, and finally
crash.&lt;/p>
&lt;p>For single-tenant clusters, this would mean that an user may make a mistake and
the controller stops working, potentially resulting in future
reconciliations not being applied. For multi-tenant clusters, depending on the
deployment model, a tenant could cause a disruption to affect not only
itself but also the other tenants and potentially even the management
cluster.&lt;/p>
&lt;p>The solution mitigating this vulnerability was to further improve our
validation and ensure that such scenarios are not processed in the first
place.&lt;/p>
&lt;h2 id="inspecting-your-flux-system-version">Inspecting your Flux system version&lt;/h2>
&lt;p>To check if your system is currently vulnerable, run &lt;code>flux version --context=my-cluster&lt;/code>
with the &lt;code>--context&lt;/code> set to the cluster you want to inspect. This will
report the current Flux binary and controller versions.&lt;/p>
&lt;h3 id="vulnerable-flux-system">Vulnerable Flux system&lt;/h3>
&lt;p>To find out if your system could be vulnerable, simply find out the
version of Flux. Here it&amp;rsquo;s important to check you are running all of
these:&lt;/p>
&lt;ul>
&lt;li>flux &lt;code>&amp;lt; v0.29.0&lt;/code>&lt;/li>
&lt;li>helm-controller &lt;code>&amp;lt; v0.19.0&lt;/code>&lt;/li>
&lt;li>kustomize-controller &lt;code>&amp;lt; v0.24.0&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>You can do this like so:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-cli" data-lang="cli">$ flux version
flux: v0.22.1
helm-controller: v0.12.2
kustomize-controller: v0.17.0
notification-controller: v0.18.1
source-controller: v0.17.2
&lt;/code>&lt;/pre>&lt;h3 id="updating-your-vulnerable-system">Updating your vulnerable system&lt;/h3>
&lt;p>&amp;#x1f4a5; If you find the controllers versioned within the range
mentioned above, follow the upgrade procedure for your system. For
&lt;code>flux bootstrap&lt;/code>, this can be done by running the command again with
the same arguments as used during install.&lt;/p>
&lt;p>&amp;#x26a0;&amp;#xfe0f; Please note that if you are upgrading from below one of the
versions in the following list, there are breaking changes and, pre-
and/or post-upgrade notes you need to take into account:
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/05/april-2022-update/#latest-flux-release-series-is-029">0.29&lt;/a>,
&lt;a href="https://github.com/fluxcd/flux2/discussions/2567" target="_blank">0.28&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/03/february-update/#latest-flux-is-027">0.27&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/01/january-update/#flux-v026-more-secure-by-default">0.26&lt;/a>,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/december-update/#a-flurry-of-flux-releases">0.24 - 0.21&lt;/a>.&lt;/p>
&lt;h3 id="up-to-date-flux-system">Up-to-date Flux system&lt;/h3>
&lt;p>An up to date Flux system should at least have versions listed below:&lt;/p>
&lt;ul>
&lt;li>flux &lt;code>&amp;gt;= v0.29.0&lt;/code>&lt;/li>
&lt;li>helm-controller &lt;code>&amp;gt;= v0.19.0&lt;/code>&lt;/li>
&lt;li>kustomize-controller &lt;code>&amp;gt;= v0.24.0&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>So in practice the output could look like this:&lt;/p>
&lt;pre tabindex="0">&lt;code class="language-cli" data-lang="cli">$ flux version
flux version
flux: v0.30.2
helm-controller: v0.21.0
kustomize-controller: v0.25.0
notification-controller: v0.23.5
source-controller: v0.24.4
&lt;/code>&lt;/pre>&lt;p>We encourage all users to keep Flux up-to-date. We offer a
&lt;a href="https://github.com/fluxcd/flux2/tree/main/action#automate-flux-updates" target="_blank">GitHub Action&lt;/a> with which you can automate the Flux upgrades in a GitOps manner, without having to connect from CI to the cluster&amp;rsquo;s API, as Flux is capable of upgrading itself from Git.&lt;/p>
&lt;h2 id="flux-security-more-generally-speaking">Flux Security more generally speaking&lt;/h2>
&lt;p>It is no secret that the Flux community has been investing in security
for a long time. Early on the Flux journey we re-architectured the
codebase to avoid shelling out to binaries to decrease the likelihood of
code execution vulnerabilities. The story about our Git integration
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/03/flux-puts-the-git-into-gitops/">we
wrote down here&lt;/a>.&lt;/p>
&lt;p>As Security is such a central pillar of Flux, we are
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/tags/security/">keen to write
about it&lt;/a> and tell you how you can benefit from all
the individual features and improvements we worked on, e.g. SBOMs,
CI Checks, Branch Protection, restricted pod security standard and
more. Since the beginning we worked hard to ensure that we ship code
that does what it needs to do, even when that means having to rewrite
parts of upstream dependencies.&lt;/p>
&lt;p>When we had our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/">first security audit last
year&lt;/a>, the results were quite
reassuring as most of the findings were quite small, with the exception
of a
&lt;a href="https://github.com/fluxcd/kustomize-controller/security/advisories/GHSA-35rf-v2jv-gfg7" target="_blank">RCE in
kustomize-controller&lt;/a>,
which speaks to the security improvements we have been investing on, and
how they are resulting in better development practices.&lt;/p>
&lt;p>Another recommendation from the auditors was to implement and follow a
stricter and more elaborate RFC process, which is
&lt;a href="https://github.com/fluxcd/flux2/tree/main/rfcs" target="_blank">what we
did&lt;/a>. They
also recommended we get in touch with other security teams or auditors
for getting feedback on a refined and more general multi-tenancy
proposal - which we also did as mentioned below.&lt;/p>
&lt;h2 id="whats-next-for-flux">What&amp;rsquo;s next for Flux&lt;/h2>
&lt;p>The way we shaped the Flux Roadmap for GA was&lt;/p>
&lt;ol>
&lt;li>Feature party with Flux Legacy&lt;/li>
&lt;li>Stable APIs (this was after the controller refactoring which
consolidated functionality in
&lt;a href="https://github.com/fluxcd/pkg" target="_blank">fluxcd/pkg&lt;/a>)&lt;/li>
&lt;li>Straightforward multi-tenancy implementation&lt;/li>
&lt;li>GA release&lt;/li>
&lt;/ol>
&lt;p>
&lt;a href="https://github.com/fluxcd/flux2/issues/2655" target="_blank">Here is the status
quo&lt;/a> regarding
multi-tenancy:&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>Flux2 supports multi-tenancy, and users have been using it in
production for&lt;/em> &lt;em>
&lt;a href="https://www.youtube.com/watch?v=F7B_TBcIyl8" target="_blank">some time
now&lt;/a>.&lt;/em>&lt;/p>
&lt;p>&lt;em>The documentation around the subject covers a&lt;/em> &lt;em>
&lt;a href="https://github.com/fluxcd/flux2-multi-tenancy" target="_blank">bootstrap
example&lt;/a>
to help users kick start their multi-tenancy deployments. And also how
to implement control plane isolation with the&lt;/em>
&lt;em>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/installation/configuration/multitenancy/">multi-tenancy-lockdown&lt;/a>.&lt;/em>&lt;/p>
&lt;p>&lt;em>&lt;strong>What's next&lt;/strong>&lt;/em>&lt;/p>
&lt;p>&lt;em>In summary, the documentation needs expanding to better inform users
around the security risks of multi-tenancy and the recommended
deployment models for their specific isolation/security requirements.&lt;/em>&lt;/p>
&lt;p>&lt;em>There are proposed changes that would further improve Flux in
multi-tenancy environments, by for example enabling tenants to share
resources amongst themselves. Such changes must be progressed once the
security impact of such changes have been assessed.&lt;/em>&lt;/p>
&lt;/blockquote>
&lt;p>To help us get this right, we are engaging with the
&lt;a href="https://github.com/cncf/tag-security" target="_blank">CNCF TAG
Security&lt;/a>. This is
the upstream group where key contributors and experts of the CNCF
Landscape assemble and define security best practices across all the
individual Cloud Native projects. We are
&lt;a href="https://github.com/cncf/tag-security/issues/896" target="_blank">asking them for an
independent security
review&lt;/a>
and recommendations, particularly around multi-tenancy.&lt;/p>
&lt;p>If you want to join the conversation, we are all ears. Please refer to
the open RFC documents and have your say there. We definitely want to
get this right for everyone.&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://github.com/fluxcd/flux2/pull/2086" target="_blank">RFC: Define Flux tenancy models #2086&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://github.com/fluxcd/flux2/pull/2092" target="_blank">RFC: Access control for cross-namespace source refs #2092&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://github.com/fluxcd/flux2/pull/2093" target="_blank">RFC: Flux Multi-Tenancy Mode #2093&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>In addition to that we are working hard to round up features, improve
their performance, security and overall stability.&lt;/p>
&lt;p>If you want to follow all the other GA related work, we explained
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/04/march-update/#flux-maintainers-focus-project-board">how
to do that
here&lt;/a>
and if you would like to participate in any of the discussions,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/04/contributing-to-flux/">come
and find us&lt;/a>
on Slack or in our regular meetings. We are always looking forward to
growing Team Flux and the closer we get to GA, it&amp;rsquo;s getting even more
important to have all voices heard.&lt;/p></description></item><item><title>Blog: Security: Using Pod Security Standard "restricted"</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/03/security-pod-security-standard-restricted/</link><pubDate>Wed, 09 Mar 2022 12:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/03/security-pod-security-standard-restricted/</guid><description>
&lt;p>Next up in our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/tags/security/">blog series about Flux
Security&lt;/a> is how we moved
to Pod Security Standard &amp;ldquo;restricted&amp;rdquo;, all the background info you need
to know and how that makes things safer for you.&lt;/p>
&lt;p>
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/01/january-update/#security-news">Since version 0.26 of
Flux&lt;/a>
we are applying&lt;/p>
&lt;blockquote>
&lt;p>[..] the
&lt;a href="https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted" target="_blank">restricted pod security
standard&lt;/a>
to all controllers. In practice this means:&lt;/p>
&lt;ul>
&lt;li>all Linux capabilities were dropped&lt;/li>
&lt;li>the root filesystem was set to read-only&lt;/li>
&lt;li>the &lt;code>seccomp&lt;/code> profile was set to the runtime default&lt;/li>
&lt;li>run as non-root was enabled&lt;/li>
&lt;li>the filesystem group was set to 1337&lt;/li>
&lt;li>the user and group ID was set to 65534&lt;/li>
&lt;/ul>
&lt;p>Flux also enables the Seccomp runtime default across all controllers.
Why is this important? Well, the default &lt;code>seccomp&lt;/code> profile blocks key
system calls that can be used maliciously, for example to break out of
the container isolation. The recently disclosed
&lt;a href="https://blog.aquasec.com/cve-2022-0185-linux-kernel-container-escape-in-kubernetes" target="_blank">kernel vulnerability
CVE-2022-0185&lt;/a>
is a good example of that.&lt;/p>
&lt;/blockquote>
&lt;h2 id="pod-security-standards-definition">Pod Security Standards definition&lt;/h2>
&lt;p>Kubernetes defined three policies in its Pod Security Standards. They
range from&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Privileged&lt;/strong>: This does not place any restrictions on the workload
at all. The idea being that this can be used for system- and
infrastructure-level workloads which are managed by privileged and
trusted users only.&lt;/li>
&lt;li>&lt;strong>Baseline&lt;/strong>: This policy comes with some restrictions. It aims to
guard against known privilege escalations while still making it
easy to adopt and use it by keeping a certain level of
compatibility with most workloads.&lt;/li>
&lt;li>&lt;strong>Restricted&lt;/strong>: Inheriting all the restrictions from &lt;em>Baseline&lt;/em>, it
enforces additional limitations, thus follows hardening best
practices by increasing the isolation levels the workload is
exposed to.&lt;/li>
&lt;/ul>
&lt;p>We are very pleased that all Flux controllers were moved to
&lt;em>Restricted&lt;/em>, as that offers the highest level of security for you.&lt;/p>
&lt;p>We recommend checking out the
&lt;a href="https://kubernetes.io/docs/concepts/security/pod-security-standards/" target="_blank">Upstream Kubernetes documentation on Pod
Security
Standards&lt;/a>
as it gives a generally good overview of all the security features
enabled. In addition to that you can see which restrictions were added
as part of which Kubernetes release, meaning that with every Kubernetes
release, you will benefit from new Upstream Kubernetes security
improvements automatically.&lt;/p>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> &lt;p>As of v1.24 Kubernetes still runs all workloads with &lt;code>seccomp&lt;/code> in
&lt;code>unconfined&lt;/code> mode, in other words, disabled. On the other hand, Docker
has &lt;code>seccomp&lt;/code> enabled by default for years now.&lt;/p>
&lt;p>There are discussions to change the Kubernetes default on v1.25, and have all
workloads set to &lt;code>RuntimeDefault&lt;/code> unless opted-out. This would be based on
&lt;code>SeccompDefault&lt;/code>
&lt;a href="https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/" target="_blank">feature
gate&lt;/a>
being enabled from that version onwards.&lt;/p>
&lt;/div>
&lt;div class="alert alert-info" role="alert">
&lt;strong>Note:&lt;/strong> If you are an OpenShift user, you might run into
&lt;a href="https://github.com/fluxcd/source-controller/issues/582" target="_blank">this
issue&lt;/a>
(
&lt;a href="https://github.com/openshift/cluster-kube-apiserver-operator/issues/1325" target="_blank">related upstream
report&lt;/a>).
The work-around right now is to remove the seccomp profile as
described in
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/use-cases/openshift/">these instructions&lt;/a>.
&lt;/div>
&lt;h2 id="seccomp-and-runtimedefault">&lt;code>seccomp&lt;/code> and &lt;code>RuntimeDefault&lt;/code>&lt;/h2>
&lt;p>Seccomp is short for &amp;ldquo;Secure Computing&amp;rdquo;. It refers to a facility in the
Linux kernel which can limit the number of system calls available to a
given process. Right now there are around 300+ system calls available,
e.g. &lt;code>read&lt;/code> to read from a file descriptor or &lt;code>chmod&lt;/code> to change the
permissions of a file. The more syscalls you block, the more secure your
application, as a rogue process will only be able to do what you
specified.&lt;/p>
&lt;p>In its first inception &lt;code>seccomp&lt;/code> was introduced into Linux in 2005, to
Docker in version 1.10 (Feb 2016) and to Kubernetes in version 1.3 (Jul
2016). So while the technology has been around for a while and you could
handcraft your own &lt;code>seccomp&lt;/code> profiles, the challenge has always been
striking the right balance: if you are too generous in your filter, it
won&amp;rsquo;t guard against malware effectively &amp;ndash; if you are too strict, your
application might not work.&lt;/p>
&lt;p>All container runtimes come with a default seccomp profile.
&lt;a href="https://github.com/moby/moby/blob/master/profiles/seccomp/default.json" target="_blank">Docker
Desktop for
example&lt;/a>
blocks around 44 system calls. In Kubernetes you can enable the seccomp
profile RuntimeDefault for your pod like so:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">securityContext&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">seccompProfile&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">type&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>RuntimeDefault&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>All Flux controllers have this implemented as well now!&lt;/p>
&lt;p>By adopting both changes, we further restrict the permissions that Flux
requires in order to operate. This, alongside other changes we are working
on, translate in a decreased attack surface which may reduce the impact of
eventual CVEs that may surface in our code base - or our supply chain.&lt;/p>
&lt;h2 id="further-reading">Further reading&lt;/h2>
&lt;p>If you would like to understand the concepts in this blog post better,
you might want to check out these blog posts (in addition to the docs
referred to above):&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://itnext.io/seccomp-in-kubernetes-part-i-7-things-you-should-know-before-you-even-start-97502ad6b6d6" target="_blank">Seccomp in Kubernetes &amp;mdash; Part I: 7 things you should know before
you even start! | by Paulo Gomes&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://medium.com/@LachlanEvenson/how-to-enable-kubernetes-container-runtimedefault-seccomp-profile-for-all-workloads-6795624fcbcc" target="_blank">How to enable Kubernetes container RuntimeDefault seccomp profile
for all workloads | by Lachlan Evenson&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://kubernetes.io/blog/2021/08/25/seccomp-default/" target="_blank">Enable seccomp for all workloads with a new v1.22 alpha feature |
Kubernetes&lt;/a>&lt;/li>
&lt;li>
&lt;a href="https://kubernetes.io/docs/tutorials/security/seccomp" target="_blank">Restrict a Container's Syscalls with seccomp | Kubernetes
Documentation&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="talk-to-us">Talk to us&lt;/h2>
&lt;p>We love feedback, questions and ideas, so please let us know your
personal use-cases today. Ask us if you have any questions and please&lt;/p>
&lt;ul>
&lt;li>join our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/community/#meetings">upcoming dev meetings&lt;/a>&lt;/li>
&lt;li>find us in the #flux channel on
&lt;a href="https://slack.cncf.io/" target="_blank">CNCF Slack&lt;/a>&lt;/li>
&lt;li>add yourself
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/adopters/">as an adopter&lt;/a> if you haven&amp;rsquo;t already&lt;/li>
&lt;/ul>
&lt;p>See you around!&lt;/p></description></item><item><title>Blog: Security: More confidence through Fuzzing</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-more-confidence-through-fuzzing/</link><pubDate>Tue, 22 Feb 2022 08:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-more-confidence-through-fuzzing/</guid><description>
&lt;p>Next up in our blog series about Flux Security is how we implemented
fuzzing in Flux and its controllers and how that makes things safer for
you.&lt;/p>
&lt;p>
&lt;a href="https://en.wikipedia.org/wiki/Fuzzing" target="_blank">Wikipedia explains Fuzzing&lt;/a>
like so:&lt;/p>
&lt;blockquote>
&lt;p>&lt;strong>Fuzzing&lt;/strong> or &lt;strong>fuzz testing&lt;/strong> is an automated software testing
technique that involves providing invalid, unexpected, or random data
as inputs to a computer program. The program is then monitored for
exceptions such as crashes, failing built-in code assertions, or
potential memory leaks. Typically, fuzzers are used to test programs
that take structured inputs. This structure is specified, e.g., in a
file format or protocol and distinguishes valid from invalid input. An
effective fuzzer generates semi-valid inputs that are &amp;quot;valid enough&amp;quot;
in that they are not directly rejected by the parser, but do create
unexpected behaviors deeper in the program and are &amp;quot;invalid enough&amp;quot;
to expose corner cases that have not been properly dealt with.&lt;/p>
&lt;/blockquote>
&lt;p>We already have quite a good coverage of unit and end-to-end tests
across the controllers. Adding fuzzing to the mix will further extend
the scope of tests to scenarios and payloads not previously covered.
Together with the fuzzing that&amp;rsquo;s already being done within the
Kubernetes repositories, e.g. &lt;code>kubernetes&lt;/code>, &lt;code>client-go&lt;/code> and
&lt;code>apimachinery&lt;/code> we feel ever more confident in our code.&lt;/p>
&lt;p>We are happy to share that since the 0.27 release of Flux all Flux
controllers and libraries are now tested by
&lt;a href="https://github.com/google/oss-fuzz" target="_blank">Google&amp;rsquo;s continuous
fuzzing for open source software&lt;/a>.&lt;/p>
&lt;h2 id="how-we-got-here">How we got here&lt;/h2>
&lt;p>When we
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/#flux-coming-to-oss-fuzz">announced the results of the security
audit&lt;/a>
back in November, we already shared that the team at
&lt;a href="https://adalogics.com/" target="_blank">ADA
Logics&lt;/a> had helped put together an initial
implementation of Fuzzing for some of the Flux controllers. In this
first inception three issues were already found (1x slice
out-of-bounds, 2x nil-dereference), and immediately fixed.
Naturally we were very interested in merging the fuzzing integration.&lt;/p>
&lt;p>In order for us to fully land the fuzzers, we needed to make some
architectural changes to the build process, especially for the
controllers that rely on C bindings to &lt;code>libgit2&lt;/code>, such as
&lt;code>source-controller&lt;/code> and &lt;code>image-automation-controller&lt;/code>, which are now
statically built. In addition to that, we extended the scope of the
fuzzers considerably. If you take a look at the related
&lt;a href="https://github.com/fluxcd/notification-controller/pull/306" target="_blank">pull request
for
notification-controller&lt;/a>
you get a good idea of what this all entailed, e.g. fuzzing for all
notifiers.&lt;/p>
&lt;p>Fuzzers are now run for every commit which lands in the Flux controllers
and libraries.&lt;/p>
&lt;p>Thanks again ADA Logics for contributing and to everyone else who helped
integrate this! We are also very grateful to Google and
&lt;a href="https://openssf.org/" target="_blank">OpenSSF&lt;/a> who provide and maintain the required
infrastructure.&lt;/p>
&lt;h2 id="whats-next">What&amp;rsquo;s next&lt;/h2>
&lt;p>As Go will see built-in Fuzz support in 1.18, we were very interested
in structuring everything closely to the new format, so that the
transition from
&lt;a href="https://github.com/dvyukov/go-fuzz" target="_blank">dvyukov/go-fuzz&lt;/a>
(which is currently being used) goes smoothly. (We can recommend
&lt;a href="https://jayconrod.com/posts/123/internals-of-go-s-new-fuzzing-system" target="_blank">Jay
Conrod&amp;rsquo;s blog
post&lt;/a>
about the Internals of Go&amp;rsquo;s new fuzzing system, if you are curious!)&lt;/p>
&lt;p>The move of Flux to go native fuzzing is being tracked in
&lt;a href="https://github.com/fluxcd/flux2/issues/2417" target="_blank">this
issue&lt;/a>. We
also hope to add new fuzzers soon, so if you want to contribute there:
come and find us on Slack! It&amp;rsquo;s an easy way to get to know and extend
the Flux codebase.&lt;/p>
&lt;p>This is just one more measure we are taking to keep you more secure.&lt;/p>
&lt;h2 id="talk-to-us">Talk to us&lt;/h2>
&lt;p>We love feedback, questions and ideas, so please let us know your
personal use-cases today. Ask us if you have any questions and please&lt;/p>
&lt;ul>
&lt;li>join our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/community/#meetings">upcoming dev meetings&lt;/a>&lt;/li>
&lt;li>find us in the #flux channel on
&lt;a href="https://slack.cncf.io/" target="_blank">CNCF Slack&lt;/a>&lt;/li>
&lt;li>add yourself
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/adopters/">as an adopter&lt;/a> if you haven&amp;rsquo;t already&lt;/li>
&lt;/ul>
&lt;p>See you around!&lt;/p></description></item><item><title>Blog: Security: Image Provenance</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-image-provenance/</link><pubDate>Mon, 14 Feb 2022 10:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-image-provenance/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-image-provenance/featured-sigstore-architecture_huefa4916296414128a5d73aaac8fdcd3e_53505_640x0_resize_box_3.png" width="640" height="699"/>
&lt;p>Next up in our blog series about Flux Security is how and why we use
signatures for the Flux CLI and all its controller images and what you
can do to verify image provenance in your workflow.&lt;/p>
&lt;p>Since Flux 0.26 our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/security/#signed-container-images">Security Docs&lt;/a>
had this addition:&lt;/p>
&lt;blockquote>
&lt;p>The Flux CLI and the controllers' images are signed using
&lt;a href="https://www.sigstore.dev/" target="_blank">Sigstore&lt;/a> Cosign and GitHub
OIDC. The container images along with their signatures are published
on GitHub Container Registry and Docker Hub.&lt;/p>
&lt;p>To verify the authenticity of Flux&amp;rsquo;s container images, install
&lt;a href="https://docs.sigstore.dev/cosign/installation/" target="_blank">cosign&lt;/a>
and run &lt;code>cosign verify&lt;/code>.&lt;/p>
&lt;pre tabindex="0">&lt;code>&lt;/code>&lt;/pre>&lt;/blockquote>
&lt;p>We are very pleased to bring this to you and encourage you to make use
of it in your workflows to make your clusters more secure. But let&amp;rsquo;s
unpack everything the above section says.&lt;/p>
&lt;h2 id="why-sign-release-artifacts-in-the-first-place">Why sign release artifacts in the first place?&lt;/h2>
&lt;p>Essentially we want you to be able to verify Flux&amp;rsquo;s &lt;em>image provenance&lt;/em>, which
boils down to making sure that&lt;/p>
&lt;ol>
&lt;li>The release you just downloaded actually comes from us, the Flux team&lt;/li>
&lt;li>It hasn&amp;rsquo;t been tampered with&lt;/li>
&lt;/ol>
&lt;p>Cryptographic signatures are the go-to choice for this and have been
used for decades, but are not without challenges.&lt;/p>
&lt;p>The (excellent)
&lt;a href="https://docs.sigstore.dev/" target="_blank">sigstore docs&lt;/a> say this:&lt;/p>
&lt;blockquote>
&lt;p>Software supply chains are exposed to multiple risks. Users are
susceptible to various targeted attacks, along with account and
cryptographic key compromise. Keys in particular are a challenge for
software maintainers to manage. Projects often have to maintain a list
of current keys in use, and manage the keys of individuals who no
longer contribute to a project. Projects all too often store public
keys and digests on git repo readme files or websites, two forms of
storage susceptible to tampering and less than ideal means of securely
communicating trust.&lt;/p>
&lt;p>The tool sets we&amp;rsquo;ve historically relied on were not built for the
present circumstance of remote teams either. This can be seen by the
need to create a web of trust, with teams having to meet in person and
sign each others&amp;rsquo; keys. The current tooling (outside of controlled
environments) all too often feel inappropriate to even technical
users.&lt;/p>
&lt;/blockquote>
&lt;p>We are very happy that
&lt;a href="https://www.sigstore.dev/" target="_blank">sigstore&lt;/a> exists.
It is a Linux Foundation project backed by Google, Red Hat and Purdue
University striving to establish a new standard for signing, verifying and
provenance checks for the open source community.&lt;/p>
&lt;p>&lt;img src="featured-sigstore-architecture.png" alt="sigstore architecture">&lt;/p>
&lt;p>The way it works is that our cosign workflow uses&lt;/p>
&lt;ul>
&lt;li>
&lt;a href="https://docs.sigstore.dev/cosign/overview" target="_blank">cosign&lt;/a> to
sign our release artifacts and store the signatures in an OCI
registry (GHCR and Docker Hub in our case)&lt;/li>
&lt;li>OpenID Connect (OIDC) beforehand to be identified via our email
address&lt;/li>
&lt;li>Fulcio, a root certification authority (CA), which issues a
time-stamped certificate for the identified user that has been
authenticated&lt;/li>
&lt;li>Rekor, acts as the transparency log storage, where the certificate
and signed metadata is stored in a searchable ledger, that can&amp;rsquo;t
be tampered with&lt;/li>
&lt;/ul>
&lt;p>That&amp;rsquo;s a lot of terminology and project names, but what&amp;rsquo;s beautiful
about cosign is that you can relatively easily integrate this using
GitHub Actions (see how it was
&lt;a href="https://github.com/fluxcd/source-controller/pull/550/files" target="_blank">done in
source-controller&lt;/a>).&lt;/p>
&lt;h2 id="how-to-verify-signatures">How to verify signatures&lt;/h2>
&lt;p>If you want to do this manually as an one-off,
&lt;a href="https://docs.sigstore.dev/cosign/installation" target="_blank">install the cosign
tool&lt;/a> and
essentially just run &lt;code>cosign verify&lt;/code> for the image you want to verify:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>cosign verify ghcr.io/fluxcd/source-controller:v1.0.0-rc.5 &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --certificate-oidc-issuer&lt;span style="color:#666">=&lt;/span>https://token.actions.githubusercontent.com &lt;span style="color:#4070a0;font-weight:bold">\
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-weight:bold">&lt;/span> --certificate-identity-regexp&lt;span style="color:#666">=&lt;/span>^https://github.com/fluxcd/.*$
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>With &lt;code>--certificate-oidc-issuer&lt;/code> we verify that the Flux image was signed by GitHub Actions OIDC issuer.
With &lt;code>--certificate-identity-regexp&lt;/code> we verify that the image originates from the FluxCD GitHub organization.&lt;/p>
&lt;p>The output should be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>Verification &lt;span style="color:#007020;font-weight:bold">for&lt;/span> ghcr.io/fluxcd/source-controller:v1.0.0-rc.5 --
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>The following checks were performed on each of these signatures:
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - The cosign claims were validated
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - Existence of the claims in the transparency log was verified offline
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> - The code-signing certificate was verified using trusted certificate authority certificates
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now let&amp;rsquo;s take a look at how to automate this further.&lt;/p>
&lt;h2 id="enforcing-verified-signatures-in-a-cluster">Enforcing verified signatures in a cluster&lt;/h2>
&lt;p>Luckily cosign is compatible with and supported by policy engines such
as Connaisseur, Kyverno and OPA Gatekeeper. Let&amp;rsquo;s go with Kyverno for
now. To make sure that Flux image signatures are verified, all you need
to do is add the following manifest:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-yaml" data-lang="yaml">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#062873;font-weight:bold">apiVersion&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kyverno.io/v1&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ClusterPolicy&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">metadata&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>verify-flux-images&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb">&lt;/span>&lt;span style="color:#062873;font-weight:bold">spec&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">validationFailureAction&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>enforce&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">background&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">false&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">webhookTimeoutSeconds&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#40a070">30&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">failurePolicy&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>Fail&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">rules&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">name&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>verify-cosign-signature&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">match&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">any&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">resources&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">kinds&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- Pod&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">verifyImages&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">imageReferences&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/source-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/kustomize-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/helm-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/notification-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/image-reflector-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#4070a0">&amp;#34;ghcr.io/fluxcd/image-automation-controller:*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">attestors&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">entries&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>- &lt;span style="color:#062873;font-weight:bold">keyless&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">subject&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;https://github.com/fluxcd/*&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">issuer&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;https://token.actions.githubusercontent.com&amp;#34;&lt;/span>&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">rekor&lt;/span>:&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#062873;font-weight:bold">url&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>https://rekor.sigstore.dev&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Have a look at
&lt;a href="https://github.com/fluxcd/flux2-multi-tenancy" target="_blank">fluxcd/flux2-multi-tenancy&lt;/a>
to see a more elaborate example and how the Kyverno policies are wired
up there.&lt;/p>
&lt;p>By verifying all our artifacts, you ensure their provenance and
guarantee that they haven&amp;rsquo;t been modified from the moment we signed and
shipped them. This is just one more measure we are taking to keep you
more secure.&lt;/p>
&lt;h2 id="talk-to-us">Talk to us&lt;/h2>
&lt;p>We love feedback, questions and ideas, so please let us know your
personal use-cases today. Ask us if you have any questions and please&lt;/p>
&lt;ul>
&lt;li>join our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/community/#meetings">upcoming dev meetings&lt;/a>&lt;/li>
&lt;li>find us in the #flux channel on
&lt;a href="https://slack.cncf.io/" target="_blank">CNCF Slack&lt;/a>&lt;/li>
&lt;li>add yourself
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/adopters/">as an adopter&lt;/a> if you haven&amp;rsquo;t already&lt;/li>
&lt;/ul>
&lt;p>See you around!&lt;/p></description></item><item><title>Blog: Security: The Value of SBOMs</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-the-value-of-sboms/</link><pubDate>Mon, 07 Feb 2022 08:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-the-value-of-sboms/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/02/security-the-value-of-sboms/featured-image_huacf912f24b4e58092a4844eb6fa614f5_13167_640x0_resize_box_3.png" width="640" height="174"/>
&lt;h2 id="flux---built-with-security-in-mind">Flux - built with security in mind&lt;/h2>
&lt;p>You don&amp;rsquo;t get to re-architect a successful project very often, but we
did about two years ago. The Flux project was already off to a great
start and had
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/adopters/#flux-legacy">many happy adopters&lt;/a> and many of
its design principles we kept at the forefront of our mind:&lt;/p>
&lt;ul>
&lt;li>Pull vs Push: if you haven&amp;rsquo;t read this
&lt;a href="https://web.archive.org/web/20231207173518/https://www.weave.works/blog/why-is-a-pull-vs-a-push-pipeline-important" target="_blank">great blog
post&lt;/a>
from 2018 about why you want Pull - all it says still holds true.&lt;/li>
&lt;li>Least amount of privileges.&lt;/li>
&lt;li>Reusing best practises, libraries and tools, e.g. client-go and helm
APIs.&lt;/li>
&lt;li>And more we will explain further down the line.&lt;/li>
&lt;/ul>
&lt;p>Why did we re-architect and rewrite Flux? Flux Legacy (v1) had been
started Mid-2016 and while it worked great and still does, it didn&amp;rsquo;t
quite benefit from more recent developments in the Kubernetes space like
&lt;a href="https://github.com/kubernetes-sigs/controller-runtime" target="_blank">controller-runtime&lt;/a>
because it pre-dated them significantly.&lt;/p>
&lt;p>Also rewriting Flux as a set of very targeted controllers was a unique
opportunity to reduce the scope (and thus attack surface) of these
individual sub-projects and make testing and debugging a lot easier.
Re-usability as well.&lt;/p>
&lt;p>All of this said, we believe that a blog series about Flux and its
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/security/">security&lt;/a>
considerations and features is in order and we will kick it off talking
about SBOMs.&lt;/p>
&lt;h3 id="what-is-a-sbom">What is a SBOM?&lt;/h3>
&lt;p>Since Flux release 0.26 we publish a SBOM for each of the individual
controllers. We reported about this in the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/01/january-update/#-security-enhancements">accompanying monthly update
blog post&lt;/a>.&lt;/p>
&lt;p>So what is a SBOM? It&amp;rsquo;s short for Software Bill of Materials. Wikipedia
defines it as&lt;/p>
&lt;blockquote>
&lt;p>A &lt;strong>software bill of materials&lt;/strong> (SBOM) is a list of components in a
piece of software. Software vendors often create products by
assembling open source and commercial software components. The SBOM
describes the components in a product. It is analogous to a list of
ingredients on food packaging: where you might consult a label to
avoid foods that may cause allergies, SBOMs can help organizations or
persons avoid consumption of software that could harm them.&lt;/p>
&lt;p>The concept of a BOM is well-established in traditional manufacturing
as part of supply chain management. A manufacturer uses a BOM to track
the parts it uses to create a product. If defects are later found in a
specific part, the BOM makes it easy to locate affected products.&lt;/p>
&lt;/blockquote>
&lt;p>For the Flux project we publish a Software Bill of Materials (SBOM) with
each release. The SBOM is generated with
&lt;a href="https://github.com/anchore/syft" target="_blank">Syft&lt;/a> in the
&lt;a href="https://spdx.dev/" target="_blank">SPDX&lt;/a> format.&lt;/p>
&lt;p>&lt;img src="featured-image.png" alt="SPDX logo">&lt;/p>
&lt;p>The &lt;code>spdx.json&lt;/code> file is available for download on the GitHub release page
e.g.:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="background-color:#f0f0f0;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-shell" data-lang="shell">&lt;span style="display:flex;">&lt;span>curl -sL https://github.com/fluxcd/flux2/releases/download/v0.25.3/flux_0.25.3_sbom.spdx.json | jq
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Inspecting the JSON data, you will see that for each of the files and
libraries required for building and shipping the release you can verify
the license, origin, version and checksum.&lt;/p>
&lt;p>What might seem like a lot of overhead and unnecessary bookkeeping,
quickly turns out as useful information because it allows you to&lt;/p>
&lt;ul>
&lt;li>Verify the origin and integrity of artifacts&lt;/li>
&lt;li>Inspect the dependencies easily for CVEs and known security issues&lt;/li>
&lt;li>Get a holistic view of your complete supply chain, so which other
dependencies and Open Source projects now become part of your
stack&lt;/li>
&lt;/ul>
&lt;p>Because it is structured data, all of the above can be done in an
automated, programmatic fashion.&lt;/p>
&lt;p>Big organizations, corporate or governmental, already keep track of
SBOMs and make decisions based on the information provided there. Some
started requiring SBOMs for software in-use. A good example of this is
the
&lt;a href="https://www.whitehouse.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/" target="_blank">government of the USA requiring
SBOM&lt;/a>
from software suppliers.&lt;/p>
&lt;h3 id="possible-use-cases-for-sboms">Possible use-cases for SBOMs&lt;/h3>
&lt;p>Here are a couple more concrete examples of what the SBOMs for Flux
allow you to do:&lt;/p>
&lt;ul>
&lt;li>Security alerts of dependencies will be the most obvious use-case.
If a CVE is detected, you can inspect your SBOM and see if the
components you are using are in any way affected.&lt;/li>
&lt;li>It will be easy to identify when a certain component was created and
how. In addition to that, having the licensing information of all
the pieces, you better know what you can do with it (redistribute,
change, etc).&lt;/li>
&lt;li>Automation allows you to send alerts, if a compliance issue is
detected, e.g. if the licensing of updated/replaced dependencies
changes.&lt;/li>
&lt;li>Missing components or required build files. Incompatible licenses
and more.&lt;/li>
&lt;/ul>
&lt;p>One example of automating all of this could be to store SBOMs in
&lt;a href="https://grafeas.io/" target="_blank">https://grafeas.io/&lt;/a>. This way you could search across your Estate for:&lt;/p>
&lt;ul>
&lt;li>Images that are built from a particular Github commit that is known to have introduced a security problem.&lt;/li>
&lt;li>Find all images that were built by a certain version of a certain builder when that builder is known to have been compromised.&lt;/li>
&lt;li>Find all images in my project that are impacted by &lt;code>CVE-1234&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>For policy enforcement,
&lt;a href="https://github.com/grafeas/kritis" target="_blank">kritis&lt;/a> can be used to leverage the information provided by SBOMs inside Grafeas to enforce policies inside of a cluster, enabling auto-blocking of applications that are vulnerable to a specific CVE for example.&lt;/p>
&lt;p>If you have read this far and you are using SBOMs in your organisation,
let us know what you get out of them as well!&lt;/p>
&lt;h3 id="whats-more">What&amp;rsquo;s more&lt;/h3>
&lt;p>If you would like to know more about the history of SBOMs and their
development, you might want to read this
&lt;a href="https://blog.chainguard.dev/what-an-sbom-can-do-for-you/" target="_blank">excellent article from
ChainGuard&lt;/a>
about the subject.&lt;/p>
&lt;p>At the time of writing this, Syft does not yet
&lt;a href="https://github.com/anchore/syft/issues/656" target="_blank">classify licenses based
on the file
contents&lt;/a>, but
it is being considered.&lt;/p>
&lt;p>Here is the table of SBOMs for all the latest Flux controllers and
CLI (as of 2022-02-09).&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Project&lt;/th>
&lt;th>SBOM&lt;/th>
&lt;th>Dependencies &amp;amp; Licenses&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>flagger&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flagger/releases/download/v1.17.0/flagger_1.17.0_sbom.spdx.json" target="_blank">1.17.0&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fflagger/v1.17.0/dependencies" target="_blank">1.17.0&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>flux2&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/flux2/releases/download/v0.26.2/flux_0.26.2_sbom.spdx.json" target="_blank">0.26.2&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fflux2/v0.26.2/dependencies" target="_blank">0.26.2&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>helm-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/helm-controller/releases/download/v0.16.0/helm-controller_0.16.0_sbom.spdx.json" target="_blank">0.16.0&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fhelm-controller/v0.16.0/dependencies" target="_blank">0.16.0&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>image-automation-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/image-automation-controller/releases/download/v0.20.0/image-automation-controller_0.20.0_sbom.spdx.json" target="_blank">0.20.0&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fimage-automation-controller/v0.20.0/dependencies" target="_blank">0.20.0&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>image-reflector-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/image-reflector-controller/releases/download/v0.16.0/image-reflector-controller_0.16.0_sbom.spdx.json" target="_blank">0.16.0&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fimage-reflector-controller/v0.16.0/dependencies" target="_blank">0.16.0&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>kustomize-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/kustomize-controller/releases/download/v0.20.1/kustomize-controller_0.20.1_sbom.spdx.json" target="_blank">0.20.1&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fkustomize-controller/v0.20.1/dependencies" target="_blank">0.20.1&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>notification-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/notification-controller/releases/download/v0.21.0/notification-controller_0.21.0_sbom.spdx.json" target="_blank">0.21.0&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fnotification-controller/v0.21.0/dependencies" target="_blank">0.21.0&lt;/a>&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>source-controller&lt;/td>
&lt;td>
&lt;a href="https://github.com/fluxcd/source-controller/releases/download/v0.21.2/source-controller_0.21.2_sbom.spdx.json" target="_blank">0.21.2&lt;/a>&lt;/td>
&lt;td>
&lt;a href="https://deps.dev/go/github.com%2Ffluxcd%2Fsource-controller/v0.21.2/dependencies" target="_blank">0.21.2&lt;/a>&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>This is just one more measure we are taking to keep you more secure.&lt;/p>
&lt;h2 id="talk-to-us">Talk to us&lt;/h2>
&lt;p>We love feedback, questions and ideas, so please let us know how you are
using SBOMs today. Ask us if you have any questions and please&lt;/p>
&lt;ul>
&lt;li>join our
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/community/#meetings">upcoming dev meetings&lt;/a>&lt;/li>
&lt;li>find us in the #flux channel on
&lt;a href="https://slack.cncf.io/" target="_blank">CNCF Slack&lt;/a>&lt;/li>
&lt;li>add yourself
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/adopters/">as an adopter&lt;/a> if you haven&amp;rsquo;t already&lt;/li>
&lt;/ul>
&lt;p>See you around!&lt;/p></description></item><item><title>Blog: Flux Security Audit has concluded</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/</link><pubDate>Wed, 10 Nov 2021 12:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2021/11/flux-security-audit/featured-image_hu64c248523c5fd6e7257d472c4637e51d_32255_640x0_resize_box_3.png" width="640" height="185"/>
&lt;p>As Flux is an Incubation project within the
&lt;a href="https://www.cncf.io/" target="_blank">Cloud Native Computing
Foundation&lt;/a>, we were graciously
granted a sponsored audit. The primary aim was to assess Flux&amp;rsquo;s
fundamental security posture and to identify next steps in its security
story. The audit was commissioned by the CNCF, and facilitated by
&lt;a href="https://ostif.org/" target="_blank">OSTIF&lt;/a> (the Open Source Technology
Improvement Fund).
&lt;a href="https://adalogics.com/" target="_blank">ADA Logics&lt;/a>
was quickly brought into the picture, and spent a month on the audit.&lt;/p>
&lt;p>The Flux maintainers and community are very grateful for the work put
into this by everyone and the opportunity to grow and improve as a
project.&lt;/p>
&lt;p>&lt;img src="featured-image.png" alt="ADA Logics, CNCF, OSTIF">&lt;/p>
&lt;h2 id="our-first-cve-in-flux">Our first CVE in Flux&lt;/h2>
&lt;p>Let&amp;rsquo;s start with what will likely interest you as a Flux user. The
engagement uncovered a privilege escalation vulnerability in Flux that
could enable users to gain cluster admin privileges. The issue has been
fixed and is assigned CVE 2021-41254, and the full disclosure advisory
is available at the following link:&lt;/p>
&lt;p>CVE-2021-41254:
&lt;a href="https://github.com/fluxcd/kustomize-controller/security/advisories/GHSA-35rf-v2jv-gfg7" target="_blank">Privilege escalation to cluster admin on multi-tenant
Flux&lt;/a>.&lt;/p>
&lt;p>Description:&lt;/p>
&lt;p>Users that can create Kubernetes Secrets, Service Accounts and Flux
&lt;code>Kustomization&lt;/code> objects, could execute commands inside the
&lt;code>kustomize-controller&lt;/code> container by embedding a shell script in a
Kubernetes Secret. This can be used to run &lt;code>kubectl&lt;/code> commands under the
Service Account of &lt;code>kustomize-controller&lt;/code>, thus allowing an authenticated
Kubernetes user to gain cluster admin privileges.&lt;/p>
&lt;p>Impact:&lt;/p>
&lt;p>Multi-tenant environments where non-admin users have permissions to
create Flux &lt;code>Kustomization&lt;/code> objects are affected by this issue.&lt;/p>
&lt;p>Fix:&lt;/p>
&lt;p>This vulnerability was fixed in &lt;code>kustomize-controller&lt;/code> v0.15.0 (included
in Flux v0.18.0) released on 2021-10-08. Starting with v0.15, the
&lt;code>kustomize-controller&lt;/code> no longer executes shell commands on the container
OS and the &lt;code>kubectl&lt;/code> binary has been removed from the container image.&lt;/p>
&lt;h2 id="audit-report-with-full-details">Audit report with full details&lt;/h2>
&lt;p>We are thankful for the great attention to detail by the team at ADA
Logics. The whole report can be found
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/FluxFinalReport-v1.1.pdf">here&lt;/a>.
To benefit from the analysis in all its detail, we created a
&lt;a href="https://github.com/orgs/fluxcd/projects/5" target="_blank">project
board&lt;/a> in
GitHub. If you take a look at it closely, you will see that we have
fixed some of the most immediate issues already.&lt;/p>
&lt;p>Broadly speaking, the issues fall into three categories:&lt;/p>
&lt;ol>
&lt;li>Enabling Fuzzing for the Flux project&lt;/li>
&lt;li>Documentation issues&lt;/li>
&lt;li>Concrete issues discovered in the Flux code&lt;/li>
&lt;/ol>
&lt;h3 id="flux-coming-to-oss-fuzz">Flux coming to OSS-Fuzz&lt;/h3>
&lt;p>The team at ADA Logics didn&amp;rsquo;t stop at reviewing Flux code. We were
pleasantly surprised to receive actual PRs by the team, who set down and
helped us integrate with the OSS-Fuzz project. Some of this work still
needs to be integrated into all of the Flux controllers, but we are very
pleased that a start has been made! OSS-Fuzz is a service for running
fuzzers continuously on important open source projects, and the goal is
to use sophisticated dynamic analysis to uncover security and
reliability issues. There are already numerous other CNCF projects
integrated, e.g. Kubernetes, Envoy and Fluent-bit, and we&amp;rsquo;re excited to
be a part of that.&lt;/p>
&lt;h3 id="our-documentation-from-an-outside-perspective">Our documentation from an outside perspective&lt;/h3>
&lt;p>One very important piece of feedback was that our documentation is
mostly geared towards end users, who need very concrete advice on how to
integrate Flux into their setups. We provide lots of examples, which are
helpful if you want Flux to behave the right way. What is missing to
date is an architectural overview and documentation which focuses on the
security-related aspects of Flux.&lt;/p>
&lt;h3 id="what-transpired-during-the-code-review">What transpired during the code review&lt;/h3>
&lt;p>The team at ADA Logics found 22 individual issues, some of which were
results from the fuzzers. 1 high severity (that&amp;rsquo;s the above mentioned
CVE), 3 medium severity, 13 low severity and 5 informational.&lt;/p>
&lt;p>We appreciate the attention to detail by the team at ADA Logics. The
issues range from dependency upgrades to oversights in the code (files
which aren&amp;rsquo;t closed during an operation, unhandled errors) to misleading
documentation.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Issue&lt;/th>
&lt;th>Severity&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1:
&lt;a href="https://github.com/fluxcd/kustomize-controller/security/advisories/GHSA-35rf-v2jv-gfg7" target="_blank">Arbitrary command execution via command injection in the kustomize controller by way of secrets&lt;/a>&lt;/td>
&lt;td>High&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/246" target="_blank">Nil-dereference in image-automation controller&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3:
&lt;a href="https://github.com/fluxcd/flux2/issues/2011" target="_blank">Credentials exposed in environment variables and command line arguments&lt;/a>&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>4:
&lt;a href="https://github.com/fluxcd/flux2/issues/1658" target="_blank">Use of deprecated library&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5:
&lt;a href="https://github.com/fluxcd/community/issues/133" target="_blank">Invalid and missing testing documentation&lt;/a>&lt;/td>
&lt;td>Informational&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>6:
&lt;a href="https://github.com/fluxcd/.github/issues/8" target="_blank">Bug fixes do not always include regression tests&lt;/a>&lt;/td>
&lt;td>Informational&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>7:
&lt;a href="https://github.com/fluxcd/source-controller/issues/467" target="_blank">Deprecated SHA-1 is used for checksums&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>8:
&lt;a href="https://github.com/fluxcd/source-controller/issues/468" target="_blank">Missing checksum verification&lt;/a>&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>9:
&lt;a href="https://github.com/fluxcd/pkg/issues/172" target="_blank">Inconsistent and missing logging&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>10:
&lt;a href="https://github.com/fluxcd/source-controller/issues/470" target="_blank">Reading large files can crash flux with an out-of-memory bug&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>11:
&lt;a href="https://github.com/fluxcd/source-controller/issues/471" target="_blank">Files are opened but never closed&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>12:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/242" target="_blank">Unhandled error&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>13:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/243" target="_blank">Slice bounds out of range&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>14:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/246" target="_blank">Possible nil-deref in image-automation controller&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>15:
&lt;a href="https://github.com/fluxcd/pkg/issues/173" target="_blank">Inconsistent code-styles and potential nil-dereferences&lt;/a>&lt;/td>
&lt;td>Informational&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>16:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/244" target="_blank">Missing return statement after error&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>17:
&lt;a href="https://github.com/fluxcd/kustomize-controller/issues/476" target="_blank">File extension comparisons are case sensitive&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>18:
&lt;a href="https://github.com/fluxcd/source-controller/issues/472" target="_blank">Some dependencies are outdated&lt;/a>&lt;/td>
&lt;td>Informational&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>19:
&lt;a href="https://github.com/fluxcd/flux2/issues/2014" target="_blank">Lack of container security options in deployed pods&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>20:
&lt;a href="https://github.com/fluxcd/pkg/issues/174" target="_blank">Unhandled errors from deferred file close operations&lt;/a>&lt;/td>
&lt;td>Low&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>21:
&lt;a href="https://github.com/fluxcd/notification-controller/issues/278" target="_blank">x509 certificates are not used for Webex&lt;/a>&lt;/td>
&lt;td>Medium&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>22:
&lt;a href="https://github.com/fluxcd/image-automation-controller/issues/245" target="_blank">Unnecessary conditions in the code&lt;/a>&lt;/td>
&lt;td>Informational&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>At the time of writing, 43% of the issues were still TODO, 21% WIP and 36% DONE.&lt;/p>
&lt;h2 id="the-road-ahead">The Road Ahead&lt;/h2>
&lt;p>We are very happy we were given the opportunity to work with and have
our assumptions and code reviewed and tested by security experts. Early
on we decided that we want to benefit from the findings as much as
possible. That&amp;rsquo;s why we created a
&lt;a href="https://github.com/orgs/fluxcd/projects/5" target="_blank">project
board&lt;/a> and added
a review of it as a standing agenda item in our weekly dev meetings.&lt;/p>
&lt;blockquote>
&lt;p>&amp;ldquo;The Flux team also created a public and easy to track dashboard
showing all of the work we've done together and is a fantastic
example of good issue-tracking and remediation.&amp;rdquo;&lt;/p>
&lt;p>-- Derek Zimmer, President and Executive Director,
&lt;a href="https://ostif.org/" target="_blank">OSTIF&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;h3 id="growing-the-team">Growing the team&lt;/h3>
&lt;p>If you are interested in contributing to this, we are very much looking
forward to working with you. We welcome contributions in helping resolve
issues of the road, additional comments on our security posture and also
welcome contributions in the form of extending our fuzzing
infrastructure. Finally, if you have any additional security feedback,
please come and talk to us.&lt;/p>
&lt;p>We are working full steam on the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/roadmap/">Flux Roadmap&lt;/a>, just recently got
more maintainers involved and continue to listen to feedback.&lt;/p>
&lt;p>Again we would like to thank the Cloud Native Computing Foundation for
sponsoring the audit, the Open Source Technology Improvement Fund for
the coordination and ADA Logics for the careful review and advice during
the audit period.&lt;/p>
&lt;p>We are happy and proud to be part of this community!&lt;/p></description></item></channel></rss>