Skip to content

Commit

Permalink
new(plugins/k8saudit): add subject name fields
Browse files Browse the repository at this point in the history
Signed-off-by: Luca Guerra <[email protected]>
  • Loading branch information
LucaGuerra authored and poiana committed Jan 13, 2025
1 parent 35ec887 commit a383f07
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 0 deletions.
4 changes: 4 additions & 0 deletions plugins/k8saudit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ The event source for Kubernetes Audit Events is `k8s_audit`.
| `ka.target.subresource` | `string` | None | The target object subresource |
| `ka.target.pod.name` | `string` | None | The target pod name |
| `ka.req.binding.subjects` | `string (list)` | None | When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding |
| `ka.req.binding.subjects.user_names` | `string (list)` | None | When the request object refers to a cluster role binding, the subject user names being linked by the binding |
| `ka.req.binding.subjects.serviceaccount_names` | `string (list)` | None | When the request object refers to a cluster role binding, the subject service account names being linked by the binding |
| `ka.req.binding.subjects.serviceaccount_ns_names` | `string (list)` | None | When the request object refers to a cluster role binding, the subject serviceaccount namespaced names being linked by the binding, e.g. a list containing: mynamespace:myserviceaccount |
| `ka.req.binding.subjects.group_names` | `string (list)` | None | When the request object refers to a cluster role binding, the subject group names being linked by the binding |
| `ka.req.binding.role` | `string` | None | When the request object refers to a cluster role binding, the role being linked by the binding |
| `ka.req.binding.subject.has_name` | `string` | Key, Required | Deprecated, always returns "N/A". Only provided for backwards compatibility |
| `ka.req.configmap.name` | `string` | None | If the request object refers to a configmap, the configmap name |
Expand Down
66 changes: 66 additions & 0 deletions plugins/k8saudit/pkg/k8saudit/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,30 @@ func (e *Plugin) ExtractFromJSON(req sdk.ExtractRequest, jsonValue *fastjson.Val
}
case "ka.req.binding.subjects":
return e.extractFromKeys(req, jsonValue, "requestObject", "subjects")
case "ka.req.binding.subjects.user_names":
names, err := e.readSubjectNamesByKind(jsonValue, "User")
if err != nil {
return err
}
req.SetValue(names)
case "ka.req.binding.subjects.serviceaccount_names":
names, err := e.readSubjectNamesByKind(jsonValue, "ServiceAccount")
if err != nil {
return err
}
req.SetValue(names)
case "ka.req.binding.subjects.serviceaccount_ns_names":
names, err := e.readSubjectNamesByKind(jsonValue, "NamespacedServiceAccount")
if err != nil {
return err
}
req.SetValue(names)
case "ka.req.binding.subjects.group_names":
names, err := e.readSubjectNamesByKind(jsonValue, "Group")
if err != nil {
return err
}
req.SetValue(names)
case "ka.req.binding.role":
return e.extractFromKeys(req, jsonValue, "requestObject", "roleRef", "name")
case "ka.req.binding.subject.has_name":
Expand Down Expand Up @@ -478,6 +502,48 @@ func (e *Plugin) arrayAsStringsWithDefault(values []*fastjson.Value, defaultValu
return res
}

func (e *Plugin) readSubjectNamesByKind(jsonValue *fastjson.Value, kind string) ([]string, error) {
res := []string{}
jsonSubjects := jsonValue.Get("requestObject", "subjects")
if jsonSubjects == nil {
return res, nil
}
if jsonSubjects.Type() != fastjson.TypeArray {
return nil, ErrExtractWrongType
}

namespacedServiceAccount := false
if kind == "NamespacedServiceAccount" {
namespacedServiceAccount = true
kind = "ServiceAccount"
}

for _, subject := range jsonSubjects.GetArray() {
if subject.Get("kind") != nil && subject.Get("name") != nil {
subjectKind, err := e.jsonValueAsString(subject.Get("kind"))
if err != nil {
continue
}
if subjectKind == kind {
name, err := e.jsonValueAsString(subject.Get("name"))
if err != nil {
continue
}
if namespacedServiceAccount {
namespace, err := e.jsonValueAsString(subject.Get("namespace"))
if err != nil {
continue
}
name = namespace + ":" + name
}
res = append(res, name)
}
}
}

return res, nil
}

// note: this returns an error on nil values
func (e *Plugin) readContainerImages(jsonValue *fastjson.Value, indexFilter int) ([]string, error) {
arr, err := e.getValuesRecursive(jsonValue, indexFilter, "requestObject", "spec", "containers", "image")
Expand Down
24 changes: 24 additions & 0 deletions plugins/k8saudit/pkg/k8saudit/fields.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,30 @@ func (k *Plugin) Fields() []sdk.FieldEntry {
Desc: "When the request object refers to a cluster role binding, the subject (e.g. account/users) being linked by the binding",
IsList: true,
},
{
Type: "string",
Name: "ka.req.binding.subjects.user_names",
Desc: "When the request object refers to a cluster role binding, the subject user names being linked by the binding",
IsList: true,
},
{
Type: "string",
Name: "ka.req.binding.subjects.serviceaccount_names",
Desc: "When the request object refers to a cluster role binding, the subject service account names being linked by the binding",
IsList: true,
},
{
Type: "string",
Name: "ka.req.binding.subjects.serviceaccount_ns_names",
Desc: "When the request object refers to a cluster role binding, the subject serviceaccount namespaced names being linked by the binding, e.g. a list containing: mynamespace:myserviceaccount",
IsList: true,
},
{
Type: "string",
Name: "ka.req.binding.subjects.group_names",
Desc: "When the request object refers to a cluster role binding, the subject group names being linked by the binding",
IsList: true,
},
{
Type: "string",
Name: "ka.req.binding.role",
Expand Down

0 comments on commit a383f07

Please sign in to comment.