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

UI - write without read for kv #6570

Merged
merged 19 commits into from
Apr 16, 2019
Merged

UI - write without read for kv #6570

merged 19 commits into from
Apr 16, 2019

Conversation

meirish
Copy link
Contributor

@meirish meirish commented Apr 11, 2019

This is a follow up to #5879 (comment) which allowed you to write KV v2 secret versions without being able to read secret metadata. This extends that so the forms in KV v1 and KV v2 do not need read access to the secret / version data in order to write new data, allowing you to use workflows in the UI and practice the principle of least privilege.

Our tests cover 3 scenarios:

KV v2 where you can't read the metadata or the secret version:
Screen Shot 2019-04-11 at 9 35 47 AM
Screen Shot 2019-04-11 at 9 36 06 AM

KV v2 where you can read the metadata but not the secret version:
Screen Shot 2019-04-11 at 9 36 23 AM
Screen Shot 2019-04-11 at 9 36 32 AM

KV v1 where you can't read the secret data
Screen Shot 2019-04-11 at 9 36 46 AM
Screen Shot 2019-04-11 at 9 36 58 AM

KV v2 where you can do everything except read
write-wo-read

Tool bar where you can only write
Screen Shot 2019-04-12 at 3 30 24 PM

TODO

  • clean up the toolbar on the show screens (hide the JSON toggle)
  • determine what history items are available in v2 when you can read the metadata
  • are the empty state messages and the alert banners styled properly? are the messages appropriate and helpful?

id: secret,
// so we know it's a stub model and won't be saving it
// because we don't have access to that endpoint
isStub: true,
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a way to make this more clear? isStub makes me think fake or incomplete data but doesn't make my mind go all the way to "doesn't have permission to see this"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do you have suggestions about how we might change it? It is fake / incomplete data - we need to return an object so that the template has something to render, so we create a stub model. This code path is only run if you get a 403 from the read endpoint which is what the comment is here: https://github.com/hashicorp/vault/pull/6570/files#diff-66ae76528cc7c3eea9365b29bde71ce9R112

Something like failedRead starts to cross over to the canRead canEdit, etc. properties that the model has so I could see that being confusing too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Chatted about this and will change it to failedServerRead - thanks @madalynrose !

Copy link
Contributor

@joshuaogle joshuaogle left a comment

Choose a reason for hiding this comment

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

Had a small copy question, but looks great!

