-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
SSH secrets engine - Enabled creation of key pairs (CA Mode) #15561
SSH secrets engine - Enabled creation of key pairs (CA Mode) #15561
Conversation
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.
Looking like a great start @Gabrielopesantos!
A few nits here and there around how validation of type/bits parameters occurs, that's tricky but expected :-) In retrospect, I really made that more complicated than I intended to.
You might be able to refactor the existing logic into taking a keyType/keyBits parameter and hoisting the type/bits extraction to a separate method.
And regarding your comment:
Also, for now everything is in a single function but I could also refactor the existing
pathSignCertificate
to support this new case.
I think I'd maybe take the common logic (124 and down in the new implementation?) and refactor it to a shared call. So three functions (pathSignCertificate
, pathIssueCertificate
, and perhaps pathSignIssueCertificateHelper
or something of the sort).
Just a thought. :-)
Also, as a heads up, this likely won't make RC1 milestone for 1.11 which means it'll likely be slated for 1.12, in case you were wondering :-)
Hello @cipherboy, There are two files What is the behavior expected if no value are defined? Currently, the |
I'm fine with either an error or an implicit default. If the goal is to make the call as simple as possible to make then the default works. |
Hello, added a few tests which should cover which should the implementation of this new endpoint, as most of it is reusing the existing Also, while testing found something that I am not sure if it expected. I defined a |
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 looks like rather clean, well-written code! The refactor I think helped a fair bit here. I think most of these are rather minor nits.
Oh and a change log entry :-)
Hello @cipherboy, made a commit that addresses both comments and proposes a solution for this #15561 (comment) . There are a few things that still need to be addressed such as help messages, error messages, organizing functions in correct files and creating the changelog. Let me know if am forgetting anything. |
Hey @Gabrielopesantos Sorry for the delay in getting back to this. I think you need to run |
No worries, I know this improvement is set for a 1.12.*** milestone so isn't a priority. I did not include 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.
Love the refactor! I'll have a colleague check this out before merging though.
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.
Overall this is really great! I have some small nits but nothing preventing this from merging.
An api documentation update is required for this change though, if you do not feel comfortable writing the updated documentation, we can handle that in a separate PR.
ErrorOk: true, | ||
// Returns like nil, err break this | ||
Check: func(resp *logical.Response) error { | ||
if expectError { |
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.
Because ErrorOk is set to true above, this check function should perhaps validate that resp is not in an error state when expectError is false? At least it would help to diagnose test failures if we returned the error in resp if it was unexpected?
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.
Thank you for the feedback, I agree with the suggestion. Would something like the following after the if expectError
block be enough to handle it?
if resp.Error() != nil {
return fmt.Errorf("unexpected error response returned: %v", resp.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.
Yup that's perfect, just an FYI the following is a little more common (but don't bother changing it)
if resp.IsError() {
return fmt.Errorf("unexpected error response returned: %v", resp.Error())
}
builtin/logical/ssh/backend_test.go
Outdated
} | ||
|
||
if resp.Data["private_key_type"] != keyType { | ||
return errors.New("private key type does not match provided key_type") |
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: Could we include expected vs actual within this error please to again help to diagnose future test failures?
// them as 4xx values | ||
keyID, err := b.calculateKeyID(data, req, role, publicKey) | ||
if err != nil { | ||
return logical.ErrorResponse(err.Error()), 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.
nit: It's a tad odd that we return an error response and an err, should we not be consistent and return nil, 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.
Not to nitpick your nitpick, but this was just a copy/paste refactor of the existing code:
vault/builtin/logical/ssh/path_sign.go
Lines 125 to 128 in 7c72d9d
keyID, err := b.calculateKeyID(data, req, role, userPublicKey) | |
if err != nil { | |
return logical.ErrorResponse(err.Error()), nil | |
} |
And worst, it seems consistently used that way.
Never mind, I agree that returning both the formatted stuff and the err is weird. I'd return one or the other like the existing code did.
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.
Actually there is a behavior change here, as the callers are wrapping any error into a logical.ErrorResponse so some existing error scenarios we did return a 500 will be switched to a 400.
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.
Also makes sense, I remember making this change during development because was having some kind of error. The latest commit reverts these returns to how they were initially (also not consistent). If consistency in the return statements is what we are looking for, I can make the change to return nil, err
as suggested.
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.
Thanks! What you have changed it too, reverting to what it was, is the correct approach, much appreciated.
Co-authored-by: Alexander Scheel <[email protected]>
Pushed a commit with possible fixes to the suggestions made, let me know if there is anything that still should be altered. Regarding the documentation, is it setting up the documentation for the endpoint, like this https://www.vaultproject.io/api-docs/secret/pki#generate-certificate but for the |
Correct the file to update would be https://github.com/hashicorp/vault/blob/main/website/content/api-docs/secret/ssh.mdx, adding a new section for the new api endpoint added. It should include a short description, parameters, sample payload, request and response sections as well. |
Pushed a commit with the documentation proposal, it is basically a copy of the existing endpoint (with some minor changes), not sure if it enough or might require extra information. I think I also found an issue with a previous PR (made by me), the documentation of the |
This looks excellent @Gabrielopesantos! Going to go ahead and merge this, and I'll get a fix opened for that docs change you noted (needs to be a separate PR as it goes back to 1.11) :) |
…7694) Extend the documentation the API endpoint '/ssh/issue/:name' (added in #15561 with v1.12.0) and '/ssh/issue/:name': - Be more specific that the issued certificate uses the defaults given of the role at the given endpoint; and that it is subject to the limitations configured in this role. - Note that the endpoint /ssh/issue/:name is available with v1.12+. - Make it more clear that the generated credentials are only returned but not stored by Vault (not just the generated private key).
Description
Issue: #10879
Created a new endpoint (/ssh/issue/:name) that does not take a public_key (as /ssh/sign/:name does), and instead generates a new public/private key pair internally which is returned in the response.