<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Flux – oci</title><link>https://deploy-preview-2413--fluxcd.netlify.app/tags/oci/</link><description>Recent content in oci on Flux</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Mon, 14 Nov 2022 10:30:00 +0000</lastBuildDate><atom:link href="https://deploy-preview-2413--fluxcd.netlify.app/tags/oci/index.xml" rel="self" type="application/rss+xml"/><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: CNCF Talk: Increased security and scalability with OCI</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/cncf-talk-flux-oci/</link><pubDate>Wed, 26 Oct 2022 13:20:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/cncf-talk-flux-oci/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/cncf-talk-flux-oci/oci-featured_hu02c8ff3ca7eb3b16c64ca5ec0f4c7ec0_122624_640x0_resize_q75_box.jpg" width="640" height="360"/>
&lt;p>Integrating OCI into Flux was one of the most-requested features of all
times. We listened to your feedback and in the past couple of releases,
OCI was integrated more deeply into Flux. Here is a brief summary of
what landed when:&lt;/p>
&lt;ul>
&lt;li>v0.31 (Jun 2022): Support for Helm repositories of type OCI&lt;/li>
&lt;li>v0.32 (Aug 2022): Kubernetes manifests, Kustomize overlays and
Terraform code as OCI artifacts&lt;/li>
&lt;li>v0.33 (Aug 2022): More configurability of OCI settings&lt;/li>
&lt;li>v0.34 (Sep 2022): More flexibility when interacting with OCI
artifacts/repositories&lt;/li>
&lt;li>v0.35 (Sep 2022): verify OCI artifacts signed by cosign&lt;/li>
&lt;li>v0.36 (Oct 2022): verify OCI helm charts signed by cosign plus lots
of new tooling to interact with OCI using the Flux CLI&lt;/li>
&lt;/ul>
&lt;p>To bring you up to speed with what&amp;rsquo;s possible, Max Jonas Werner, Flux
Core Maintainer and Senior Software Engineer at Weaveworks, gave a talk
in the CNCF Online Programme series to give some background and do a
practical demo.&lt;/p>
&lt;p>First off, Max explained the core GitOps concepts and gave an overview
of the architecture of Flux. In the next step, he dived into how Docker
and others created the Open Containers Initiative (OCI) which is a part
of the Linux Foundation.&lt;/p>
&lt;p>One of the key points Max is making is that we went through a
transformation from Docker containers to generic application and
configuration containers. More and more OCI is becoming an application
delivery format.&lt;/p>
&lt;p>OCI registries (which implement the distribution spec) are a commodity
in the cloud space. This means that it&amp;rsquo;s very easy to get enhanced
scalability this way, because pulling an OCI image is much less
resource-intensive compared to a full or shallow Git clone.
Additionally, high available registries are available everywhere.&lt;/p>
&lt;p>It also provides many ways to secure your infrastructure.
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/helmrepositories/#provider">Flux
leverages Kubernetes workload identity and
IAM&lt;/a>
when pulling OCI artifacts from managed registries. So no more key
management, no more SSH keys to generate, no more proprietary API usage
for token generation. You use the same mechanism that is used for
pulling container images. You might also want to check out this post
about
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/10/prove-the-authenticity-of-oci-artifacts/">verifying authenticity of artifacts with
cosign&lt;/a>.&lt;/p>
&lt;p>Max spends more than half of his presentation time for the demo, so you
get a good idea of how to use these new features and integrate them into
your setup.&lt;/p>
&lt;p>Check out the video here:&lt;/p>
&lt;div class="responsive-video">
&lt;iframe src="https://www.youtube.com/embed/l5pVzP6wsP0" allowfullscreen title="YouTube Video">&lt;/iframe>
&lt;/div>
&lt;p>Thanks a lot Max for taking the time to walk us through this!&lt;/p>
&lt;p>Start your journey and start
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/cheatsheets/oci-artifacts/">using Flux&amp;rsquo;s OCI
features&lt;/a> today.&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: Managing Kyverno Policies as OCI Artifacts with OCIRepository Sources</title><link>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/08/manage-kyverno-policies-as-ocirepositories/</link><pubDate>Thu, 01 Sep 2022 11:30:00 +0000</pubDate><guid>https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/08/manage-kyverno-policies-as-ocirepositories/</guid><description>
&lt;img src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/08/manage-kyverno-policies-as-ocirepositories/meme-featured_hu1b81cb8283a13af439b1a218a4c0872a_49442_640x0_resize_box_3.png" width="640" height="480"/>
&lt;p>The Flux team has released a new version of Flux 
&lt;a href="https://github.com/fluxcd/flux2/releases/tag/v0.32.0" target="_blank">v0.32&lt;/a> that includes fantastic features. One of them is OCI Repositories feature that allows us to store and distribute a wide variety of sources such as Kubernetes manifests, Kustomize overlays, and Terraform modules as
&lt;a href="https://github.com/opencontainers/artifacts#project-introduction-and-scope" target="_blank">OCI (Open Container Initiative) artifacts&lt;/a>. Furthermore, the Flux team got us even more excited because they are planning to verify the authenticity of the OCI artifacts before they get applied into Kubernetes by integrating Cosign, which is one of the most significant projects from the @projectsigstore community that help us to sign and verify OCI images, blobs, etc. please see the 
&lt;a href="https://github.com/fluxcd/source-controller/issues/863" target="_blank">issue&lt;/a> to get more details about the plan.&lt;/p>
&lt;blockquote>
&lt;p>⚠️ &lt;strong>Note:&lt;/strong> You can read the RFC of this feature
&lt;a href="https://github.com/fluxcd/flux2/tree/main/rfcs/0003-kubernetes-oci" target="_blank">here&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;blockquote class="twitter-tweet">&lt;p lang="en" dir="ltr">I&amp;#39;m super excited to announce that &lt;a href="https://twitter.com/fluxcd?ref_src=twsrc%5Etfw">@fluxcd&lt;/a> support for distributing &lt;a href="https://twitter.com/hashtag/Kubernetes?src=hash&amp;amp;ref_src=twsrc%5Etfw">#Kubernetes&lt;/a> manifests, Kustomize overlays and Terraform code as OCI artifacts has finally shipped in v0.32. &lt;a href="https://t.co/144HY6LUTy">https://t.co/144HY6LUTy&lt;/a>&lt;/p>&amp;mdash; Stefan Prodan (@stefanprodan) &lt;a href="https://twitter.com/stefanprodan/status/1557754198648913921?ref_src=twsrc%5Etfw">August 11, 2022&lt;/a>&lt;/blockquote>
&lt;script async src="https://platform.twitter.com/widgets.js" charset="utf-8">&lt;/script>
&lt;p>Today’s blog post is all about a quick tour of this feature and will give you a real-world example of it to show you how you can leverage this feature to manage Kyverno policies as OCI Artifacts. It is worth saying that this topic has been discussed for a while in the Kyverno community, too. There is an ongoing 
&lt;a href="https://github.com/kyverno/KDP/pull/19" target="_blank">issue&lt;/a> about packaging and distributing Kyverno policies as OCI Artifacts through its CLI. Also, there is a chance to move that logic into Kyverno’s core.&lt;/p>
&lt;p>But for those who might not be familiar enough with OCI artifacts (including me), it’s worth explaining what the OCI Artifacts are before jumping into the details. OCI Artifacts gives you the power of storing and distributing other types of data (nearly anything), such as Kubernetes deployment files, 
&lt;a href="https://helm.sh/" target="_blank">Helm Charts&lt;/a>, 
&lt;a href="https://cnab.io/" target="_blank">and CNAB&lt;/a>, in addition to container images via OCI registries. And today, we’ll be using this feature for Kyverno policies. To be more precise, OCI Artifacts are not a new specification, format, or API. It just utilizes the existent 
&lt;a href="https://github.com/opencontainers/image-spec/blob/master/manifest.md" target="_blank">OCI manifest&lt;/a> and 
&lt;a href="https://github.com/opencontainers/image-spec/blob/master/image-index.md" target="_blank">OCI index&lt;/a> definitions. Hence, we can quickly start using the same client tooling, such as a crane, skopeo, etc., and distribute them using OCI registries, thanks to the 
&lt;a href="https://github.com/opencontainers/distribution-spec/" target="_blank">OCI distribution-spec&lt;/a>. Because OCI Artifacts does not change anything related to the specs, it only expands them to give people (artifact authors) power to define their content types. It is more like a generic definition for determining what can be stored in an OCI registry and consumed by clients.&lt;/p>
&lt;p>The Flux CLI generates a single layer OCI image for storing things. As you can use some other tools to generate an OCI image with multiple layers in it, you can use the
&lt;a href="https://github.com/fluxcd/flux2/tree/main/rfcs/0003-kubernetes-oci#layer-selection" target="_blank">Layer Selection&lt;/a> feature that Flux provides to select the layers you want to use in the OCI image. If the layer selector matches more than one layer, the first layer matching the specified media type will be used. Note that Flux requires that the OCI layer is compressed in the tar+gzip format.&lt;/p>
&lt;figure class="card rounded p-2 td-post-card mb-4 mt-4" style="max-width: 410px">
&lt;img class="card-img-top" src="https://deploy-preview-2413--fluxcd.netlify.app/blog/2022/08/manage-kyverno-policies-as-ocirepositories/meme-featured_hu1b81cb8283a13af439b1a218a4c0872a_49442_400x0_resize_box_3.png" width="400" height="300">
&lt;figcaption class="card-body px-0 pt-2 pb-0">
&lt;p class="card-text">
&lt;/p>
&lt;/figcaption>
&lt;/figure>
&lt;p>Today, we’ll leverage the OCI Repositories feature to apply Kyverno policies stored in an OCI registry into the Kubernetes cluster.&lt;/p>
&lt;p>First, we need to install Flux CLI, please see the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/installation/">installation&lt;/a> page for more details.&lt;/p>
&lt;p>Next, we should have a Kubernetes cluster running. We’ll be using
&lt;a href="https://kind.sigs.k8s.io/docs/user/quick-start#configuring-your-kind-cluster" target="_blank">KinD&lt;/a> for this purpose.&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>Once the cluster has been provisioned successfully, we need to install Flux components into it by simply running the command below:&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 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>developer-guy &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-kyverno-policies &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/local &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>⚠️ &lt;strong>Note:&lt;/strong> Don&amp;rsquo;t forget to change the values with your own details!&lt;/p>
&lt;/blockquote>
&lt;p>This command will install Flux and create necessary files for us and push them into the repository.&lt;/p>
&lt;p>Next, we should install Kyverno by using a GitOps approach with Flux. In order to do that, we use the following 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-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>GitRepository&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>kyverno-controller&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>flux-system&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">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>30m&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://github.com/kyverno/kyverno&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">ignore&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>|&lt;span style="color:#4070a0;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-style:italic"> /*
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-style:italic"> !/config/&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">ref&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">semver&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;1.x&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:#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>kustomize.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>Kustomization&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>kyverno-controller&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>flux-system&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">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>30m&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">sourceRef&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">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>GitRepository&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>kyverno-controller&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">serviceAccountName&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>kustomize-controller&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">path&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>./config/release&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">prune&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&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">wait&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&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">timeout&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Do not forget to check whether everything works fine before moving into the next steps:&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 kyverno-controller
&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>kyverno-controller v1.7.3/f2b63ce False True Applied revision: v1.7.3/f2b63ce
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now, we are ready to create an OCI image to store my Kyverno policies.&lt;/p>
&lt;blockquote>
&lt;p>⚠️  You can find all the code examples in
&lt;a href="https://github.com/developer-guy/flux-kyverno-policies" target="_blank">GitHub&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>In order to do that, we will clone our repository that holds the Kyverno policies and create an OCI artifact to store them.&lt;/p>
&lt;blockquote>
&lt;p>⚠️ We are expecting that some other team like DevSecOps will be responsible for maintaining and publishing the policies to our registry.&lt;/p>
&lt;/blockquote>
&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 https://github.com/developer-guy/my-kyverno-policies.git
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ &lt;span style="color:#007020">cd&lt;/span> my-kyverno-policies
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>$ flux push artifact oci://ghcr.io/developer-guy/policies:v1.0.0 &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;.&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;&lt;/span>&lt;span style="color:#007020;font-weight:bold">$(&lt;/span>git config --get remote.origin.url&lt;span style="color:#007020;font-weight:bold">)&lt;/span>&lt;span style="color:#4070a0">&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;&lt;/span>&lt;span style="color:#007020;font-weight:bold">$(&lt;/span>git branch --show-current&lt;span style="color:#007020;font-weight:bold">)&lt;/span>&lt;span style="color:#4070a0">/&lt;/span>&lt;span style="color:#007020;font-weight:bold">$(&lt;/span>git rev-parse HEAD&lt;span style="color:#007020;font-weight:bold">)&lt;/span>&lt;span style="color:#4070a0">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>► pushing artifact to ghcr.io/developer-guy/policies:v1.0.0
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>✔ artifact successfully pushed to ghcr.io/developer-guy/policies@sha256:56e853e3c5c02139c840b7f5c89a02f63ede8dc498ed3925a52360032aa49e60
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;blockquote>
&lt;p>⚠️ &lt;strong>Note:&lt;/strong> Don&amp;rsquo;t forget to change the values with your own details!&lt;/p>
&lt;/blockquote>
&lt;p>Last but not least, we need to create an &lt;code>OCIRepository&lt;/code> resource that points to my 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-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>OCIRepository&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>kyverno-policies&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>flux-system&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">interval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m&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/developer-guy/policies&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">ref&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">semver&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#4070a0">&amp;#34;v1.x&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">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>ghcr-auth&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:#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>kustomize.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>Kustomization&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>kyverno-policies&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>flux-system&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">sourceRef&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">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>OCIRepository&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>kyverno-policies&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>60m&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">retryInterval&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>5m&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">path&lt;/span>:&lt;span style="color:#bbb"> &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">prune&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&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">wait&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#007020;font-weight:bold">true&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">timeout&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>2m&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">dependsOn&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>kyverno-controller&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">patches&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>&lt;span style="color:#60a0b0;font-style:italic"># enforce all policies&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">patch&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>|&lt;span style="color:#4070a0;font-style:italic">
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-style:italic"> - op: replace
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-style:italic"> path: /spec/validationFailureAction
&lt;/span>&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#4070a0;font-style:italic"> value: enforce&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">target&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">kind&lt;/span>:&lt;span style="color:#bbb"> &lt;/span>ClusterPolicy&lt;span style="color:#bbb">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I&amp;rsquo;d like to highlight some key points about the resources above. Here in &lt;code>OCIRepository&lt;/code> resource, we are using
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/ocirepositories/#semver-example">SemVer&lt;/a> to select the policies that we want to apply. &lt;code>.spec.ref&lt;/code> is an optional field to specify the OCI reference to resolve and watch for changes. If not specified, the latest version of the repository will be used. You can reach out to the complete list of references supported in Flux, here is the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/source/ocirepositories/#reference">link&lt;/a> for you.&lt;/p>
&lt;p>Also, in the &lt;code>Kustomization&lt;/code> resource, we are using &lt;code>.spec.patches&lt;/code> to apply patches to the policies that we want to enforce. We are using &lt;code>op: replace&lt;/code> to replace the existing value of the field with the new one. &lt;code>path&lt;/code> is the path to the field that we want to replace. &lt;code>value&lt;/code> is the value of the field that we want to replace. To get more detail about the &lt;code>Patches&lt;/code>, please see the
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/kustomize/kustomization/#patches">link&lt;/a>.&lt;/p>
&lt;p>Last but not least, we are specifying an explicit dependencies for the &lt;code>Kustomization&lt;/code> resource by using &lt;code>dependsOn&lt;/code> keyword that ensures the Kyverno deployment is ready before applying the policies. This is important because Kyverno needs to be installed before applying the policies. Otherwise, the policies won&amp;rsquo;t be used because CRD (Custom Resource Definitions) won&amp;rsquo;t exist until Kyverno works. You can learn more about the dependencies of &lt;code>Kustomization&lt;/code> resource,
&lt;a href="https://deploy-preview-2413--fluxcd.netlify.app/flux/components/kustomize/kustomization/#dependencies">here&lt;/a>.&lt;/p>
&lt;p>Now, we can apply these manifests by committing and pushing them to the repository and letting Flux take care of the rest but still, one little step left that we need to do, which is authentication.&lt;/p>
&lt;blockquote>
&lt;p>⚠️  Don&amp;rsquo;t forget, the authentication part is only needed when the OCI artifact is not publicly accessible. If your image has publicy available, you can skip that part.&lt;/p>
&lt;/blockquote>
&lt;p>You might notice a &lt;code>secretRef&lt;/code> section in the &lt;code>OCIRepository&lt;/code> resource. We should create this secret because Flux should be able to pull my container image. To do that, we should follow the documentation.&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>developer-guy &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_PAT&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>Once everything is completed, you should be able to see the following output:&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 clusterpolicies
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>NAME BACKGROUND ACTION READY
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>require-base-image &lt;span style="color:#007020">true&lt;/span> enforce &lt;span style="color:#007020">true&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is what we expected to happen, whee!🕺🏻&lt;/p>
&lt;p>This is an exciting policy, though, if you want to learn more about it, I wrote a 
&lt;a href="https://nirmata.com/2022/07/14/securing_base_images/" target="_blank">blog post&lt;/a> that explains what the base image concept refers to and how we can enforce policies related to them.&lt;/p>
&lt;p>As you can see, this feature is quite promising and easy to use. I hope you enjoyed it, and please stay tuned because there are more features on the way you don’t want to miss.&lt;/p>
&lt;p>Thanks for reading.&lt;/p></description></item></channel></rss>