Skip to content

feat: simplify signing experience#579

Merged
priteshbandi merged 5 commits intonotaryproject:mainfrom
kody-kimberl:main
Mar 7, 2023
Merged

feat: simplify signing experience#579
priteshbandi merged 5 commits intonotaryproject:mainfrom
kody-kimberl:main

Conversation

@kody-kimberl
Copy link
Copy Markdown
Contributor

This PR introduces a new option for users to sign using an on-demand key. Users are able to sign without needing to add a key first

This PR intends to address the following issue: #537
Based on spec changes in #553


Successful sign/verify:

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id $IMAGE
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d

c889f3b9d811:notation kodysk$ ./bin/notation verify $IMAGE
Warning: Always verify the artifact using digest(@sha256:...) rather than a tag(:v1) because resolved digest may not point to the same signed artifact, as tags are mutable.
Successfully verified signature for localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d

Error when providing only one of the options

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin $IMAGE 
Error: incompatible options, both a key ID and plugin name are required when not using an existing key

c889f3b9d811:notation kodysk$ ./bin/notation sign --id example:test-id $IMAGE 
Error: incompatible options, both a key ID and plugin name are required when not using an existing key

Error when providing key with both plugin and id:

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id --key my-key $IMAGE 
Error: incompatible options, do not provide a key name when providing a key ID and plugin name

Error when providing key with one of the other options

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --key my-key $IMAGE 
Error: incompatible options, do not provide a key ID or plugin name when providing a key name

c889f3b9d811:notation kodysk$ ./bin/notation sign --id example:test-id --key my-key $IMAGE 
Error: incompatible options, do not provide a key ID or plugin name when providing a key name

Signed-off-by: Kody Kimberl kody.kimberl.work@gmail.com

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
fs.StringVar(p, PflagPlugin.Name, "", PflagPlugin.Usage)
}

