-
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
CreateOperation should only be implemented alongside ExistenceCheck #18492
Conversation
Closes hashicorp#12329 Vault treats all POST or PUT HTTP requests equally - they default to being treated as UpdateOperations, but, if a backend implements an ExistenceCheck function, CreateOperations can be separated out when the existence check returns false. It follows, then, that if a CreateOperation handler is implemented without an ExistenceCheck function, this is unreachable code - a coding error. It's a fairly minor error in the grand scheme of things, but it causes the generated OpenAPI spec to include x-vault-createSupported for operations on which create can never actually be invoked - and promotes muddled understanding of the create/update feature. In this PR: 1) Implement a new test, which checks all builtin auth methods and secrets engines can be successfully initialized. (This is important to validate the next part.) 2) Expand upon the existing coding error checks built in to framework.Backend, adding a check for this misuse of CreateOperation. 3) Fix up instances of improper CreateOperation within the Vault repository - just two, transit and mock. Note: At this point, the newly added test will **fail**. There are improper uses of CreateOperation in all of the following: vault-plugin-auth-cf vault-plugin-auth-kerberos vault-plugin-auth-kubernetes vault-plugin-secrets-ad vault-plugin-secrets-gcpkms vault-plugin-secrets-kubernetes vault-plugin-secrets-kv vault-plugin-secrets-openldap vault-plugin-secrets-terraform each of which needs to be fixed and updated in go.mod here, before this new check can be added.
@maxb is attempting to deploy a commit to the HashiCorp Team on Vercel. A member of the Team first needs to authorize it. |
That concludes the 9 PRs in other plugin repositories that go along with this change. |
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.
From a crypto side, I'm fine with this change. I do note that nominally the permissions will be different, but am otherwise leaving this and the rest of the changes to Ecosystem's and Core's reviews.
As far as I know, I don't think there's any way for this to catch out users, because via the HTTP API, there's no way to submit a request which is explicitly a CreateOperation - it's just a POST/PUT, and without an ExistenceCheck to evaluate it, it will always be categorised as an UpdateOperation - therefore the code being removed here has always been inaccessible to users. Some users will have written ACL policies mentioning the ...unless you can see any flaw in the reasoning? |
No, you're sharper than I am this morning. I seem to have forgotten to update the existence check for Transit when adding the no-create option. I was thinking that if an ACL provided Create permissions (with or without an existence check) but not an Update permission, a user would always get a Create operation, but this isn't true; its strictly on the existence check itself. |
I wonder if adding the Instead of testing for invalid path configurations, we could enforce the |
I don't agree about it being the correct setup, at least not in the general case, as in many of these, CreateOperations have been specified for paths for which the create operation is semantically meaningless - for example:
It may be there are some individual operations within this PR set where separating create and update semantics could potentially be useful, but that would need to be assessed on a case by case basis, taking into account the need to prominently notify users that they may need to update their ACL policies (as access which would previously have been authorized by As currently written, this PR set aims to avoid all user-facing compatibility issues. Though, it does not rule out further future changes to introduce separated |
I don't follow ... I'm already enforcing that in this PR. |
Excellent, I didn't catch that bit. |
We're going to take a look at this change in our upcoming team meeting, especially since the change affects numerous backends. |
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 good. I added some suggestions that should be addressed.
// Detect the coding error of attempting to define a CreateOperation without defining an ExistenceCheck | ||
if p.ExistenceCheck == nil { | ||
if _, ok := p.Operations[logical.CreateOperation]; ok { | ||
panic(fmt.Sprintf("Pattern %v defines a CreateOperation but no ExistenceCheck", p.Pattern)) |
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.
We shouldn't be panicking in production code. Perhaps the panic should be conditional during testing. Also it would be good to log a warning in all cases.
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.
Whilst I agree that it's a very bad thing to panic as a way to report runtime failure conditions, this code is different:
-
It's a compile time constant condition - either the Backend paths config has been set up in a way which is considered bad, or not, and if it is triggered, the only fix is to recompile the code.
-
It's consistent with the two other pre-existing checks that conditionally panic in this function already - the detection of empty patterns, and the detection of patterns which are invalid regexps (by way of the use of MustCompile).
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.
@ncabatoff Are you fine with the panic?
I've added the subtests, and responded on why I think it is appropriate to use panic here. |
This is a surprisingly complicated special case
…nvocations of the builtin backends too
) * CreateOperation should only be implemented alongside ExistenceCheck See hashicorp/vault#18492 * Remove CreateOperation cases in tests too
) * CreateOperation should only be implemented alongside ExistenceCheck See hashicorp/vault#18492 * Change CreateOperation to UpdateOperation in tests, too
Note, this IS an upgrade despite the apparent version numbers going down. (That's a consequence of slightly odd release management occurring in the plugin repositories.)
Would anyone from HashiCorp be able to assist with getting hashicorp/vault-plugin-secrets-terraform#16 merged? That is the last of the 9 prerequisite PRs that is not yet merged. |
) * CreateOperation should only be implemented alongside ExistenceCheck See hashicorp/vault#18492 * A follow-up to removing incorrect CreateOperation usage It turns out the pathRolesWrite function contained dedicated conditionals to deal with CreateOperation, ignoring the fact it never had an ExistenceCheck, so this code path could never be reached! Prune away the unused code, and also update the tests.
@maxb hashicorp/vault-plugin-secrets-terraform#16 has been approved and merged. Thanks! |
This PR is currently waiting for the version of vault-plugin-secrets-kubernetes in Vault to be upgraded to v0.4.0 or later. |
Hi @benashz , @cipherboy , Thank you for reviewing this PR in the past. All the related changes have finally made it through the journey of being merged into plugin repositories, and the plugins upgraded in the Vault repo. This PR is now a candidate to be actually merged, if you're able to give it another look? |
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.
Looks good to me from Vault Core's perspective.
@maxb @mpalmi @miagilepner It looks like the activity counters needs to be updated, at least as of this last run date:
It looks like its still a valid test failure: vault/vault/logical_system_activity_write_testonly.go Lines 29 to 45 in 3ca3397
Maybe it should be moved to |
…dpoint By being hidden behind a Go build constraint, it had evaded notice until now.
Ah, this has eluded the regular testing since it is not compiled unless a build constraint is set. Updated. |
Hi @benashz , @ncabatoff , Would one (or both!) of you be able to respond to the open question in the thread above #18492 (review), which is AFAIK the only thing holding this back from being merged ? It concerns the correctness of reporting incorrect coding via panic. I put forward the case that it is fine, because:
Thanks! |
I think your reasoning on the panic makes perfect sense @maxb and I've spoken with Nick out of band and he agreed. I think this is ready to merge as others have already approved the code changes. |
Closes #12329
Vault treats all POST or PUT HTTP requests equally - they default to being treated as UpdateOperations, but, if a backend implements an ExistenceCheck function, CreateOperations can be separated out when the existence check returns false.
It follows, then, that if a CreateOperation handler is implemented without an ExistenceCheck function, this is unreachable code - a coding error. It's a fairly minor error in the grand scheme of things, but it causes the generated OpenAPI spec to include x-vault-createSupported for operations on which create can never actually be invoked - and promotes muddled understanding of the create/update feature.
In this PR:
Implement a new test, which checks all builtin auth methods and
secrets engines can be successfully initialized. (This is important
to validate the next part.)
Expand upon the existing coding error checks built in to
framework.Backend, adding a check for this misuse of CreateOperation.
Fix up instances of improper CreateOperation within the Vault
repository - just two, transit and mock.
Note: At this point, the newly added test will fail.
There are improper uses of CreateOperation in all of the following:
each of which needs to be fixed and updated in go.mod here, before this new check can be added.