From bedb53e0fa50135cf3fe2b64abbe981cf33bcee3 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Fri, 12 Nov 2021 12:35:26 +0200 Subject: [PATCH 1/2] Verify artifacts integrity After downloading an artifact, compute its checksum and verify that it matches the original checksum advertised by source-controller. Signed-off-by: Stefan Prodan --- controllers/kustomization_controller.go | 39 +++++++++++++++++-- controllers/kustomization_decryptor_test.go | 18 ++++----- controllers/kustomization_dependson_test.go | 4 +- controllers/kustomization_force_test.go | 11 ++---- controllers/kustomization_inventory_test.go | 12 +++--- controllers/kustomization_prune_test.go | 25 ++++-------- controllers/kustomization_transformer_test.go | 12 ++---- controllers/kustomization_varsub_test.go | 4 +- controllers/kustomization_wait_test.go | 4 +- controllers/suite_test.go | 16 +++++--- 10 files changed, 76 insertions(+), 69 deletions(-) diff --git a/controllers/kustomization_controller.go b/controllers/kustomization_controller.go index 46db6a54..fdf0a879 100644 --- a/controllers/kustomization_controller.go +++ b/controllers/kustomization_controller.go @@ -19,7 +19,10 @@ package controllers import ( "bytes" "context" + "crypto/sha1" + "crypto/sha256" "fmt" + "io" "net/http" "net/url" "os" @@ -296,7 +299,7 @@ func (r *KustomizationReconciler) reconcile( defer os.RemoveAll(tmpDir) // download artifact and extract files - err = r.download(source.GetArtifact().URL, tmpDir) + err = r.download(source.GetArtifact(), tmpDir) if err != nil { return kustomizev1.KustomizationNotReady( kustomization, @@ -495,7 +498,8 @@ func (r *KustomizationReconciler) checkDependencies(kustomization kustomizev1.Ku return nil } -func (r *KustomizationReconciler) download(artifactURL string, tmpDir string) error { +func (r *KustomizationReconciler) download(artifact *sourcev1.Artifact, tmpDir string) error { + artifactURL := artifact.URL if hostname := os.Getenv("SOURCE_CONTROLLER_LOCALHOST"); hostname != "" { u, err := url.Parse(artifactURL) if err != nil { @@ -521,14 +525,43 @@ func (r *KustomizationReconciler) download(artifactURL string, tmpDir string) er return fmt.Errorf("failed to download artifact from %s, status: %s", artifactURL, resp.Status) } + var buf bytes.Buffer + + // verify checksum matches origin + if err := r.verifyArtifact(artifact, &buf, resp.Body); err != nil { + return err + } + // extract - if _, err = untar.Untar(resp.Body, tmpDir); err != nil { + if _, err = untar.Untar(&buf, tmpDir); err != nil { return fmt.Errorf("failed to untar artifact, error: %w", err) } return nil } +func (r *KustomizationReconciler) verifyArtifact(artifact *sourcev1.Artifact, buf *bytes.Buffer, reader io.Reader) error { + hasher := sha256.New() + + // for backwards compatibility with source-controller v0.17.2 and older + if len(artifact.Checksum) == 40 { + hasher = sha1.New() + } + + // compute checksum + mw := io.MultiWriter(hasher, buf) + if _, err := io.Copy(mw, reader); err != nil { + return err + } + + if checksum := fmt.Sprintf("%x", hasher.Sum(nil)); checksum != artifact.Checksum { + return fmt.Errorf("failed to verify artifact: computed checksum '%s' doesn't match advertised '%s'", + checksum, artifact.Checksum) + } + + return nil +} + func (r *KustomizationReconciler) getSource(ctx context.Context, kustomization kustomizev1.Kustomization) (sourcev1.Source, error) { var source sourcev1.Source sourceNamespace := kustomization.GetNamespace() diff --git a/controllers/kustomization_decryptor_test.go b/controllers/kustomization_decryptor_test.go index 2f1d379a..43137209 100644 --- a/controllers/kustomization_decryptor_test.go +++ b/controllers/kustomization_decryptor_test.go @@ -43,16 +43,12 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) { err = createKubeConfigSecret(id) g.Expect(err).NotTo(HaveOccurred(), "failed to create kubeconfig secret") - artifactFile := "sops-" + randStringRunes(5) - artifactChecksum, err := createArtifact(testServer, "testdata/sops", artifactFile) - g.Expect(err).ToNot(HaveOccurred()) - artifactURL, err := testServer.URLForFile(artifactFile) + artifactName := "sops-" + randStringRunes(5) + artifactChecksum, err := createArtifact(testServer, "testdata/sops", artifactName) g.Expect(err).ToNot(HaveOccurred()) - overlayArtifactFile := "sops-" + randStringRunes(5) - overlayChecksum, err := createArtifact(testServer, "testdata/test-dotenv", overlayArtifactFile) - g.Expect(err).ToNot(HaveOccurred()) - overlayArtifactUrl, err := testServer.URLForFile(overlayArtifactFile) + overlayArtifactName := "sops-" + randStringRunes(5) + overlayChecksum, err := createArtifact(testServer, "testdata/test-dotenv", overlayArtifactName) g.Expect(err).ToNot(HaveOccurred()) repositoryName := types.NamespacedName{ @@ -65,10 +61,10 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) { Namespace: id, } - err = applyGitRepository(repositoryName, artifactURL, "main/"+artifactChecksum, artifactChecksum) + err = applyGitRepository(repositoryName, artifactName, "main/"+artifactChecksum) g.Expect(err).NotTo(HaveOccurred()) - err = applyGitRepository(overlayRepositoryName, overlayArtifactUrl, "main/"+overlayChecksum, overlayChecksum) + err = applyGitRepository(overlayRepositoryName, overlayArtifactName, "main/"+overlayChecksum) g.Expect(err).NotTo(HaveOccurred()) pgpKey, err := os.ReadFile("testdata/sops/pgp.asc") @@ -180,7 +176,7 @@ func TestKustomizationReconciler_Decryptor(t *testing.T) { t.Run("does not emit change events for identical secrets", func(t *testing.T) { resultK := &kustomizev1.Kustomization{} revision := "v2.0.0" - err = applyGitRepository(repositoryName, artifactURL, revision, artifactChecksum+"v2") + err = applyGitRepository(repositoryName, artifactName, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { diff --git a/controllers/kustomization_dependson_test.go b/controllers/kustomization_dependson_test.go index ba79c14d..dc6e005a 100644 --- a/controllers/kustomization_dependson_test.go +++ b/controllers/kustomization_dependson_test.go @@ -126,8 +126,6 @@ spec: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("dep-%s", randStringRunes(5)), Namespace: id, @@ -178,7 +176,7 @@ spec: }) t.Run("reconciles when source is found", func(t *testing.T) { - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { diff --git a/controllers/kustomization_force_test.go b/controllers/kustomization_force_test.go index 53ec861e..6933eeed 100644 --- a/controllers/kustomization_force_test.go +++ b/controllers/kustomization_force_test.go @@ -63,16 +63,13 @@ stringData: } artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5))) - g.Expect(err).NotTo(HaveOccurred()) - - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) repositoryName := types.NamespacedName{ Name: fmt.Sprintf("force-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -127,9 +124,8 @@ stringData: t.Run("fails to update immutable secret", func(t *testing.T) { artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5))) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) revision := "v2.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -150,9 +146,8 @@ stringData: t.Run("recreates immutable secret", func(t *testing.T) { artifact, err := testServer.ArtifactFromFiles(manifests(id, randStringRunes(5))) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) revision := "v3.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() error { diff --git a/controllers/kustomization_inventory_test.go b/controllers/kustomization_inventory_test.go index d8dc546b..3dbe1f63 100644 --- a/controllers/kustomization_inventory_test.go +++ b/controllers/kustomization_inventory_test.go @@ -75,14 +75,12 @@ stringData: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("inv-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -180,7 +178,7 @@ stringData: }) g.Expect(k8sClient.Update(context.Background(), configMapClone)).To(Succeed()) - err = applyGitRepository(repositoryName, url, testRev, "") + err = applyGitRepository(repositoryName, artifact, testRev) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -203,7 +201,7 @@ stringData: }) g.Expect(k8sClient.Update(context.Background(), configMapClone)).To(Succeed()) - err = applyGitRepository(repositoryName, url, testRev, "") + err = applyGitRepository(repositoryName, artifact, testRev) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -229,8 +227,8 @@ stringData: artifact, err := testServer.ArtifactFromFiles(manifests(testId, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - err = applyGitRepository(repositoryName, url, testRev, "") + + err = applyGitRepository(repositoryName, artifact, testRev) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { diff --git a/controllers/kustomization_prune_test.go b/controllers/kustomization_prune_test.go index d07bf337..873d7d5e 100644 --- a/controllers/kustomization_prune_test.go +++ b/controllers/kustomization_prune_test.go @@ -77,14 +77,12 @@ data: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("gc-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -134,9 +132,8 @@ data: newID := randStringRunes(5) artifact, err := testServer.ArtifactFromFiles(manifests(newID, newID)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) revision := "v2.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -208,14 +205,12 @@ data: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("gc-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -260,9 +255,9 @@ data: t.Run("deletes stale objects", func(t *testing.T) { artifact, err := testServer.ArtifactFromFiles([]testserver.File{}) g.Expect(err).NotTo(HaveOccurred()) - url = fmt.Sprintf("%s/%s", testServer.URL(), artifact) + revision = "v2.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -285,9 +280,8 @@ kind: Kustomization } artifact, err := testServer.ArtifactFromFiles(empty) g.Expect(err).NotTo(HaveOccurred()) - url = fmt.Sprintf("%s/%s", testServer.URL(), artifact) revision = "v3.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -301,9 +295,8 @@ kind: Kustomization t.Run("restores objects", func(t *testing.T) { artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url = fmt.Sprintf("%s/%s", testServer.URL(), artifact) revision = "v4.0.0" - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) g.Eventually(func() bool { @@ -356,14 +349,12 @@ data: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("gc-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ diff --git a/controllers/kustomization_transformer_test.go b/controllers/kustomization_transformer_test.go index 1eb8f3cb..f6e68bbb 100644 --- a/controllers/kustomization_transformer_test.go +++ b/controllers/kustomization_transformer_test.go @@ -53,15 +53,13 @@ func TestKustomizationReconciler_KustomizeTransformer(t *testing.T) { artifactFile := "patch-" + randStringRunes(5) artifactChecksum, err := createArtifact(testServer, "testdata/transformers", artifactFile) g.Expect(err).ToNot(HaveOccurred()) - artifactURL, err := testServer.URLForFile(artifactFile) - g.Expect(err).ToNot(HaveOccurred()) repositoryName := types.NamespacedName{ Name: fmt.Sprintf("%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, artifactURL, "main/"+artifactChecksum, artifactChecksum) + err = applyGitRepository(repositoryName, artifactFile, "main/"+artifactChecksum) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -178,15 +176,13 @@ func TestKustomizationReconciler_KustomizeTransformerFiles(t *testing.T) { artifactFile := "patch-" + randStringRunes(5) artifactChecksum, err := createArtifact(testServer, "testdata/file-transformer", artifactFile) g.Expect(err).ToNot(HaveOccurred()) - artifactURL, err := testServer.URLForFile(artifactFile) - g.Expect(err).ToNot(HaveOccurred()) repositoryName := types.NamespacedName{ Name: fmt.Sprintf("%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, artifactURL, "main/"+artifactChecksum, artifactChecksum) + err = applyGitRepository(repositoryName, artifactFile, "main/"+artifactChecksum) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ @@ -299,15 +295,13 @@ func TestKustomizationReconciler_FluxTransformers(t *testing.T) { artifactFile := "patch-" + randStringRunes(5) artifactChecksum, err := createArtifact(testServer, "testdata/patch", artifactFile) g.Expect(err).ToNot(HaveOccurred()) - artifactURL, err := testServer.URLForFile(artifactFile) - g.Expect(err).ToNot(HaveOccurred()) repositoryName := types.NamespacedName{ Name: fmt.Sprintf("%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, artifactURL, "main/"+artifactChecksum, artifactChecksum) + err = applyGitRepository(repositoryName, artifactFile, "main/"+artifactChecksum) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ diff --git a/controllers/kustomization_varsub_test.go b/controllers/kustomization_varsub_test.go index d3577538..cf06b128 100644 --- a/controllers/kustomization_varsub_test.go +++ b/controllers/kustomization_varsub_test.go @@ -66,14 +66,12 @@ metadata: artifact, err := testServer.ArtifactFromFiles(manifests(id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) configName := types.NamespacedName{ diff --git a/controllers/kustomization_wait_test.go b/controllers/kustomization_wait_test.go index d6018cf9..943ccded 100644 --- a/controllers/kustomization_wait_test.go +++ b/controllers/kustomization_wait_test.go @@ -64,14 +64,12 @@ data: artifact, err := testServer.ArtifactFromFiles(manifests(id, id)) g.Expect(err).NotTo(HaveOccurred()) - url := fmt.Sprintf("%s/%s", testServer.URL(), artifact) - repositoryName := types.NamespacedName{ Name: fmt.Sprintf("wait-%s", randStringRunes(5)), Namespace: id, } - err = applyGitRepository(repositoryName, url, revision, "") + err = applyGitRepository(repositoryName, artifact, revision) g.Expect(err).NotTo(HaveOccurred()) kustomizationKey := types.NamespacedName{ diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 26203e37..fe89e937 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -21,6 +21,7 @@ import ( "compress/gzip" "context" "crypto/sha1" + "crypto/sha256" "fmt" "io" "math/rand" @@ -205,7 +206,7 @@ func createKubeConfigSecret(namespace string) error { return k8sClient.Create(context.Background(), secret) } -func applyGitRepository(objKey client.ObjectKey, artifactURL, artifactRevision, artifactChecksum string) error { +func applyGitRepository(objKey client.ObjectKey, artifactName string, revision string) error { repo := &sourcev1.GitRepository{ TypeMeta: metav1.TypeMeta{ Kind: sourcev1.GitRepositoryKind, @@ -221,6 +222,11 @@ func applyGitRepository(objKey client.ObjectKey, artifactURL, artifactRevision, }, } + b, _ := os.ReadFile(filepath.Join(testServer.Root(), artifactName)) + checksum := fmt.Sprintf("%x", sha256.Sum256(b)) + + url := fmt.Sprintf("%s/%s", testServer.URL(), artifactName) + status := sourcev1.GitRepositoryStatus{ Conditions: []metav1.Condition{ { @@ -231,10 +237,10 @@ func applyGitRepository(objKey client.ObjectKey, artifactURL, artifactRevision, }, }, Artifact: &sourcev1.Artifact{ - Path: artifactURL, - URL: artifactURL, - Revision: artifactRevision, - Checksum: artifactChecksum, + Path: url, + URL: url, + Revision: revision, + Checksum: checksum, LastUpdateTime: metav1.Now(), }, } From e9c002cf62bb38f55c466509d2217b5f599a7bb7 Mon Sep 17 00:00:00 2001 From: Stefan Prodan Date: Fri, 12 Nov 2021 15:32:38 +0200 Subject: [PATCH 2/2] Update source-controller/api to v0.18.0 Signed-off-by: Stefan Prodan --- Makefile | 2 +- config/default/kustomization.yaml | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index 3bcc19b0..993ddf61 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ IMG ?= fluxcd/kustomize-controller:latest # Produce CRDs that work back to Kubernetes 1.16 CRD_OPTIONS ?= crd:crdVersions=v1 -SOURCE_VER ?= v0.17.2 +SOURCE_VER ?= v0.18.0 # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index 69005c63..18782fef 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -2,8 +2,8 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: kustomize-system resources: -- https://github.com/fluxcd/source-controller/releases/download/v0.17.2/source-controller.crds.yaml -- https://github.com/fluxcd/source-controller/releases/download/v0.17.2/source-controller.deployment.yaml +- https://github.com/fluxcd/source-controller/releases/download/v0.18.0/source-controller.crds.yaml +- https://github.com/fluxcd/source-controller/releases/download/v0.18.0/source-controller.deployment.yaml - ../crd - ../rbac - ../manager diff --git a/go.mod b/go.mod index 93334626..5cf21498 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/fluxcd/pkg/ssa v0.3.1 github.com/fluxcd/pkg/testserver v0.1.0 github.com/fluxcd/pkg/untar v0.1.0 - github.com/fluxcd/source-controller/api v0.17.2 + github.com/fluxcd/source-controller/api v0.18.0 github.com/go-logr/logr v0.4.0 github.com/hashicorp/go-retryablehttp v0.7.0 github.com/onsi/gomega v1.15.0 diff --git a/go.sum b/go.sum index 8b5f2950..1fc10b90 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ github.com/fluxcd/pkg/testserver v0.1.0 h1:nOYgM1HYFZNNSUFykuWDmrsxj4jQxUCvmLHWO github.com/fluxcd/pkg/testserver v0.1.0/go.mod h1:fvt8BHhXw6c1+CLw1QFZxcQprlcXzsrL4rzXaiGM+Iw= github.com/fluxcd/pkg/untar v0.1.0 h1:k97V/xV5hFrAkIkVPuv5AVhyxh1ZzzAKba/lbDfGo6o= github.com/fluxcd/pkg/untar v0.1.0/go.mod h1:aGswNyzB1mlz/T/kpOS58mITBMxMKc9tlJBH037A2HY= -github.com/fluxcd/source-controller/api v0.17.2 h1:noePJGsevuvxWols6ErbowujuAHGWb/ZO8irtRHcVAc= -github.com/fluxcd/source-controller/api v0.17.2/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo= +github.com/fluxcd/source-controller/api v0.18.0 h1:cK1uWHCujeEm9mjPPum5gogbMXOo0C6ieVZtTTxDNkY= +github.com/fluxcd/source-controller/api v0.18.0/go.mod h1:guUCCapjzE2kocwFreQTM/IGvtAglIJc4L97mokairo= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c= github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=