PflagTimestamp = &pflag.Flag{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Can we please remove timestamp flag as we will not be supporting in rc3?

cc: @shizhMSFT @patrickzheng200 @yizha1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@patrickzheng200 @shizhMSFT I didn't see timestamp flag in the command line. Is it the flag that we should have removed it earlier?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dead code not referenced anywhere.

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
Copy link
Copy Markdown
Contributor Author

@kody-kimberl kody-kimberl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New commit addresses above comments. Option checking has been moved to PreRunE, and timestamp pflag has been removed.

// Construct a signer from preconfigured key pair in config.json
// if key name is provided as the CLI argument
key, err := configutil.ResolveKey(opts.Key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unnecessary empty line

if err != nil {
return nil, err
}
return signer.NewFromPlugin(plugin, opts.KeyID, map[string]string{})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a pluginConfig in SignerFlagOpts

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that pluginConfig is only in signOpts, not SignerFlagOpts.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PluginConfig in NewFromPlugin is used only when we are reading keys which includes pluginConfig from singingkeys.json then this plugin config is then merged with pluginConfig passed via CLI in Sign and Verify operation to generate final pluginConfig.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a --plugin-config flag for sign command

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is one of the options passed to sign, but it doesn't get passed via the SignerFlagOpts. The pluginConfig that is used here is intended to be the one from the key, which is later merged with the values from the pluginConfig command line option you are speaking of. That's what Pritesh was referring to above.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, got it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@priteshbandi This is what I mentioned earlier in the comments of the original issue. A user might get confused on where did the key.PluginConfig go? (Although programmatically it works exactly the same, users have to remember to add those configs in notation sign's pluginConfig now)

if opts.KeyID != "" && opts.PluginName != "" && opts.Key == "" {
// Construct a signer from on-demand key
mgr := plugin.NewCLIManager(dir.PluginFS())
plugin, err := mgr.Get(context.Background(), opts.PluginName)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the context generated in runSign() because it contains the logger.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please update line 41 to use the context from runSign()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added ctx (the context from runSign) to the function in latest commit

Comment on lines +76 to +91
if opts.KeyID != "" && opts.PluginName != "" {
if opts.Key == "" {
// Valid, use ondemand key
return nil
} else {
return errors.New("incompatible options, do not provide a key name when providing a key ID and plugin name")
}
} else if opts.KeyID == "" && opts.PluginName == "" {
// Valid, use preconfigured key
return nil
} else {
if opts.Key == "" {
return errors.New("incompatible options, both a key ID and plugin name are required when not using an existing key")
} else {
return errors.New("incompatible options, do not provide a key ID or plugin name when providing a key name")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we simplify the validation? In fact, we just need to check invalid cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines +75 to +91
// Check if the options are valid for the key (Key is mutually exclusive with [KeyID, PluginName])
if opts.KeyID != "" && opts.PluginName != "" {
if opts.Key == "" {
// Valid, use ondemand key
return nil
} else {
return errors.New("incompatible options, do not provide a key name when providing a key ID and plugin name")
}
} else if opts.KeyID == "" && opts.PluginName == "" {
// Valid, use preconfigured key
return nil
} else {
if opts.Key == "" {
return errors.New("incompatible options, both a key ID and plugin name are required when not using an existing key")
} else {
return errors.New("incompatible options, do not provide a key ID or plugin name when providing a key name")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are using the Cobra library as our CLI tool: github.com/spf13/cobra

  1. For mutual exclusive flags, we could try to use: Command.MarkFlagsMutuallyExclusive.
  2. For "Required Together" flags such as plugin and key id, we could try to use: Command.MarkFlagsRequiredTogether.

@codecov-commenter
Copy link
Copy Markdown

Codecov Report

Merging #579 (495a872) into main (55f0764) will decrease coverage by 0.34%.
The diff coverage is 0.00%.

📣 This organization is not using Codecov’s GitHub App Integration. We recommend you install it so Codecov can continue to function properly for your repositories. Learn more

@@            Coverage Diff             @@
##             main     #579      +/-   ##
==========================================
- Coverage   34.36%   34.03%   -0.34%     
==========================================
  Files          32       32              
  Lines        1848     1866      +18     
==========================================
  Hits          635      635              
- Misses       1192     1210      +18     
  Partials       21       21              
Impacted Files Coverage Δ
cmd/notation/sign.go 34.40% <0.00%> (-5.79%) ⬇️

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
Copy link
Copy Markdown
Contributor Author

@kody-kimberl kody-kimberl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Latest commit addresses above comments. Some of the error messages have changed as a result of using Cobra's functions for validation (see below). I have also added unit testing for each of the below scenarios.


Successful sign/verify:

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id $IMAGE
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d

c889f3b9d811:notation kodysk$ ./bin/notation verify $IMAGE
Warning: Always verify the artifact using digest(@sha256:...) rather than a tag(:v1) because resolved digest may not point to the same signed artifact, as tags are mutable.
Successfully verified signature for localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d

Error when providing only one of the options

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin $IMAGE 
Error: if any flags in the group [id plugin] are set they must all be set; missing [id]

c889f3b9d811:notation kodysk$ ./bin/notation sign --id example:test-id $IMAGE 
Error: if any flags in the group [id plugin] are set they must all be set; missing [plugin]

Error when providing key with one of the other options

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --key my-key $IMAGE 
Error: if any flags in the group [id plugin] are set they must all be set; missing [id]

c889f3b9d811:notation kodysk$ ./bin/notation sign --id example:test-id --key my-key $IMAGE 
Error: if any flags in the group [id plugin] are set they must all be set; missing [plugin]

Error when providing key with both plugin and id:

c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id --key my-key $IMAGE 
Error: if any flags in the group [key id] are set none of the others can be; [id key] were all set

if err != nil {
return nil, err
}
return signer.NewFromPlugin(plugin, opts.KeyID, map[string]string{})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PluginConfig in NewFromPlugin is used only when we are reading keys which includes pluginConfig from singingkeys.json then this plugin config is then merged with pluginConfig passed via CLI in Sign and Verify operation to generate final pluginConfig.

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
priteshbandi
priteshbandi previously approved these changes Mar 6, 2023
Copy link
Copy Markdown
Contributor

@priteshbandi priteshbandi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
Copy link
Copy Markdown
Contributor

@JeyJeyGao JeyJeyGao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

@patrickzheng200 patrickzheng200 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@priteshbandi priteshbandi merged commit 9b714c7 into notaryproject:main Mar 7, 2023
@yizha1 yizha1 mentioned this pull request Mar 7, 2023
3 tasks
@FeynmanZhou
Copy link
Copy Markdown
Member

FeynmanZhou commented Mar 7, 2023

Hi @kody-kimberl @priteshbandi @JeyJeyGao @patrickzheng200 ,

It seems the CLI example was not added to the CLI help info. Just a kindly reminder, when we change CLI commands and flags, we need to add or update the CLI examples in notation/cmd accordingly.

I will raise another PR to add it.

duffney pushed a commit to duffney/notation that referenced this pull request Mar 30, 2023
This PR introduces a new option for users to sign using an on-demand key. Users are able to sign without needing to add a key first.
This PR intends to address the following issue: notaryproject#537 based on spec changes in notaryproject#553

```
c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id $IMAGE
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d
```

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
Signed-off-by: Josh Duffney <jduffney@microsoft.com>
7h3-3mp7y-m4n pushed a commit to 7h3-3mp7y-m4n/notation that referenced this pull request Mar 29, 2025
This PR introduces a new option for users to sign using an on-demand key. Users are able to sign without needing to add a key first.
This PR intends to address the following issue: notaryproject#537 based on spec changes in notaryproject#553 

```
c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id $IMAGE
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d
```

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
FeynmanZhou pushed a commit to FeynmanZhou/notation that referenced this pull request May 15, 2025
This PR introduces a new option for users to sign using an on-demand key. Users are able to sign without needing to add a key first.
This PR intends to address the following issue: notaryproject#537 based on spec changes in notaryproject#553 

```
c889f3b9d811:notation kodysk$ ./bin/notation sign --plugin com.example.plugin --id example:test-id $IMAGE
Warning: Always sign the artifact using digest(@sha256:...) rather than a tag(:v1) because tags are mutable and a tag reference can point to a different artifact than the one signed.
Successfully signed localhost:5000/net-monitor@sha256:07c30edca95116e23f6a150ba3f7ed296eca71021dba9d9569eb07820f8c0e7d
```

Signed-off-by: Kody Kimberl <kody.kimberl.work@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants