Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: OCI 1.1 support #1192

Merged
merged 4 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions cmd/notation/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation/cmd/notation/internal/display"
cmderr "github.com/notaryproject/notation/cmd/notation/internal/errors"
"github.com/notaryproject/notation/cmd/notation/internal/experimental"
"github.com/notaryproject/notation/cmd/notation/internal/option"
"github.com/notaryproject/notation/internal/cmd"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand All @@ -33,9 +32,8 @@ type inspectOpts struct {
SecureFlagOpts
option.Common
option.Format
reference string
allowReferrersAPI bool
maxSignatures int
reference string
maxSignatures int
}

func inspectCommand(opts *inspectOpts) *cobra.Command {
Expand Down Expand Up @@ -69,23 +67,18 @@ Example - Inspect signatures on an OCI artifact identified by a digest and outpu
return err
}
opts.Common.Parse(cmd)
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api")
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatures <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatures)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runInspect(cmd, opts)
},
}

opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
command.Flags().IntVar(&opts.maxSignatures, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "inspect"))

// set output format
opts.Format.ApplyFlags(command.Flags(), option.FormatTypeTree, option.FormatTypeJSON)
Expand Down
16 changes: 5 additions & 11 deletions cmd/notation/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import (
"context"
"errors"
"fmt"
"os"

notationregistry "github.com/notaryproject/notation-go/registry"
cmderr "github.com/notaryproject/notation/cmd/notation/internal/errors"
Expand All @@ -31,11 +30,10 @@ import (
type listOpts struct {
cmd.LoggingFlagOpts
SecureFlagOpts
reference string
allowReferrersAPI bool
ociLayout bool
inputType inputType
maxSignatures int
reference string
ociLayout bool
inputType inputType
maxSignatures int
}

func listCommand(opts *listOpts) *cobra.Command {
Expand Down Expand Up @@ -75,21 +73,17 @@ Example - [Experimental] List signatures of an OCI artifact identified by a tag
if opts.ociLayout {
opts.inputType = inputTypeOCILayout
}
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout")
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatures <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatures)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runList(cmd.Context(), opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "list"))
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] list signatures stored in OCI image layout")
command.Flags().IntVar(&opts.maxSignatures, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
experimental.HideFlags(command, experimentalExamples, []string{"oci-layout"})
Expand Down
4 changes: 1 addition & 3 deletions cmd/notation/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,10 @@ func getRemoteRepository(ctx context.Context, opts *SecureFlagOpts, reference st
}

if forceReferrersTag {
logger.Info("The referrers tag schema is always attempted")
logger.Info("Force to store signatures using the referrers tag schema")
if err := remoteRepo.SetReferrersCapability(false); err != nil {
return nil, err
}
} else {
logger.Info("Allowed to access the referrers API, fallback if not supported")
}
return notationregistry.NewRepository(remoteRepo), nil
}
Expand Down
15 changes: 2 additions & 13 deletions cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ type signOpts struct {
pluginConfig []string
userMetadata []string
reference string
allowReferrersAPI bool
forceReferrersTag bool
ociLayout bool
inputType inputType
Expand Down Expand Up @@ -116,7 +115,7 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
if opts.ociLayout {
opts.inputType = inputTypeOCILayout
}
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout")
},
RunE: func(cmd *cobra.Command, args []string) error {
// timestamping
Expand All @@ -129,15 +128,6 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
}
}

// allow-referrers-api flag is set
if cmd.Flags().Changed("allow-referrers-api") {
if opts.allowReferrersAPI {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions, use '--force-referrers-tag=false' instead.")
opts.forceReferrersTag = false
} else {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
}
return runSign(cmd, opts)
},
}
Expand All @@ -147,12 +137,11 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
cmd.SetPflagExpiry(command.Flags(), &opts.expiry)
cmd.SetPflagPluginConfig(command.Flags(), &opts.pluginConfig)
cmd.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, cmd.PflagUserMetadataSignUsage)
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "sign"))
command.Flags().StringVar(&opts.tsaServerURL, "timestamp-url", "", "RFC 3161 Timestamping Authority (TSA) server URL")
command.Flags().StringVar(&opts.tsaRootCertificatePath, "timestamp-root-cert", "", "filepath of timestamp authority root certificate")
cmd.SetPflagReferrersTag(command.Flags(), &opts.forceReferrersTag, "force to store signatures using the referrers tag schema")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] sign the artifact stored as OCI image layout")
command.MarkFlagsMutuallyExclusive("oci-layout", "force-referrers-tag", "allow-referrers-api")
command.MarkFlagsMutuallyExclusive("oci-layout", "force-referrers-tag")
command.MarkFlagsRequiredTogether("timestamp-url", "timestamp-root-cert")
experimental.HideFlags(command, experimentalExamples, []string{"oci-layout"})
return command
Expand Down
2 changes: 1 addition & 1 deletion cmd/notation/sign_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestSignCommand_BasicArgs(t *testing.T) {
Key: "key",
SignatureFormat: envelope.JWS,
},
forceReferrersTag: true,
forceReferrersTag: false,
}
if err := command.ParseFlags([]string{
expected.reference,
Expand Down
8 changes: 1 addition & 7 deletions cmd/notation/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ package main
import (
"errors"
"fmt"
"os"

"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/cmd/notation/internal/display"
Expand All @@ -36,7 +35,6 @@ type verifyOpts struct {
reference string
pluginConfig []string
userMetadata []string
allowReferrersAPI bool
ociLayout bool
trustPolicyScope string
inputType inputType
Expand Down Expand Up @@ -82,23 +80,19 @@ Example - [Experimental] Verify a signature on an OCI artifact identified by a t
opts.inputType = inputTypeOCILayout
}
opts.Common.Parse(cmd)
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout", "scope")
return experimental.CheckFlagsAndWarn(cmd, "oci-layout", "scope")
},
RunE: func(cmd *cobra.Command, args []string) error {
if opts.maxSignatureAttempts <= 0 {
return fmt.Errorf("max-signatures value %d must be a positive number", opts.maxSignatureAttempts)
}
if cmd.Flags().Changed("allow-referrers-api") {
fmt.Fprintln(os.Stderr, "Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.")
}
return runVerify(cmd, opts)
},
}
opts.LoggingFlagOpts.ApplyFlags(command.Flags())
opts.SecureFlagOpts.ApplyFlags(command.Flags())
command.Flags().StringArrayVar(&opts.pluginConfig, "plugin-config", nil, "{key}={value} pairs that are passed as it is to a plugin, if the verification is associated with a verification plugin, refer plugin documentation to set appropriate values")
cmd.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, cmd.PflagUserMetadataVerifyUsage)
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "verify"))
command.Flags().IntVar(&opts.maxSignatureAttempts, "max-signatures", 100, "maximum number of signatures to evaluate or examine")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] verify the artifact stored as OCI image layout")
command.Flags().StringVar(&opts.trustPolicyScope, "scope", "", "[Experimental] set trust policy scope for artifact verification, required and can only be used when flag \"--oci-layout\" is set")
Expand Down
11 changes: 1 addition & 10 deletions internal/cmd/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,11 @@ var (
fs.StringArrayVarP(p, PflagUserMetadata.Name, PflagUserMetadata.Shorthand, nil, usage)
}

