-
Notifications
You must be signed in to change notification settings - Fork 511
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
notary key generate
shouldn't be restricted to root keys
#1134
notary key generate
shouldn't be restricted to root keys
#1134
Conversation
4b2a686
to
4070365
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a great addition :) I have a few UX concerns but I'm excited that this is being added.
@@ -14,10 +14,13 @@ import ( | |||
store "github.com/docker/notary/storage" | |||
"github.com/docker/notary/trustmanager" | |||
"github.com/docker/notary/tuf/data" | |||
tufutils "github.com/docker/notary/tuf/utils" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in other packages this is tufUtils
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did a search in the project, it's consistently tufutils
(all lower case)
cmd/notary/keys.go
Outdated
@@ -38,7 +41,7 @@ var cmdRotateKeyTemplate = usageTemplate{ | |||
Long: `Generates a new key for the given Globally Unique Name and role (one of "snapshot", "targets", "root", or "timestamp"). If rotating to a server-managed key, a new key is requested from the server rather than generated. If the generation or key request is successful, the key rotation is immediately published. No other changes, even if they are staged, will be published.`, | |||
} | |||
|
|||
var cmdKeyGenerateRootKeyTemplate = usageTemplate{ | |||
var cmdKeyGenerateKeyTemplate = usageTemplate{ | |||
Use: "generate [ algorithm ]", | |||
Short: "Generates a new root key with a given algorithm.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should update the description
cmd.AddCommand(cmdKeyGenerateRootKeyTemplate.ToCommand(k.keysGenerateRootKey)) | ||
cmdGenerate := cmdKeyGenerateKeyTemplate.ToCommand(k.keysGenerate) | ||
cmdGenerate.Flags().StringVarP( | ||
&k.outFile, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should --output
only output the public key? Or at least have different flags for pub/priv out?
I'm just thinking about the case where you're storing in a yubikey but still want the public part output to a file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to work in tandem with the PR to update notary add
which allows keys to be provided on the CLI. My expectation is this would be used to generate delegation keys, which at the moment is a pain as they have to be generated with OpenSSL.
@@ -159,7 +170,7 @@ func (k *keyCommander) keysList(cmd *cobra.Command, args []string) error { | |||
return nil | |||
} | |||
|
|||
func (k *keyCommander) keysGenerateRootKey(cmd *cobra.Command, args []string) error { | |||
func (k *keyCommander) keysGenerate(cmd *cobra.Command, args []string) error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this take a role
now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The command functions have a set signature required to meet one of the Cobra interfaces. It can't be changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right! I meant as one of the command args, which you took care of.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah sorry, misunderstood!
cmd/notary/keys.go
Outdated
} | ||
cs := cryptoservice.NewCryptoService(ks...) | ||
|
||
pubKey, err := cs.Create(data.CanonicalRootRole, "", algorithm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the UX is a little confusing - it generates a root key if no output is defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I wasn't sure about how to handle that. I didn't want to add a flag while I was uncertain about whether we'd be following up the PKCS#8 stuff with a PR to remove roles and guns from the PEMs.
Having seen how people use Notary, and have trouble using Notary, one of the things I wanted to discuss at DockerCon was how much we try to farm out some of the data management. We're not doing any special with keys so would it be more obvious for users if we just made them manage their own keys? Key management right now is almost too magic... We'd still need integrations for things like Yubikeys, but maybe a user would provide CLI args saying "Use Slot 3", rather than all the automatic detection we do right now.
51c1203
to
a18a003
Compare
@endophage this looks good to me if there's an extra test or two coming |
23acee6
to
78d6438
Compare
@ecordell test added to cover the new functionality. |
cmd/notary/keys.go
Outdated
"storage (e.g. a Yubikey) is available, the key will be stored both " + | ||
"on hardware and on disk (so that it can be backed up). Please make " + | ||
"sure to back up and then remove this on-key disk immediately" + | ||
"afterwards. If a `--output` file name is provided, two files will " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-blocking grammar nit: Maybe something like: "If the --output
flag is provided, two files will be written to disk relative to the current working directory (as opposed to in Notary's default on-disk key storage): the public key as <output>.pub
and a private key as <output>.priv
."?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If --output
is absolute is won't be relative to the cwd :-P I didn't want to get into the intricacies and was relying on user general knowledge of CLI tools to make sensible assumptions about providing paths to a tool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that still may be the term, though. If you give something a relative link, it's relative to X, but absolute is always just absolute. I totally understand why we may want to leave that part out, though.
But would it make sense to include the rest of the above? I just mainly wanted to directly state that the extensions will be appended to whatever output file name the user gives us.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can rephrase to make that clearer
Since there are no restrictions on which roles can be used for Also, could we add one more test for generating a delegation key without passing |
cmd/notary/keys.go
Outdated
|
||
// if we had an outfile set, we'll write 2 files with the given name, appending .pub and .priv for the | ||
// public and private keys respectively | ||
return generateKeyToFile(k.generateRole, algorithm, k.getRetriever(), k.outFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to only write the keys to a file, but does not store the key in the yubikey, if it's available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh is that what the key will not be stored in Notary's key storage
means? Neither the key storage disk or the yubikey? Could we clarify that in the docstring for the command? I thought providing an outfile would back up the keys to a different location, but also write to the yubikey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it only outputs to the provided file and doesn't store it anywhere else. I'm trying to reduce the magic of the commands. It would still be possible to subsequently notary key import
to load the key in to a yubikey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At some point, not in this PR, I wonder if it'd make sense to just generate the key directly in the yubikey if available unless --output
is provided (no backups - the output
can be your backup, since we've had issues where folks would prefer not having the key anywhere else).
78d6438
to
911ffa0
Compare
@cyli it came up in the PCKS#8 PR, I think GUNs in the key PEMs are going to be deprecated. Especially as keys are used across repos it become less relevant. |
That makes sense, thanks |
911ffa0
to
296c3bd
Compare
@endophage Are we expecting that this PR allows non-root keys to be imported into the yubikey? |
I wasn't planning on doing that here. |
@endophage Er sorry, not import, but that the generated non-root keys will be stored in the yubikey? I think if so, we may need to remove https://github.com/docker/notary/blob/master/trustmanager/yubikey/yubikeystore.go#L704, because currently generated keys that aren't root won't get stored in the yubikey. If not, and the plan is to do that in another PR, could we please update the description and maybe the CLI description for key generation to say that for easier change tracking? |
Same answer, wasn't planning to make any changes to the yubikey logic in this PR. |
@endophage This LGTM with the caveat of updating the CLI docstring to make it clear that only root keys will be generated and put into the yubikey for now. I know the next one is probably coming soon, but if it gets delayed or if we have a release between this one and when that one comes, it may be confusing for users who may expect otherwise. |
cmd/notary/keys.go
Outdated
Long: "Generates a new root key with a given algorithm. If hardware key storage (e.g. a Yubikey) is available, the key will be stored both on hardware and on disk (so that it can be backed up). Please make sure to back up and then remove this on-key disk immediately afterwards.", | ||
Short: "Generates a new key with a given algorithm.", | ||
Long: "Generates a new key with a given algorithm. If hardware key " + | ||
"storage (e.g. a Yubikey) is available, the key will be stored both " + |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposed amendment:
Generates a new key with a given algorithm. If the key is a root key and hardware key storage (e.g. a Yubikey) is available...
cmd/notary/keys.go
Outdated
|
||
pubKey, err := cs.Create(data.RoleName(k.generateRole), "", algorithm) | ||
if err != nil { | ||
return fmt.Errorf("Failed to create a new root key: %v", err) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/"root key"/k.generateRole
} | ||
cs := cryptoservice.NewCryptoService(ks...) | ||
|
||
pubKey, err := cs.Create(data.RoleName(k.generateRole), "", algorithm) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is empty GUN intended? I noticed a comment about GUNs in PEMs being potentially deprecated but lost track if it was referring to this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be necessary for the "templating", right?
Perhaps this PR should remove the GUN checks when parsing PEM files, too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think but I'm not certain we have those checks in a few scattered places. With the PRs coming in for providing certs and keys on the CLI, I'd rather hold off on making those changes here to keep potential conflicts down.
cmd/notary/keys.go
Outdated
return errors.New("no password provided") | ||
} | ||
|
||
privFile := strings.Join([]string{outFile, "priv"}, ".") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we should use .key
instead, so that manually moving the key and importing should just work? .priv
is conceptually fine with me, just that I'd like to add a notary key import
test for it if we want to keep it that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the cfssl defaults are:
private: <name>-key.pem
public: <name>.pem
which seems reasonable to me, though I don't have a strong preference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy to go with the cfssl filenames for consistency.
To clarify my approval: LGTM after @riyazdf's comments are addressed Excited to see this in! This is a solid UX improvement. |
c7a45bb
to
b97f9ee
Compare
cmd/notary/keys.go
Outdated
return nil | ||
} | ||
|
||
// if we had an outfile set, we'll write 2 files with the given name, appending .pub and .priv for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: this should be .pem
and -key.pem
cmd/notary/keys_test.go
Outdated
@@ -30,6 +30,7 @@ import ( | |||
"github.com/docker/notary/trustpinning" | |||
"github.com/docker/notary/tuf/data" | |||
"github.com/docker/notary/tuf/utils" | |||
"path/filepath" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: can we put this import into the first block?
require.NoError(t, err) | ||
assertNumKeys(t, tempDir, 0, 1, false) // key shouldn't be written to store and won't show up in keylist | ||
|
||
// test that we can read the keys we created |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we additionally test a key rotate
and/or key import
to check that the notary CLI can ingest the key directly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test for import.
jenkins, test this please |
Signed-off-by: David Lawrence <[email protected]> (github: endophage)
Signed-off-by: David Lawrence <[email protected]> (github: endophage)
b97f9ee
to
ade502a
Compare
@rubenmachuca FYI - you might have posted some personal information on a comment you left here. I've deleted the original comment, please reach out (my email is in my signoffs) if you have additional questions |
It also gains the
-o
/--output
flag, which if provided will cause the public and private key to be output to the filepath specified in the flag with the .pub and .priv file extensions respectively.Signed-off-by: David Lawrence [email protected] (github: endophage)