diff --git a/cluster/gce/gci/audit_policy_test.go b/cluster/gce/gci/audit_policy_test.go index 3ea6f54b416..bd9a553f7ff 100644 --- a/cluster/gce/gci/audit_policy_test.go +++ b/cluster/gce/gci/audit_policy_test.go @@ -117,8 +117,8 @@ func TestCreateMasterAuditPolicy(t *testing.T) { ) at := auditTester{ - T: t, - checker: auditpolicy.NewChecker(policy), + T: t, + evaluator: auditpolicy.NewPolicyRuleEvaluator(policy), } at.testResources(none, kubeproxy, "watch", endpoints, sysEndpoints, services, serviceStatus) @@ -162,7 +162,7 @@ func TestCreateMasterAuditPolicy(t *testing.T) { type auditTester struct { *testing.T - checker auditpolicy.Checker + evaluator auditpkg.PolicyRuleEvaluator } func (t *auditTester) testResources(level audit.Level, usrVerbRes ...interface{}) { @@ -229,9 +229,9 @@ func (t *auditTester) expectLevel(expected audit.Level, attrs authorizer.Attribu } } name := fmt.Sprintf("%s.%s.%s", attrs.GetUser().GetName(), attrs.GetVerb(), obj) - checker := t.checker + evaluator := t.evaluator t.Run(name, func(t *testing.T) { - level, stages := checker.LevelAndStages(attrs) + level, stages := evaluator.LevelAndStages(attrs) assert.Equal(t, expected, level) if level != audit.LevelNone { assert.ElementsMatch(t, stages, []audit.Stage{audit.StageRequestReceived}) diff --git a/staging/src/k8s.io/apiserver/pkg/audit/evaluator.go b/staging/src/k8s.io/apiserver/pkg/audit/evaluator.go new file mode 100644 index 00000000000..4319e050dd0 --- /dev/null +++ b/staging/src/k8s.io/apiserver/pkg/audit/evaluator.go @@ -0,0 +1,28 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package audit + +import ( + "k8s.io/apiserver/pkg/apis/audit" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +// PolicyRuleEvaluator exposes methods for evaluating the policy rules. +type PolicyRuleEvaluator interface { + // Check the audit level for a request with the given authorizer attributes. + LevelAndStages(authorizer.Attributes) (audit.Level, []audit.Stage) +} diff --git a/staging/src/k8s.io/apiserver/pkg/audit/policy/checker.go b/staging/src/k8s.io/apiserver/pkg/audit/policy/checker.go index e9a901abf64..26ce7825f05 100644 --- a/staging/src/k8s.io/apiserver/pkg/audit/policy/checker.go +++ b/staging/src/k8s.io/apiserver/pkg/audit/policy/checker.go @@ -20,6 +20,7 @@ import ( "strings" "k8s.io/apiserver/pkg/apis/audit" + auditinternal "k8s.io/apiserver/pkg/audit" "k8s.io/apiserver/pkg/authorization/authorizer" ) @@ -28,18 +29,12 @@ const ( DefaultAuditLevel = audit.LevelNone ) -// Checker exposes methods for checking the policy rules. -type Checker interface { - // Check the audit level for a request with the given authorizer attributes. - LevelAndStages(authorizer.Attributes) (audit.Level, []audit.Stage) -} - -// NewChecker creates a new policy checker. -func NewChecker(policy *audit.Policy) Checker { +// NewPolicyRuleEvaluator creates a new policy rule evaluator. +func NewPolicyRuleEvaluator(policy *audit.Policy) auditinternal.PolicyRuleEvaluator { for i, rule := range policy.Rules { policy.Rules[i].OmitStages = unionStages(policy.OmitStages, rule.OmitStages) } - return &policyChecker{*policy} + return &policyRuleEvaluator{*policy} } func unionStages(stageLists ...[]audit.Stage) []audit.Stage { @@ -56,16 +51,17 @@ func unionStages(stageLists ...[]audit.Stage) []audit.Stage { return result } -// FakeChecker creates a checker that returns a constant level for all requests (for testing). -func FakeChecker(level audit.Level, stage []audit.Stage) Checker { - return &fakeChecker{level, stage} +// NewFakePolicyRuleEvaluator creates a fake policy rule evaluator that returns +// a constant level for all requests (for testing). +func NewFakePolicyRuleEvaluator(level audit.Level, stage []audit.Stage) auditinternal.PolicyRuleEvaluator { + return &fakePolicyRuleEvaluator{level, stage} } -type policyChecker struct { +type policyRuleEvaluator struct { audit.Policy } -func (p *policyChecker) LevelAndStages(attrs authorizer.Attributes) (audit.Level, []audit.Stage) { +func (p *policyRuleEvaluator) LevelAndStages(attrs authorizer.Attributes) (audit.Level, []audit.Stage) { for _, rule := range p.Rules { if ruleMatches(&rule, attrs) { return rule.Level, rule.OmitStages @@ -209,11 +205,11 @@ func hasString(slice []string, value string) bool { return false } -type fakeChecker struct { +type fakePolicyRuleEvaluator struct { level audit.Level stage []audit.Stage } -func (f *fakeChecker) LevelAndStages(_ authorizer.Attributes) (audit.Level, []audit.Stage) { +func (f *fakePolicyRuleEvaluator) LevelAndStages(_ authorizer.Attributes) (audit.Level, []audit.Stage) { return f.level, f.stage } diff --git a/staging/src/k8s.io/apiserver/pkg/audit/policy/checker_test.go b/staging/src/k8s.io/apiserver/pkg/audit/policy/checker_test.go index d1818ef69d4..b08a917c7aa 100644 --- a/staging/src/k8s.io/apiserver/pkg/audit/policy/checker_test.go +++ b/staging/src/k8s.io/apiserver/pkg/audit/policy/checker_test.go @@ -185,7 +185,7 @@ func test(t *testing.T, req string, expLevel audit.Level, policyStages, expOmitS policy.Rules = append(policy.Rules, rules[rule]) } require.Contains(t, attrs, req) - actualLevel, actualOmitStages := NewChecker(&policy).LevelAndStages(attrs[req]) + actualLevel, actualOmitStages := NewPolicyRuleEvaluator(&policy).LevelAndStages(attrs[req]) assert.Equal(t, expLevel, actualLevel, "request:%s rules:%s", req, strings.Join(ruleNames, ",")) assert.True(t, stageEqual(expOmitStages, actualOmitStages), "request:%s rules:%s, expected stages: %v, actual stages: %v", req, strings.Join(ruleNames, ","), expOmitStages, actualOmitStages) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go index 15855d18fae..3f0ee9c5c74 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/apiserver_test.go @@ -286,9 +286,9 @@ func handleInternal(storage map[string]rest.Storage, admissionControl admission. // simplified long-running check return requestInfo.Verb == "watch" || requestInfo.Verb == "proxy" } - fakeChecker := auditpolicy.FakeChecker(auditinternal.LevelRequestResponse, nil) - handler := genericapifilters.WithAudit(mux, auditSink, fakeChecker, longRunningCheck) - handler = genericapifilters.WithRequestDeadline(handler, auditSink, fakeChecker, longRunningCheck, codecs, 60*time.Second) + fakeRuleEvaluator := auditpolicy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + handler := genericapifilters.WithAudit(mux, auditSink, fakeRuleEvaluator, longRunningCheck) + handler = genericapifilters.WithRequestDeadline(handler, auditSink, fakeRuleEvaluator, longRunningCheck, codecs, 60*time.Second) handler = genericapifilters.WithRequestInfo(handler, testRequestInfoResolver()) return &defaultAPIServer{handler, container} diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit.go index 02f57909ef0..ecee6600f19 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit.go @@ -30,7 +30,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/audit" - "k8s.io/apiserver/pkg/audit/policy" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/request" ) @@ -39,7 +38,7 @@ import ( // requests coming to the server. Audit level is decided according to requests' // attributes and audit policy. Logs are emitted to the audit sink to // process events. If sink or audit policy is nil, no decoration takes place. -func WithAudit(handler http.Handler, sink audit.Sink, policy policy.Checker, longRunningCheck request.LongRunningRequestCheck) http.Handler { +func WithAudit(handler http.Handler, sink audit.Sink, policy audit.PolicyRuleEvaluator, longRunningCheck request.LongRunningRequestCheck) http.Handler { if sink == nil || policy == nil { return handler } @@ -117,7 +116,7 @@ func WithAudit(handler http.Handler, sink audit.Sink, policy policy.Checker, lon // - context with audit event attached to it // - created audit event // - error if anything bad happened -func createAuditEventAndAttachToContext(req *http.Request, policy policy.Checker) (*http.Request, *auditinternal.Event, []auditinternal.Stage, error) { +func createAuditEventAndAttachToContext(req *http.Request, policy audit.PolicyRuleEvaluator) (*http.Request, *auditinternal.Event, []auditinternal.Stage, error) { ctx := req.Context() attribs, err := GetAuthorizerAttributes(ctx) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_annotations.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_annotations.go index 22b276991c6..6a885711f03 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_annotations.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_annotations.go @@ -20,14 +20,13 @@ import ( "net/http" "k8s.io/apiserver/pkg/audit" - "k8s.io/apiserver/pkg/audit/policy" ) // WithAuditAnnotations decorates a http.Handler with a []{key, value} that is merged // with the audit.Event.Annotations map. This allows layers that run before WithAudit // (such as authentication) to assert annotations. // If sink or audit policy is nil, no decoration takes place. -func WithAuditAnnotations(handler http.Handler, sink audit.Sink, policy policy.Checker) http.Handler { +func WithAuditAnnotations(handler http.Handler, sink audit.Sink, policy audit.PolicyRuleEvaluator) http.Handler { // no need to wrap if auditing is disabled if sink == nil || policy == nil { return handler diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_test.go index e326712e14c..ea7e940a0b7 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/audit_test.go @@ -668,8 +668,8 @@ func TestAudit(t *testing.T) { } { t.Run(test.desc, func(t *testing.T) { sink := &fakeAuditSink{} - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, test.omitStages) - handler := WithAudit(http.HandlerFunc(test.handler), sink, policyChecker, func(r *http.Request, ri *request.RequestInfo) bool { + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, test.omitStages) + handler := WithAudit(http.HandlerFunc(test.handler), sink, fakeRuleEvaluator, func(r *http.Request, ri *request.RequestInfo) bool { // simplified long-running check return ri.Verb == "watch" }) @@ -738,8 +738,8 @@ func TestAudit(t *testing.T) { } func TestAuditNoPanicOnNilUser(t *testing.T) { - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - handler := WithAudit(&fakeHTTPHandler{}, &fakeAuditSink{}, policyChecker, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + handler := WithAudit(&fakeHTTPHandler{}, &fakeAuditSink{}, fakeRuleEvaluator, nil) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req = withTestContext(req, nil, nil) req.RemoteAddr = "127.0.0.1" @@ -752,8 +752,8 @@ func TestAuditLevelNone(t *testing.T) { handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(200) }) - policyChecker := policy.FakeChecker(auditinternal.LevelNone, nil) - handler = WithAudit(handler, sink, policyChecker, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelNone, nil) + handler = WithAudit(handler, sink, fakeRuleEvaluator, nil) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req.RemoteAddr = "127.0.0.1" @@ -807,9 +807,8 @@ func TestAuditIDHttpHeader(t *testing.T) { handler = http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(200) }) - policyChecker := policy.FakeChecker(test.level, nil) - - handler = WithAudit(handler, sink, policyChecker, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(test.level, nil) + handler = WithAudit(handler, sink, fakeRuleEvaluator, nil) handler = WithAuditID(handler) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit.go index 2de13f74706..550a2f25b29 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit.go @@ -26,13 +26,12 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/audit" - "k8s.io/apiserver/pkg/audit/policy" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" ) // WithFailedAuthenticationAudit decorates a failed http.Handler used in WithAuthentication handler. // It is meant to log only failed authentication requests. -func WithFailedAuthenticationAudit(failedHandler http.Handler, sink audit.Sink, policy policy.Checker) http.Handler { +func WithFailedAuthenticationAudit(failedHandler http.Handler, sink audit.Sink, policy audit.PolicyRuleEvaluator) http.Handler { if sink == nil || policy == nil { return failedHandler } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit_test.go index 08a38224a1f..88419301642 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authn_audit_test.go @@ -30,12 +30,12 @@ import ( func TestFailedAuthnAudit(t *testing.T) { sink := &fakeAuditSink{} - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) handler := WithFailedAuthenticationAudit( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", http.StatusUnauthorized) }), - sink, policyChecker) + sink, fakeRuleEvaluator) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req.RemoteAddr = "127.0.0.1" req = withTestContext(req, nil, nil) @@ -62,12 +62,12 @@ func TestFailedAuthnAudit(t *testing.T) { func TestFailedMultipleAuthnAudit(t *testing.T) { sink := &fakeAuditSink{} - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) handler := WithFailedAuthenticationAudit( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", http.StatusUnauthorized) }), - sink, policyChecker) + sink, fakeRuleEvaluator) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req.RemoteAddr = "127.0.0.1" req = withTestContext(req, nil, nil) @@ -95,12 +95,12 @@ func TestFailedMultipleAuthnAudit(t *testing.T) { func TestFailedAuthnAuditWithoutAuthorization(t *testing.T) { sink := &fakeAuditSink{} - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) handler := WithFailedAuthenticationAudit( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", http.StatusUnauthorized) }), - sink, policyChecker) + sink, fakeRuleEvaluator) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req.RemoteAddr = "127.0.0.1" req = withTestContext(req, nil, nil) @@ -126,12 +126,12 @@ func TestFailedAuthnAuditWithoutAuthorization(t *testing.T) { func TestFailedAuthnAuditOmitted(t *testing.T) { sink := &fakeAuditSink{} - policyChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, []auditinternal.Stage{auditinternal.StageResponseStarted}) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, []auditinternal.Stage{auditinternal.StageResponseStarted}) handler := WithFailedAuthenticationAudit( http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { http.Error(w, "", http.StatusUnauthorized) }), - sink, policyChecker) + sink, fakeRuleEvaluator) req, _ := http.NewRequest("GET", "/api/v1/namespaces/default/pods", nil) req.RemoteAddr = "127.0.0.1" req = withTestContext(req, nil, nil) diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline.go index cc4997968a1..1df8e5b5514 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline.go @@ -31,7 +31,6 @@ import ( utilruntime "k8s.io/apimachinery/pkg/util/runtime" auditinternal "k8s.io/apiserver/pkg/apis/audit" "k8s.io/apiserver/pkg/audit" - "k8s.io/apiserver/pkg/audit/policy" "k8s.io/apiserver/pkg/endpoints/handlers/responsewriters" "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/klog/v2" @@ -47,12 +46,12 @@ const ( // auditWrapper provides an http.Handler that audits a failed request. // longRunning returns true if he given request is a long running request. // requestTimeoutMaximum specifies the default request timeout value. -func WithRequestDeadline(handler http.Handler, sink audit.Sink, policy policy.Checker, longRunning request.LongRunningRequestCheck, +func WithRequestDeadline(handler http.Handler, sink audit.Sink, policy audit.PolicyRuleEvaluator, longRunning request.LongRunningRequestCheck, negotiatedSerializer runtime.NegotiatedSerializer, requestTimeoutMaximum time.Duration) http.Handler { return withRequestDeadline(handler, sink, policy, longRunning, negotiatedSerializer, requestTimeoutMaximum, utilclock.RealClock{}) } -func withRequestDeadline(handler http.Handler, sink audit.Sink, policy policy.Checker, longRunning request.LongRunningRequestCheck, +func withRequestDeadline(handler http.Handler, sink audit.Sink, policy audit.PolicyRuleEvaluator, longRunning request.LongRunningRequestCheck, negotiatedSerializer runtime.NegotiatedSerializer, requestTimeoutMaximum time.Duration, clock utilclock.PassiveClock) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { ctx := req.Context() @@ -104,7 +103,7 @@ func withRequestDeadline(handler http.Handler, sink audit.Sink, policy policy.Ch // withFailedRequestAudit decorates a failed http.Handler and is used to audit a failed request. // statusErr is used to populate the Message property of ResponseStatus. -func withFailedRequestAudit(failedHandler http.Handler, statusErr *apierrors.StatusError, sink audit.Sink, policy policy.Checker) http.Handler { +func withFailedRequestAudit(failedHandler http.Handler, statusErr *apierrors.StatusError, sink audit.Sink, policy audit.PolicyRuleEvaluator) http.Handler { if sink == nil || policy == nil { return failedHandler } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline_test.go index 55ff4a8f035..856e443e506 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/request_deadline_test.go @@ -177,8 +177,8 @@ func TestWithRequestDeadline(t *testing.T) { }) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - withDeadline := WithRequestDeadline(handler, fakeSink, fakeChecker, + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + withDeadline := WithRequestDeadline(handler, fakeSink, fakeRuleEvaluator, func(_ *http.Request, _ *request.RequestInfo) bool { return test.longRunning }, newSerializer(), requestTimeoutMaximum) withDeadline = WithRequestInfo(withDeadline, &fakeRequestResolver{}) @@ -230,8 +230,8 @@ func TestWithRequestDeadlineWithClock(t *testing.T) { fakeClock := utilclock.NewFakeClock(receivedTimestampExpected) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - withDeadline := withRequestDeadline(handler, fakeSink, fakeChecker, + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + withDeadline := withRequestDeadline(handler, fakeSink, fakeRuleEvaluator, func(_ *http.Request, _ *request.RequestInfo) bool { return false }, newSerializer(), time.Minute, fakeClock) withDeadline = WithRequestInfo(withDeadline, &fakeRequestResolver{}) @@ -259,8 +259,8 @@ func TestWithRequestDeadlineWithFailedRequestIsAudited(t *testing.T) { }) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - withDeadline := WithRequestDeadline(handler, fakeSink, fakeChecker, + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + withDeadline := WithRequestDeadline(handler, fakeSink, fakeRuleEvaluator, func(_ *http.Request, _ *request.RequestInfo) bool { return false }, newSerializer(), time.Minute) withDeadline = WithRequestInfo(withDeadline, &fakeRequestResolver{}) @@ -295,8 +295,8 @@ func TestWithRequestDeadlineWithPanic(t *testing.T) { }) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - withDeadline := WithRequestDeadline(handler, fakeSink, fakeChecker, + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + withDeadline := WithRequestDeadline(handler, fakeSink, fakeRuleEvaluator, func(_ *http.Request, _ *request.RequestInfo) bool { return false }, newSerializer(), 1*time.Minute) withDeadline = WithRequestInfo(withDeadline, &fakeRequestResolver{}) withPanicRecovery := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { @@ -332,8 +332,8 @@ func TestWithRequestDeadlineWithRequestTimesOut(t *testing.T) { }) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) - withDeadline := WithRequestDeadline(handler, fakeSink, fakeChecker, + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) + withDeadline := WithRequestDeadline(handler, fakeSink, fakeRuleEvaluator, func(_ *http.Request, _ *request.RequestInfo) bool { return false }, newSerializer(), 1*time.Minute) withDeadline = WithRequestInfo(withDeadline, &fakeRequestResolver{}) @@ -380,9 +380,9 @@ func TestWithFailedRequestAudit(t *testing.T) { }) fakeSink := &fakeAuditSink{} - fakeChecker := policy.FakeChecker(auditinternal.LevelRequestResponse, nil) + fakeRuleEvaluator := policy.NewFakePolicyRuleEvaluator(auditinternal.LevelRequestResponse, nil) - withAudit := withFailedRequestAudit(errorHandler, test.statusErr, fakeSink, fakeChecker) + withAudit := withFailedRequestAudit(errorHandler, test.statusErr, fakeSink, fakeRuleEvaluator) w := httptest.NewRecorder() testRequest, err := http.NewRequest(http.MethodGet, "/apis/v1/namespaces/default/pods", nil) diff --git a/staging/src/k8s.io/apiserver/pkg/server/config.go b/staging/src/k8s.io/apiserver/pkg/server/config.go index d068c7e0c4c..f99d0ca1c51 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config.go @@ -41,7 +41,6 @@ import ( "k8s.io/apimachinery/pkg/version" "k8s.io/apiserver/pkg/admission" "k8s.io/apiserver/pkg/audit" - auditpolicy "k8s.io/apiserver/pkg/audit/policy" "k8s.io/apiserver/pkg/authentication/authenticator" "k8s.io/apiserver/pkg/authentication/authenticatorfactory" authenticatorunion "k8s.io/apiserver/pkg/authentication/request/union" @@ -135,8 +134,8 @@ type Config struct { Version *version.Info // AuditBackend is where audit events are sent to. AuditBackend audit.Backend - // AuditPolicyChecker makes the decision of whether and how to audit log a request. - AuditPolicyChecker auditpolicy.Checker + // AuditPolicyRuleEvaluator makes the decision of whether and how to audit log a request. + AuditPolicyRuleEvaluator audit.PolicyRuleEvaluator // ExternalAddress is the host name to use for external (public internet) facing URLs (e.g. Swagger) // Will default to a value based on secure serving info and available ipv4 IPs. ExternalAddress string @@ -772,11 +771,11 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { handler = filterlatency.TrackStarted(handler, "impersonation") handler = filterlatency.TrackCompleted(handler) - handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyChecker, c.LongRunningFunc) + handler = genericapifilters.WithAudit(handler, c.AuditBackend, c.AuditPolicyRuleEvaluator, c.LongRunningFunc) handler = filterlatency.TrackStarted(handler, "audit") failedHandler := genericapifilters.Unauthorized(c.Serializer) - failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyChecker) + failedHandler = genericapifilters.WithFailedAuthenticationAudit(failedHandler, c.AuditBackend, c.AuditPolicyRuleEvaluator) failedHandler = filterlatency.TrackCompleted(failedHandler) handler = filterlatency.TrackCompleted(handler) @@ -789,13 +788,13 @@ func DefaultBuildHandlerChain(apiHandler http.Handler, c *Config) http.Handler { // context with deadline. The go-routine can keep running, while the timeout logic will return a timeout to the client. handler = genericfilters.WithTimeoutForNonLongRunningRequests(handler, c.LongRunningFunc) - handler = genericapifilters.WithRequestDeadline(handler, c.AuditBackend, c.AuditPolicyChecker, + handler = genericapifilters.WithRequestDeadline(handler, c.AuditBackend, c.AuditPolicyRuleEvaluator, c.LongRunningFunc, c.Serializer, c.RequestTimeout) handler = genericfilters.WithWaitGroup(handler, c.LongRunningFunc, c.HandlerChainWaitGroup) if c.SecureServing != nil && !c.SecureServing.DisableHTTP2 && c.GoawayChance > 0 { handler = genericfilters.WithProbabilisticGoaway(handler, c.GoawayChance) } - handler = genericapifilters.WithAuditAnnotations(handler, c.AuditBackend, c.AuditPolicyChecker) + handler = genericapifilters.WithAuditAnnotations(handler, c.AuditBackend, c.AuditPolicyRuleEvaluator) handler = genericapifilters.WithWarningRecorder(handler) handler = genericapifilters.WithCacheControl(handler) handler = genericfilters.WithHSTS(handler, c.HSTSDirectives) diff --git a/staging/src/k8s.io/apiserver/pkg/server/config_test.go b/staging/src/k8s.io/apiserver/pkg/server/config_test.go index 532cf49d3d4..b04e018510a 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/config_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/config_test.go @@ -289,9 +289,9 @@ func TestAuthenticationAuditAnnotationsDefaultChain(t *testing.T) { }) backend := &testBackend{} c := &Config{ - Authentication: AuthenticationInfo{Authenticator: authn}, - AuditBackend: backend, - AuditPolicyChecker: policy.FakeChecker(auditinternal.LevelMetadata, nil), + Authentication: AuthenticationInfo{Authenticator: authn}, + AuditBackend: backend, + AuditPolicyRuleEvaluator: policy.NewFakePolicyRuleEvaluator(auditinternal.LevelMetadata, nil), // avoid nil panics HandlerChainWaitGroup: &waitgroup.SafeWaitGroup{}, diff --git a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go index a35163649d7..fde8e8eb08f 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/options/audit.go +++ b/staging/src/k8s.io/apiserver/pkg/server/options/audit.go @@ -289,8 +289,8 @@ func (o *AuditOptions) ApplyTo( return fmt.Errorf("server config must be non-nil") } - // 1. Build policy checker - checker, err := o.newPolicyChecker() + // 1. Build policy evaluator + evaluator, err := o.newPolicyRuleEvaluator() if err != nil { return err } @@ -302,7 +302,7 @@ func (o *AuditOptions) ApplyTo( return err } if w != nil { - if checker == nil { + if evaluator == nil { klog.V(2).Info("No audit policy file provided, no events will be recorded for log backend") } else { logBackend = o.LogOptions.newBackend(w) @@ -312,7 +312,7 @@ func (o *AuditOptions) ApplyTo( // 3. Build webhook backend var webhookBackend audit.Backend if o.WebhookOptions.enabled() { - if checker == nil { + if evaluator == nil { klog.V(2).Info("No audit policy file provided, no events will be recorded for webhook backend") } else { if c.EgressSelector != nil { @@ -343,8 +343,8 @@ func (o *AuditOptions) ApplyTo( dynamicBackend = o.WebhookOptions.TruncateOptions.wrapBackend(webhookBackend, groupVersion) } - // 5. Set the policy checker - c.AuditPolicyChecker = checker + // 5. Set the policy rule evaluator + c.AuditPolicyRuleEvaluator = evaluator // 6. Join the log backend with the webhooks c.AuditBackend = appendBackend(logBackend, dynamicBackend) @@ -355,7 +355,7 @@ func (o *AuditOptions) ApplyTo( return nil } -func (o *AuditOptions) newPolicyChecker() (policy.Checker, error) { +func (o *AuditOptions) newPolicyRuleEvaluator() (audit.PolicyRuleEvaluator, error) { if o.PolicyFile == "" { return nil, nil } @@ -364,7 +364,7 @@ func (o *AuditOptions) newPolicyChecker() (policy.Checker, error) { if err != nil { return nil, fmt.Errorf("loading audit policy file: %v", err) } - return policy.NewChecker(p), nil + return policy.NewPolicyRuleEvaluator(p), nil } func (o *AuditBatchOptions) AddFlags(pluginName string, fs *pflag.FlagSet) { diff --git a/test/integration/examples/webhook_test.go b/test/integration/examples/webhook_test.go index b16973e2d25..2592902d3d5 100644 --- a/test/integration/examples/webhook_test.go +++ b/test/integration/examples/webhook_test.go @@ -52,7 +52,7 @@ func TestWebhookLoopback(t *testing.T) { // Hook into audit to watch requests config.GenericConfig.AuditBackend = auditSinkFunc(func(events ...*auditinternal.Event) {}) - config.GenericConfig.AuditPolicyChecker = auditChecker(func(attrs authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) { + config.GenericConfig.AuditPolicyRuleEvaluator = auditPolicyRuleEvaluator(func(attrs authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) { if attrs.GetPath() == webhookPath { if attrs.GetUser().GetName() != "system:apiserver" { t.Errorf("expected user %q, got %q", "system:apiserver", attrs.GetUser().GetName()) @@ -106,9 +106,9 @@ func TestWebhookLoopback(t *testing.T) { } } -type auditChecker func(authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) +type auditPolicyRuleEvaluator func(authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) -func (f auditChecker) LevelAndStages(attrs authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) { +func (f auditPolicyRuleEvaluator) LevelAndStages(attrs authorizer.Attributes) (auditinternal.Level, []auditinternal.Stage) { return f(attrs) }