@title="You do not have permission to read this secret."
@message={{if isV2
"A new version of this secret may be written but your associated policies do not allow you to read its current contents."
"Your policies permit you to overwrite the value at this path, but do not allow you to read its current one."
Copy link
Contributor

Choose a reason for hiding this comment

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

How about a slightly less technical: "Your policies permit you to overwrite this secret, but do not allow you to read this version."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we differentiate v1 and v2 ? In v1 you're going to overwrite the value, in v2 you'll create a new version.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh! I don't know why I misread that. Yeah, maybe something like "Your policies permit you to overwrite this secret, but do not allow you to read it."

{{else if @isV2}}
<AlertBanner
@type="warning"
@message="We were not able to read the current secret version to provide editing. Saving this form will create a new version of the secret and will utilize the available check-and-set mechanism."
Copy link
Contributor

Choose a reason for hiding this comment

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

I like the way you specified on the previous pages that the policies are what prevent the user from being able to read secret metadata. I think "we were not able to read metadata" is a little ambiguous -- as a user, I might see that and think there was some kind of unexpected error (vs. expected). How about something like:

"Your policies prevent you from reading and editing the current secret version. Saving this form will create a new version of the secret and will utilize the available check-and-set mechanism."

{{else}}
<AlertBanner
@type="warning"
@message="We were not able to read the current secret data. Saving using this form will overwrite the existing values."
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as above -- assuming that this warning message is only displayed when the users' policy prevents them from reading a secret, we should be explicit that it's the policy and not an unexpected server error.

'isV2',
function() {
// if the version couldn't be read from the server
if (this.isV2 && this.model.selectedVersion.failedServerRead) {
Copy link
Contributor

@andaley andaley Apr 11, 2019

Choose a reason for hiding this comment

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

Aside from the user not having read access in their policy, are there any other scenarios which would cause the version to not be read from the server? If so, my comments above regarding the alert banner warning message aren't relevant. 😝

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, it'd only be the policy missing (or an additional Sentinel policy on the path) that could prevent it.

if (err.httpStatus === 403 && (modelType === 'secret-v2' || modelType === 'secret')) {
await capabilities;
// can't read the path and don't have update permission, so re-throw
if (!capabilities.get('canUpdate') && modelType === 'secret') {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are you using the .get('canUpdate') syntax here to prevent an exception from being thrown? I thought we were able to access properties directly safely now?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch 🦅 👀 ! This is actually here because without it I got a very detailed message that I do indeed need to use get- it's one of the edge cases with native getters where ember's get is still needed because the capabilities object is a promise proxy which is a primitive ember provides. https://api.emberjs.com/ember/release/classes/PromiseProxyMixin

data-test-write-without-read-empty-message
@title="You do not have permission to read this secret."
@message={{if isV2
"A new version of this secret may be written but your associated policies do not allow you to read its current contents."
Copy link
Contributor

Choose a reason for hiding this comment

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

Also a nit, but I don't think you need the word associated here 😬

Copy link
Contributor

Choose a reason for hiding this comment

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

if you'd like, you could follow the sentence structure on line 7, like:

"Your policies permit you to write a new version of this secret, but do not allow you to read its current contents."

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Heh, not a nit at all - I also dig following a similar structure for the messages 👍

@andaley
Copy link
Contributor

andaley commented Apr 11, 2019

This is looking so good! I had a few questions/comments related to clarifying the warning and empty state messages, but no blockers. :D

Also, the screenshots and overall PR description are great. I appreciate that you included examples and requests for specific kinds of feedback -- it helps me narrow in on what to review!

@meirish meirish force-pushed the ui-write-without-read-kv branch from 1f891f1 to 7454c98 Compare April 12, 2019 22:45
@meirish meirish marked this pull request as ready for review April 12, 2019 22:49
@meirish meirish requested review from a team April 12, 2019 22:49
@meirish meirish force-pushed the ui-write-without-read-kv branch from 80800fa to 9bdb799 Compare April 13, 2019 02:43
let versionId = targetVersion ? [backend, secret, targetVersion] : [backend, secret];

// if we have the metadata, a list of versions are part of the payload
let version = secretModel.versions && secretModel.versions.findBy('version', targetVersion);
Copy link
Contributor

Choose a reason for hiding this comment

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

hmm, so i've noticed after reading through this method a few times that this is the point where i start losing track of what's happening. i know there's a lot of logic that needs to happen inside model, but i wonder if we could break some of it up either into smaller methods like getSecretModel getTargetVersion fetchVersion etc for easier legibility. if it's too difficult to set that up, i think adding comment headers above each code block would be a good alternative, especially since the existing comments you have here are so helpful. whaddya think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that's a great idea! Have an update to push 🔜. Thanks!

@meirish meirish force-pushed the ui-write-without-read-kv branch from 7b0f3f3 to 103d918 Compare April 15, 2019 20:57
@meirish meirish force-pushed the ui-write-without-read-kv branch from 103d918 to 5632943 Compare April 16, 2019 15:29
@meirish meirish merged commit e6ec125 into master Apr 16, 2019
@meirish meirish deleted the ui-write-without-read-kv branch April 16, 2019 20:27
catsby added a commit that referenced this pull request Apr 22, 2019
* master: (94 commits)
  Add type to documentation for create in token auth API (#6622)
  Merge multiple functions for creating consul containers into one. (#6612)
  Update deep to pull in default full-level-diff behavior
  Update base64 decrypt command documentation (#6614)
  Add some missing default values (#6611)
  Typo fixes (#6610)
  UI - no ember cli eslint (#6613)
  Update githook to work with go mod workflows (#6604)
  Cut version 1.1.2
  Prep for 1.1.2
  changelog++
  Add a get handler function (#6603)
  Move cluster logic out of vault package (#6601)
  Adding common prefix known issue to upgrade guide (#6575)
  changelog++
  UI - write without read for kv (#6570)
  Add known issue section to the upgrade guide (#6593)
  Update pre-push hook
  changelog++
  Fix a dropped Okta error (#6592)
  ...
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.

4 participants