-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
platformmanagement_public_704: Added basic auditing capabilities #8815
Conversation
if len(namespace) != 0 { | ||
usernamespace = fmt.Sprintf("%s@%s", user.GetName(), namespace) | ||
} | ||
glog.Infof("%s - %s - %v", req.Method, usernamespace, req.URL) |
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 print the user as well?
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 do, it's in the form user@namespace
, or just user
when no namespace is there. See the sample code which shows test-admin@openshift
.
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'd like to suggest a standard prefix for all audit statements so they're easy to parse out of the log with a grep rather than finding all info messages. Maybe "AUDIT: <field>:%s,<field>:%s, ...">
. Adding the field name in there will probably also save us a bit of explanation for those trying to parse it. @soltysh WDYT?
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 had that, but then I figured out I'd go with audit.go
file name which will do just that 😄 Field names sgtm.
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.
Again, see the sample line ;)
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 want something machine parsable. %q
does escaping, right?
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.
How good an audit trail is this supposed to be? Do we need query params?
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 had that, but then I figured out I'd go with audit.go file name which will do just that Field names sgtm.
That is dependent on a particular glog formatting choice, which is theoretically changable. I'd pay for the extra characters in this method.
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.
How good an audit trail is this supposed to be? Do we need query params?
it couldn't hurt to have URL.RawQuery
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.
You'll want to track if this is an impersonation request.
Comments addressed, now the log consists of two lines, (request, response) (@pweil & @danmcp for you two especially 😉):
Samples from my logs (without glog prefixes):
@deads2k ptal as well |
this LGTM for the basics. @smarterclayton anything you'd like to see added? |
} | ||
id := uuid.NewRandom().String() | ||
|
||
glog.Infof("AUDIT: %s: ip:%s, method:%s, username:%s, namespace: %s, uri:%v", |
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.
You either need to add an AUDIT message in the impersonation filter using the same UID (obviously you'd have to attach it to the context) or this needs to understand the impersonation annotation.
The current state is as follows:
Format:
Sample logs:
system:admin as test-admin:
@deads2k @smarterclayton need your final singoff |
@@ -164,6 +164,8 @@ func (c *MasterConfig) Run(protected []APIInstaller, unprotected []APIInstaller) | |||
handler := c.versionSkewFilter(safe) | |||
handler = c.authorizationFilter(handler) | |||
handler = c.impersonationFilter(handler) | |||
// audit handler must comes before the impersonationFilter to read the original user | |||
handler = c.auditHandler(handler) |
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.
@deads2k that surprises me, I thought the handler order is FIFO, but from what I've tested it's LIFO.
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.
@deads2k that surprises me, I thought the handler order is FIFO, but from what I've tested it's LIFO.
One handler wraps another. I don't think you can build it the other way around.
minor comments. I don't need a second look. |
Comments addressed. One bug found on the way (see upstream pr). @smarterclayton merge at will. |
user, _ := kapi.UserFrom(ctx) | ||
asuser := req.Header.Get(authenticationapi.ImpersonateUserHeader) | ||
if len(asuser) == 0 { | ||
asuser = "<himself>" |
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 little weird - I would say <self>
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.
+1
… the host:port format
} | ||
id := uuid.NewRandom().String() | ||
|
||
glog.Infof("AUDIT: %s: ip:%v, method:%s, user:%q, as:%q, namespace:%s, uri:%v", |
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 needs to be greppable, I would recommend the following:
Infof("AUDIT: id=%q ip=%q method=%q user=%q as=%q namespace=%q uri=%q")
That ensures that each segment is wellformed and can be safely deconstructed later. I do not like adding unescaped values, since this is going to be assumed to be machine readable.
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.
%q will allow you to safely quote escaped strings.
fe1dd7e
to
193e57c
Compare
Sample logs: as
as user:
@smarterclayton ptal |
To be consistent response should be in quotes as well. |
@smarterclayton quoted response, as requested. |
Lgtm [merge] thanks On May 12, 2016, at 4:49 PM, Maciej Szulik notifications@github.com wrote: @smarterclayton https://github.com/smarterclayton quoted response, as — |
continuous-integration/openshift-jenkins/merge SUCCESS (https://ci.openshift.redhat.com/jenkins/job/merge_pull_requests_origin/5904/) (Image: devenv-rhel7_4185) |
Tests are broken On May 12, 2016, at 8:20 PM, OpenShift Bot notifications@github.com wrote: continuous-integration/openshift-jenkins/merge FAILURE ( — |
Evaluated for origin merge up to 9d872ad |
bummer... 😊 |
This implements basic audit capabilities as described in this trello.
The only thing is there's no log from the response, I'd have to do it completely differently to get it.
Sample log looks like this:
and is enabled with following config option:
@openshift/api-review for api changes
@pweil- @danmcp ptal
@mpbarrett fyi