Unverified Commit 10f2544e authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #55306 from hzxuzhonghu/audit

Automatic merge from submit-queue. If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Audit support resource wildcard matching **What this PR does / why we need it**: audit policy support "resource/subresources" wildcard matching "resource/*", "*/subresource","*" **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: Fixes #55305 **Special notes for your reviewer**: **Release note**: ```release-note [advanced audit] support subresources wildcard matching. ```
parents 6c91c420 08c024f3
...@@ -234,10 +234,19 @@ type GroupResources struct { ...@@ -234,10 +234,19 @@ type GroupResources struct {
// The empty string represents the core API group. // The empty string represents the core API group.
// +optional // +optional
Group string Group string
// Resources is a list of resources within the API group. Subresources are // Resources is a list of resources this rule applies to.
// matched using a "/" to indicate the subresource. For example, "pods/log" //
// would match request to the log subresource of pods. The top level resource // For example:
// does not match subresources, "pods" doesn't match "pods/log". // 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional // +optional
Resources []string Resources []string
// ResourceNames is a list of resource instance names that the policy matches. // ResourceNames is a list of resource instance names that the policy matches.
......
...@@ -122,10 +122,19 @@ message GroupResources { ...@@ -122,10 +122,19 @@ message GroupResources {
// +optional // +optional
optional string group = 1; optional string group = 1;
// Resources is a list of resources within the API group. Subresources are // Resources is a list of resources this rule applies to.
// matched using a "/" to indicate the subresource. For example, "pods/logs" //
// would match request to the logs subresource of pods. The top level resource // For example:
// does not match subresources, "pods" doesn't match "pods/logs". // 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional // +optional
repeated string resources = 2; repeated string resources = 2;
......
...@@ -241,10 +241,19 @@ type GroupResources struct { ...@@ -241,10 +241,19 @@ type GroupResources struct {
// The empty string represents the core API group. // The empty string represents the core API group.
// +optional // +optional
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
// Resources is a list of resources within the API group. Subresources are // Resources is a list of resources this rule applies to.
// matched using a "/" to indicate the subresource. For example, "pods/logs" //
// would match request to the logs subresource of pods. The top level resource // For example:
// does not match subresources, "pods" doesn't match "pods/logs". // 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional // +optional
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"` Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
// ResourceNames is a list of resource instance names that the policy matches. // ResourceNames is a list of resource instance names that the policy matches.
......
...@@ -126,10 +126,19 @@ message GroupResources { ...@@ -126,10 +126,19 @@ message GroupResources {
// +optional // +optional
optional string group = 1; optional string group = 1;
// Resources is a list of resources within the API group. Subresources are // Resources is a list of resources this rule applies to.
// matched using a "/" to indicate the subresource. For example, "pods/log" //
// would match request to the log subresource of pods. The top level resource // For example:
// does not match subresources, "pods" doesn't match "pods/log". // 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional // +optional
repeated string resources = 2; repeated string resources = 2;
......
...@@ -237,10 +237,19 @@ type GroupResources struct { ...@@ -237,10 +237,19 @@ type GroupResources struct {
// The empty string represents the core API group. // The empty string represents the core API group.
// +optional // +optional
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"` Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
// Resources is a list of resources within the API group. Subresources are // Resources is a list of resources this rule applies to.
// matched using a "/" to indicate the subresource. For example, "pods/log" //
// would match request to the log subresource of pods. The top level resource // For example:
// does not match subresources, "pods" doesn't match "pods/log". // 'pods' matches pods.
// 'pods/log' matches the log subresource of pods.
// '*' matches all resources and their subresources.
// 'pods/*' matches all subresources of pods.
// '*/scale' matches all scale subresources.
//
// If wildcard is present, the validation rule will ensure resources do not
// overlap with each other.
//
// An empty list implies all resources and subresources in this API groups apply.
// +optional // +optional
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"` Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
// ResourceNames is a list of resource instance names that the policy matches. // ResourceNames is a list of resource instance names that the policy matches.
......
...@@ -160,11 +160,11 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool ...@@ -160,11 +160,11 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
apiGroup := attrs.GetAPIGroup() apiGroup := attrs.GetAPIGroup()
resource := attrs.GetResource() resource := attrs.GetResource()
subresource := attrs.GetSubresource()
combinedResource := resource
// If subresource, the resource in the policy must match "(resource)/(subresource)" // If subresource, the resource in the policy must match "(resource)/(subresource)"
// if subresource != "" {
// TODO: consider adding options like "pods/*" to match all subresources. combinedResource = resource + "/" + subresource
if sr := attrs.GetSubresource(); sr != "" {
resource = resource + "/" + sr
} }
name := attrs.GetName() name := attrs.GetName()
...@@ -175,8 +175,17 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool ...@@ -175,8 +175,17 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
return true return true
} }
for _, res := range gr.Resources { for _, res := range gr.Resources {
if res == resource { if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) {
if len(gr.ResourceNames) == 0 || hasString(gr.ResourceNames, name) { // match "*"
if res == combinedResource || res == "*" {
return true
}
// match "*/subresource"
if len(subresource) > 0 && strings.HasPrefix(res, "*/") && subresource == strings.TrimLeft(res, "*/") {
return true
}
// match "resource/*"
if strings.HasSuffix(res, "/*") && resource == strings.TrimRight(res, "/*") {
return true return true
} }
} }
......
...@@ -105,6 +105,21 @@ var ( ...@@ -105,6 +105,21 @@ var (
Verbs: []string{"get"}, Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"pods/log"}}}, Resources: []audit.GroupResources{{Resources: []string{"pods/log"}}},
}, },
"getPodWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"*"}}},
},
"getPodResourceWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"*/log"}}},
},
"getPodSubResourceWildcardMatching": {
Level: audit.LevelRequest,
Verbs: []string{"get"},
Resources: []audit.GroupResources{{Resources: []string{"pods/*"}}},
},
"getClusterRoles": { "getClusterRoles": {
Level: audit.LevelRequestResponse, Level: audit.LevelRequestResponse,
Verbs: []string{"get"}, Verbs: []string{"get"},
...@@ -208,6 +223,9 @@ func testAuditLevel(t *testing.T, stages []audit.Stage) { ...@@ -208,6 +223,9 @@ func testAuditLevel(t *testing.T, stages []audit.Stage) {
test(t, "nonResource", audit.LevelNone, stages, stages, "getPodLogs", "getPods") test(t, "nonResource", audit.LevelNone, stages, stages, "getPodLogs", "getPods")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodLogs", "getPods") test(t, "subresource", audit.LevelRequest, stages, stages, "getPodLogs", "getPods")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodWildcardMatching")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodResourceWildcardMatching")
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodSubResourceWildcardMatching")
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment