mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-17 20:00:07 +00:00
feat: Allow wildcard '*' for API groups in audit policy rules
This commit is contained in:
2
pkg/generated/openapi/zz_generated.openapi.go
generated
2
pkg/generated/openapi/zz_generated.openapi.go
generated
@@ -64867,7 +64867,7 @@ func schema_pkg_apis_audit_v1_GroupResources(ref common.ReferenceCallback) commo
|
||||
Properties: map[string]spec.Schema{
|
||||
"group": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Group is the name of the API group that contains the resources. The empty string represents the core API group.",
|
||||
Description: "Group is the name of the API group that contains the resources. The empty string represents the core API group. `*` matches all groups",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
|
||||
@@ -275,6 +275,7 @@ type PolicyRule struct {
|
||||
type GroupResources struct {
|
||||
// Group is the name of the API group that contains the resources.
|
||||
// The empty string represents the core API group.
|
||||
// `*` matches all groups
|
||||
// +optional
|
||||
Group string
|
||||
// Resources is a list of resources this rule applies to.
|
||||
|
||||
@@ -135,6 +135,7 @@ message EventList {
|
||||
message GroupResources {
|
||||
// Group is the name of the API group that contains the resources.
|
||||
// The empty string represents the core API group.
|
||||
// `*` matches all groups
|
||||
// +optional
|
||||
optional string group = 1;
|
||||
|
||||
|
||||
@@ -278,6 +278,7 @@ type PolicyRule struct {
|
||||
type GroupResources struct {
|
||||
// Group is the name of the API group that contains the resources.
|
||||
// The empty string represents the core API group.
|
||||
// `*` matches all groups
|
||||
// +optional
|
||||
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
|
||||
// Resources is a list of resources this rule applies to.
|
||||
|
||||
@@ -98,7 +98,7 @@ func validateResources(groupResources []audit.GroupResources, fldPath *field.Pat
|
||||
var allErrs field.ErrorList
|
||||
for _, groupResource := range groupResources {
|
||||
// The empty string represents the core API group.
|
||||
if len(groupResource.Group) != 0 {
|
||||
if len(groupResource.Group) != 0 && groupResource.Group != "*" {
|
||||
// Group names must be lower case and be valid DNS subdomains.
|
||||
// reference: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
|
||||
// an error is returned for group name like rbac.authorization.k8s.io/v1beta1
|
||||
|
||||
@@ -191,7 +191,7 @@ func ruleMatchesResource(r *audit.PolicyRule, attrs authorizer.Attributes) bool
|
||||
name := attrs.GetName()
|
||||
|
||||
for _, gr := range r.Resources {
|
||||
if gr.Group == apiGroup {
|
||||
if gr.Group == apiGroup || gr.Group == "*" {
|
||||
if len(gr.Resources) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -84,6 +84,17 @@ var (
|
||||
ResourceRequest: true,
|
||||
Path: "/api/v1/namespaces/default/pods/busybox",
|
||||
},
|
||||
"ClusterRoleUpdate": &authorizer.AttributesRecord{
|
||||
User: tim,
|
||||
Verb: "update",
|
||||
APIGroup: "rbac.authorization.k8s.io",
|
||||
APIVersion: "v1beta1",
|
||||
Resource: "clusterroles",
|
||||
Subresource: "status",
|
||||
Name: "somerole",
|
||||
ResourceRequest: true,
|
||||
Path: "/apis/rbac.authorization.k8s.io/v1beta1/clusterroles/somerole",
|
||||
},
|
||||
}
|
||||
|
||||
rules = map[string]audit.PolicyRule{
|
||||
@@ -140,6 +151,14 @@ var (
|
||||
}},
|
||||
Namespaces: []string{""},
|
||||
},
|
||||
"getGroupWildCardMatchingWithSubresourceWildcardMatching": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"update"},
|
||||
Resources: []audit.GroupResources{{
|
||||
Group: "*",
|
||||
Resources: []string{"*/status"},
|
||||
}},
|
||||
},
|
||||
"getLogs": {
|
||||
Level: audit.LevelRequestResponse,
|
||||
Verbs: []string{"get"},
|
||||
@@ -242,6 +261,7 @@ func testAuditLevel(t *testing.T, stages []audit.Stage) {
|
||||
test(t, "Unauthorized", audit.LevelMetadata, stages, stages, "tims", "default")
|
||||
test(t, "Unauthorized", audit.LevelNone, stages, stages, "humans")
|
||||
test(t, "Unauthorized", audit.LevelMetadata, stages, stages, "humans", "default")
|
||||
test(t, "ClusterRoleUpdate", audit.LevelRequestResponse, stages, stages, "getGroupWildCardMatchingWithSubresourceWildcardMatching")
|
||||
}
|
||||
|
||||
func TestChecker(t *testing.T) {
|
||||
|
||||
@@ -99,6 +99,11 @@ rules:
|
||||
resources:
|
||||
- group: "apps"
|
||||
resources: ["deployments/scale"]
|
||||
- level: Request
|
||||
namespaces: ["wildcard-group-audit-request"]
|
||||
resources:
|
||||
- group: "*"
|
||||
resources: ["deployments"]
|
||||
|
||||
`
|
||||
nonAdmissionWebhookNamespace = "no-webhook-namespace"
|
||||
@@ -375,6 +380,25 @@ func runTestWithVersion(t *testing.T, version string) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
auditLevel: auditinternal.LevelRequest,
|
||||
namespace: "wildcard-group-audit-request",
|
||||
expEvents: []utils.AuditEvent{
|
||||
{
|
||||
Level: auditinternal.LevelRequest,
|
||||
Stage: auditinternal.StageResponseComplete,
|
||||
RequestURI: fmt.Sprintf("/apis/apps/v1/namespaces/%s/deployments", "wildcard-group-audit-request"),
|
||||
Verb: "create",
|
||||
Code: 201,
|
||||
User: auditTestUser,
|
||||
Resource: "deployments",
|
||||
Namespace: "wildcard-group-audit-request",
|
||||
RequestObject: true,
|
||||
ResponseObject: false,
|
||||
AuthorizeDecision: "allow",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tcs {
|
||||
|
||||
Reference in New Issue
Block a user