From 2114b22a13000db9d0a5dc8bc77e371047574d85 Mon Sep 17 00:00:00 2001 From: Alexandr Demicev Date: Fri, 6 Dec 2024 16:09:07 +0100 Subject: [PATCH] Verify images built for upstream projects Signed-off-by: Alexandr Demicev --- README.md | 8 ++++++++ actions/verify/action.yml | 12 +++++++++++- cmd/verify.go | 31 +++++++++++++++++++++++++++---- pkg/verify/mapping.go | 4 ++++ pkg/verify/verify.go | 19 ++++++++++++------- pkg/verify/verify_test.go | 16 ++++++++++++---- 6 files changed, 74 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 347b22d..10d3eb7 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,14 @@ The cosign verification of Rancher Prime images can be done with: slsactl verify : ``` +Images built for upstream projects can be verified with(currently only Cluster API): + +```bash +slsactl verify upstream --certIdentityWorkflow= : +``` + +See Rancher Turtles docs for workflow names for respective projects. + ## License Copyright (c) 2014-2024 [Rancher Labs, Inc.](http://rancher.com) diff --git a/actions/verify/action.yml b/actions/verify/action.yml index 62ee1b3..37938f5 100644 --- a/actions/verify/action.yml +++ b/actions/verify/action.yml @@ -10,6 +10,7 @@ # - uses: rancherlabs/slsactl/actions/verify@main # with: # image: /: +# certIdentityWorkflow: name: verify @@ -20,6 +21,10 @@ inputs: //:. required: true type: string + certIdentityWorkflow: + description: | + The workflow name to run for cert identity verification(only for images built for upstream projects). + default: "" runs: using: composite @@ -37,6 +42,11 @@ runs: - name: Verify image shell: bash run: | - slsactl verify ${{ env.IMAGE }} + if [[ -n "${{ env.CERT_IDENTITY_WORKFLOW }}" ]]; then + slsactl verify upstream --certIdentityWorkflow="${{ env.CERT_IDENTITY_WORKFLOW }}" ${{ env.IMAGE }} + else + slsactl verify ${{ env.IMAGE }} + fi env: IMAGE: ${{ inputs.image }} + CERT_IDENTITY_WORKFLOW: ${{ inputs.certIdentityWorkflow }} diff --git a/cmd/verify.go b/cmd/verify.go index e99c266..6d97ebe 100644 --- a/cmd/verify.go +++ b/cmd/verify.go @@ -12,18 +12,41 @@ const verifyf = `usage: %[1]s verify ` +var ( + certIdentityWorkflow string + upstreamImageType string +) + func verifyCmd(args []string) error { f := flag.NewFlagSet("", flag.ContinueOnError) - err := f.Parse(args) - if err != nil { + + if err := f.Parse(args); err != nil { return err } - if len(f.Args()) != 1 { + if len(f.Args()) == 0 || len(f.Args()) > 3 { showVerifyUsage() } - err = verify.Verify(f.Arg(0)) + switch f.Arg(0) { + case "upstream": + f.StringVar(&certIdentityWorkflow, "certIdentityWorkflow", "", + "The workflow used to generate the certificate identity, see relevant Rancher documentation for more information.") + + f.StringVar(&upstreamImageType, "upstreamImageType", "cluster-api", + "The type of upstream image to verify, currently only 'cluster-api' is supported.") + + if err := f.Parse(args[1:]); err != nil { + return err + } + + if certIdentityWorkflow == "" { + fmt.Println("certIdentityWorkflow is required") + showVerifyUsage() + } + } + + err := verify.Verify(f.Arg(0), upstreamImageType, certIdentityWorkflow) if err != nil { fmt.Printf("cannot validate image %s: ensure you are using an image from the Prime registry\n", f.Arg(0)) } diff --git a/pkg/verify/mapping.go b/pkg/verify/mapping.go index 719458b..dd5444b 100644 --- a/pkg/verify/mapping.go +++ b/pkg/verify/mapping.go @@ -20,3 +20,7 @@ var imageRepo = map[string]string{ "rancher/nginx-ingress-controller": "rancher/ingress-nginx", "rancher/rancher": "rancher/rancher-prime", } + +var upstreamImagesRepos = map[string]string{ + "cluster-api": "rancher/clusterapi-forks", +} diff --git a/pkg/verify/verify.go b/pkg/verify/verify.go index cb0cfe1..6bb20bf 100644 --- a/pkg/verify/verify.go +++ b/pkg/verify/verify.go @@ -30,11 +30,11 @@ var archSuffixes = []string{ // // Upstream documentation: // https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md -func Verify(imageName string) error { +func Verify(imageName, upstreamImageType, workflowName string) error { ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() - certIdentity, err := certIdentity(imageName) + certIdentity, err := certIdentity(imageName, upstreamImageType, workflowName) if err != nil { return err } @@ -58,7 +58,7 @@ func Verify(imageName string) error { return v.Exec(ctx, []string{imageName}) } -func certIdentity(imageName string) (string, error) { +func certIdentity(imageName, upstreamImageType, workflowName string) (string, error) { if len(imageName) < 5 { return "", fmt.Errorf("invalid image name: %q", imageName) } @@ -92,12 +92,17 @@ func certIdentity(imageName string) (string, error) { } } - repo = overrideRepo(repo) + identity := "" - indentity := fmt.Sprintf( - "https://github.com/%s/.github/workflows/release.yml@refs/tags/%s", repo, ref) + if upstreamImageRepo, ok := upstreamImagesRepos[upstreamImageType]; ok { + identity = fmt.Sprintf( + "https://github.com/%s/.github/workflows/%s.yaml@refs/heads/main", upstreamImageRepo, workflowName) + } else { + identity = fmt.Sprintf( + "https://github.com/%s/.github/workflows/release.yml@refs/tags/%s", overrideRepo(repo), ref) + } - return indentity, nil + return identity, nil } func overrideRepo(repo string) string { diff --git a/pkg/verify/verify_test.go b/pkg/verify/verify_test.go index 73915f5..45b45fb 100644 --- a/pkg/verify/verify_test.go +++ b/pkg/verify/verify_test.go @@ -10,9 +10,11 @@ func TestCertificateIdentity(t *testing.T) { t.Parallel() tests := []struct { - image string - want string - wantErr string + image string + upstreamImageType string + workflowName string + want string + wantErr string }{ { image: "foo/bar:v0.0.7", @@ -90,6 +92,12 @@ func TestCertificateIdentity(t *testing.T) { image: "rocker.local/foo/bar:v0.0.7-build12345", want: "https://github.com/foo/bar/.github/workflows/release.yml@refs/tags/v0.0.7-build12345", }, + { + image: "foo/bar:v0.0.7", + upstreamImageType: "cluster-api", + workflowName: "bar", + want: "https://github.com/rancher/clusterapi-forks/.github/workflows/bar.yaml@refs/heads/main", + }, } for _, tc := range tests { @@ -97,7 +105,7 @@ func TestCertificateIdentity(t *testing.T) { t.Run(tc.image, func(t *testing.T) { t.Parallel() - got, err := certIdentity(tc.image) + got, err := certIdentity(tc.image, tc.upstreamImageType, tc.workflowName) assert.Equal(t, tc.want, got)