-
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
Log auth info on permission denied due to ACL #2754
Conversation
vault/core.go
Outdated
// Check the standard non-root ACLs. Return the token entry if it's not | ||
// allowed so we can decrement the use count. | ||
allowed, rootPrivs := acl.AllowOperation(req) | ||
if !allowed { | ||
return nil, te, logical.ErrPermissionDenied | ||
return auth, te, logical.ErrPermissionDenied |
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.
Can we add a comment here explaining the need to return the auth
object even when the operation is not allowed?
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.
Sure. I've got another push coming to add populating the token and accessor fields in the auth object as well. (see latest comments on #2741) I'll include that in the push.
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.
LGTM!
@vishalnayak Pushed your requested change along with changes to populate the ClientToken (hmac'd) and Accessor fields that were always blank before. Per the discussion on #2741, left the existing fields in the request object. |
New sample output with the latest change. Also populated metadata on my test token to show that gets logged as well: Normal:
Permission denied:
|
Oops, didn't run tests. Fix coming. |
DisplayName: auth.DisplayName, | ||
Policies: auth.Policies, | ||
Metadata: auth.Metadata, | ||
RemainingUses: req.ClientTokenRemainingUses, |
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 we had omitted the ClientTokenRemainingUses in the response intentionally. @jefferai What do you think?
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.
Sure, let me know. I can pull it back out (and maybe add a comment noting the inconsistency is intentional). In the meantime, pushed a fix for the tests that failed, including adding some additional fields.
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 we had too. At the moment I don't remember the context around it; it may be in comments in the PR that introduced that 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.
Sorry for the noise. I couldn't find such a conversation in the earlier PR (#2437). On a second thought, this is looking fine to me.
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.
So leave it in as I have it, then?
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.
Yep
7fda0b0
to
ac83133
Compare
@jefferai Anything else you need from me on this? No major rush, just wanted to cross it off my to-do list. I noticed we'd diverged and had some conflicts, so I've rebased and updated the test code a little to reflect the move of the salt init. |
I'm seeing test failures on things that I don't think are related to my change:
|
@bkrodgers I'm not super thrilled with this PR, so I was holding off while thinking about it. It goes way beyond "parity for failed requests" and adds a lot of extra fields. Some of them we specifically didn't add before and I've been trying to remember why. Some of them have the potential to be very, very verbose, and seriously balloon the size of audit log. |
So the main thing I want out of this PR is to see display name, policies, and metadata on actions denied by ACL. The other parts to fill out the existing token fields that weren't being populated under any circumstance (but were always part of the log entry) and the token count one were just efforts to sync things up. I'd be happy to pull them out if those are the parts you're concerned about. |
Metadata can be very, very large. It's one of my main concerns. In theory display name can, too. What is the use-case here? I have a couple in mind, but want to know yours... |
Keep in mind that all this PR changes for metadata and display-name is to write those values in the scenario where a user tries access something but is denied by ACL. The metadata and display-name values are already being logged in every successful request. So I don't see the concern with additional size. 99% of the audit log entries will already have these values in them. My use case for wanting it on ACL denied entries is that even if they are denied, if someone is frequently trying to access something their policies don't allow them to access, I may want to follow up with them. Once their token expires, I can't use the accessor to pull that info, and it's much easier to work with if it's right there in the audit log anyway. But again, this only adds that data in that one narrow case. I do have plenty of other cases where it already is logging this info that I wouldn't want to see go away. If you're concerned these are already taking up too much space in the audit log and are thinking about removing them, that would be very problematic. Having permanent and integrated access (as in not based on token lifetime, and not needing to look it up outside the logging tool) in the audit log to info about who performed operations is a core function of the audit log to me. It is true, however, that I'm adding data to every log entry with the addition of the code to populate |
Huh. I didn't know that. That's unfortunate, although I guess for your use-case it's an enabling reason.
Dude, give us a little credit. You've been around long enough :-) |
@@ -171,7 +171,7 @@ func (c *Core) handleRequest(req *logical.Request) (retResp *logical.Response, r | |||
if errType != nil { | |||
retErr = multierror.Append(retErr, errType) | |||
} | |||
return logical.ErrorResponse(ctErr.Error()), nil, retErr | |||
return logical.ErrorResponse(ctErr.Error()), auth, retErr |
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 don't believe this change is necessary.
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.
It is necessary to get it to log the info in the response entry as well. In the case of an error, including the ACL error scenario I'm trying to address here, the auth object from this return statement then gets passed to c.auditBroker.LogResponse
on line 107.
Ah, ok. I figured I was missing something there. Basically: I really dislike this PR, but 99.9% of that comes from the fact that I really wish I could change a lot about the structure of the audit logs, so anything that adds more information on top of what's there (making it even more impossible to change later) just makes me super duper sad. But it is a sadness I will have to deal with because it is a sailed ship. |
Yeah, I hear ya. No question the audit log structure could be cleaner. Maybe someday you can add a "v2" format and default new audit backend mounts to it, leaving current backend mounts on "v1." |
Vault's HTTP API is in even more need of that, but it's not an easy thing to foist on people. |
Oh I know, I've been on both sides of that. You know I'm always happy to help provide any feedback on such changes though! |
Fixes #2741.
Test case (depends on jq for ease of reading, remove if you want):
Result:
Without this PR, the
auth
object for the second pair of req/resp would be missing info such as display name and policies that are important for determining who was denied access and why.