PflagReferrersAPI = &pflag.Flag{
Name: "allow-referrers-api",
}
PflagReferrersUsageFormat = "[Experimental] use the Referrers API to %s signatures, if not supported (returns 404), fallback to the Referrers tag schema"
SetPflagReferrersAPI = func(fs *pflag.FlagSet, p *bool, usage string) {
fs.BoolVar(p, PflagReferrersAPI.Name, false, usage)
fs.MarkHidden(PflagReferrersAPI.Name)
}

PflagReferrersTag = &pflag.Flag{
Name: "force-referrers-tag",
}
SetPflagReferrersTag = func(fs *pflag.FlagSet, p *bool, usage string) {
fs.BoolVar(p, PflagReferrersTag.Name, true, usage)
fs.BoolVar(p, PflagReferrersTag.Name, false, usage)
}
)

Expand Down
3 changes: 1 addition & 2 deletions specs/commandline/sign.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Usage:
notation sign [flags] <reference>

Flags:
--force-referrers-tag force to store signatures using the referrers tag schema (default true)
--force-referrers-tag force to store signatures using the referrers tag schema
-d, --debug debug mode
-e, --expiry duration optional expiry that provides a "best by use" time for the artifact. The duration is specified in minutes(m) and/or hours(h). For example: 12h, 30m, 3h20m
-h, --help help for sign
Expand Down Expand Up @@ -205,7 +205,6 @@ export NOTATION_EXPERIMENTAL=1
notation list --oci-layout hello-world@sha256:xxx
```

[oci-artifact-manifest]: https://github.com/opencontainers/image-spec/blob/v1.1.0-rc2/artifact.md
[oci-image-spec]: https://github.com/opencontainers/image-spec/blob/v1.1.0/spec.md
[oci-referers-api]: https://github.com/opencontainers/distribution-spec/blob/v1.1.0/spec.md#listing-referrers
[oci-image-layout]: https://github.com/opencontainers/image-spec/blob/v1.1.0/image-layout.md
34 changes: 0 additions & 34 deletions test/e2e/suite/command/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,40 +131,6 @@ var _ = Describe("notation inspect", func() {
})
})

It("sign with --allow-referrers-api set", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(inspectSuccessfully...)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(inspectSuccessfully...)
})
})

It("sign with --allow-referrers-api set to false", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api=false", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(inspectSuccessfully...)

notation.Exec("inspect", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(inspectSuccessfully...)
})
})

It("with timestamping", func() {
Host(BaseOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--timestamp-url", "http://rfc3161timestamp.globalsign.com/advanced", "--timestamp-root-cert", filepath.Join(NotationE2EConfigPath, "timestamp", "globalsignTSARoot.cer"), artifact.ReferenceWithDigest()).
Expand Down
46 changes: 0 additions & 46 deletions test/e2e/suite/command/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,50 +111,4 @@ var _ = Describe("notation list", func() {
)
})
})

It("sign with --allow-referrers-api set", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("list", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)

notation.Exec("list", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)
})
})

It("sign with --allow-referrers-api set to false", func() {
Host(BaseOptionsWithExperimental(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", "--allow-referrers-api=false", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

notation.Exec("list", artifact.ReferenceWithDigest(), "-v").
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)

notation.Exec("list", artifact.ReferenceWithDigest(), "--allow-referrers-api", "-v").
MatchErrKeyWords(
"Warning: This feature is experimental and may not be fully tested or completed and may be deprecated.",
"Warning: flag '--allow-referrers-api' is deprecated and will be removed in future versions.",
).
MatchKeyWords(
"└── application/vnd.cncf.notary.signature",
"└── sha256:",
)
})
})
})
Loading
Loading