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. ``` Kubernetes-commit: 10f2544ec80e176faad73c5025d7c16ffb8284b4
This commit is contained in:
commit
4d11630801
|
@ -234,10 +234,19 @@ type GroupResources struct {
|
|||
// The empty string represents the core API group.
|
||||
// +optional
|
||||
Group string
|
||||
// Resources is a list of resources within the API group. Subresources are
|
||||
// matched using a "/" to indicate the subresource. For example, "pods/log"
|
||||
// would match request to the log subresource of pods. The top level resource
|
||||
// does not match subresources, "pods" doesn't match "pods/log".
|
||||
// Resources is a list of resources this rule applies to.
|
||||
//
|
||||
// For example:
|
||||
// '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
|
||||
Resources []string
|
||||
// ResourceNames is a list of resource instance names that the policy matches.
|
||||
|
|
|
@ -122,10 +122,19 @@ message GroupResources {
|
|||
// +optional
|
||||
optional string group = 1;
|
||||
|
||||
// Resources is a list of resources within the API group. Subresources are
|
||||
// matched using a "/" to indicate the subresource. For example, "pods/logs"
|
||||
// would match request to the logs subresource of pods. The top level resource
|
||||
// does not match subresources, "pods" doesn't match "pods/logs".
|
||||
// Resources is a list of resources this rule applies to.
|
||||
//
|
||||
// For example:
|
||||
// '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
|
||||
repeated string resources = 2;
|
||||
|
||||
|
|
|
@ -241,10 +241,19 @@ type GroupResources struct {
|
|||
// The empty string represents the core API group.
|
||||
// +optional
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
|
||||
// Resources is a list of resources within the API group. Subresources are
|
||||
// matched using a "/" to indicate the subresource. For example, "pods/logs"
|
||||
// would match request to the logs subresource of pods. The top level resource
|
||||
// does not match subresources, "pods" doesn't match "pods/logs".
|
||||
// Resources is a list of resources this rule applies to.
|
||||
//
|
||||
// For example:
|
||||
// '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
|
||||
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
|
||||
// ResourceNames is a list of resource instance names that the policy matches.
|
||||
|
|
|
@ -126,10 +126,19 @@ message GroupResources {
|
|||
// +optional
|
||||
optional string group = 1;
|
||||
|
||||
// Resources is a list of resources within the API group. Subresources are
|
||||
// matched using a "/" to indicate the subresource. For example, "pods/log"
|
||||
// would match request to the log subresource of pods. The top level resource
|
||||
// does not match subresources, "pods" doesn't match "pods/log".
|
||||
// Resources is a list of resources this rule applies to.
|
||||
//
|
||||
// For example:
|
||||
// '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
|
||||
repeated string resources = 2;
|
||||
|
||||
|
|
|
@ -237,10 +237,19 @@ type GroupResources struct {
|
|||
// The empty string represents the core API group.
|
||||
// +optional
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
|
||||
// Resources is a list of resources within the API group. Subresources are
|
||||
// matched using a "/" to indicate the subresource. For example, "pods/log"
|
||||
// would match request to the log subresource of pods. The top level resource
|
||||
// does not match subresources, "pods" doesn't match "pods/log".
|
||||
// Resources is a list of resources this rule applies to.
|
||||
//
|
||||
// For example:
|
||||
// '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
|
||||
Resources []string `json:"resources,omitempty" protobuf:"bytes,2,rep,name=resources"`
|
||||
// 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
|
|||
|
||||
apiGroup := attrs.GetAPIGroup()
|
||||
resource := attrs.GetResource()
|
||||
subresource := attrs.GetSubresource()
|
||||
combinedResource := resource
|
||||
// If subresource, the resource in the policy must match "(resource)/(subresource)"
|
||||
//
|
||||
// TODO: consider adding options like "pods/*" to match all subresources.
|
||||
if sr := attrs.GetSubresource(); sr != "" {
|
||||
resource = resource + "/" + sr
|
||||
if subresource != "" {
|
||||
combinedResource = resource + "/" + subresource
|
||||
}
|
||||
|
||||
name := attrs.GetName()
|
||||
|
@ -175,8 +175,17 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
|
|||
return true
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,21 @@ var (
|
|||
Verbs: []string{"get"},
|
||||
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": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"get"},
|
||||
|
@ -208,6 +223,9 @@ func testAuditLevel(t *testing.T, stages []audit.Stage) {
|
|||
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, "getPodWildcardMatching")
|
||||
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodResourceWildcardMatching")
|
||||
test(t, "subresource", audit.LevelRequest, stages, stages, "getPodSubResourceWildcardMatching")
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue