Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
4b4bfe6
feat(policy): add proto fields for audit log custom resources
Sep 30, 2026
248220b
feat(compliance): collect audit events for requested API resources
Sep 30, 2026
141f0e3
feat(policy): add Kubernetes API Resource audit log policy criterion
Sep 30, 2026
c8addb7
feat(sensor): send API resources from audit log policies to compliance
Sep 30, 2026
114d49f
feat(alerts): raise CUSTOM resource alerts for API resource audit events
Sep 30, 2026
4880f33
feat(ui): add Kubernetes API resource audit log policy criterion
Sep 30, 2026
af4f865
feat(qa): e2e test for audit log policies on API resources
Sep 30, 2026
46b38ce
feat(ui): clarify plural resource names for Kubernetes API resource
Sep 30, 2026
ab1d154
fix(ui): name API resource in audit log missing-resource error
Sep 30, 2026
6e4512f
docs: add doc comments to functions touched for API resource audit po…
Sep 30, 2026
d0e0552
Merge branch 'master' into mzwennes/audit-log-custom-resources
zwennesm Sep 30, 2026
4d12333
fix: surface API resource in notifiers and dashboard, reject empty value
Oct 1, 2026
4e4d2aa
fix(ui): drop singular-name note from API resource helper text
Oct 6, 2026
8589bfa
Merge remote-tracking branch 'fork/mzwennes/audit-log-custom-resource…
Oct 6, 2026
3dcd3cc
Merge branch 'master' into mzwennes/audit-log-custom-resources
zwennesm Oct 6, 2026
447d76c
fix(ui): reject whitespace in Kubernetes API resource
Oct 6, 2026
bd15a47
Merge remote-tracking branch 'fork/mzwennes/audit-log-custom-resource…
Oct 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
docs: add doc comments to functions touched for API resource audit po…
…licies
  • Loading branch information
Martijn Zwennes
Martijn Zwennes committed Sep 30, 2026
commit 6e4512f9e3fa8282d308ed2cf19cf016266c39f9
2 changes: 2 additions & 0 deletions central/alert/views/views.go
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ func (k *AlertMatchKey) GetResourceName() string {
}
return *k.ResourceName
}

// GetResourceAPIResource returns the "<plural>[.<group>]" API resource name, or empty if unset.
func (k *AlertMatchKey) GetResourceAPIResource() string {
if k.ResourceAPIResource == nil {
return ""
Expand Down
4 changes: 4 additions & 0 deletions central/detection/alertmanager/alert_manager_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,6 +642,8 @@ func (w alertAdapter) GetResourceType() storage.Alert_Resource_ResourceType {
return w.a.GetResource().GetResourceType()
}
func (w alertAdapter) GetResourceName() string { return w.a.GetResource().GetName() }

// GetResourceAPIResource returns the API resource name of resource alerts for non built-in resource types.
func (w alertAdapter) GetResourceAPIResource() string {
return w.a.GetResource().GetApiResource()
}
Expand Down Expand Up @@ -691,6 +693,8 @@ func findMatchingKey(toFind *storage.Alert, keys []*alertviews.AlertMatchKey) *a
return nil
}

// alertsAreForSamePolicyAndEntity reports whether both alerts share policy, state and the violating
// entity (deployment, resource or node).
func alertsAreForSamePolicyAndEntity(a1, a2 alertviews.AlertMatcher) bool {
if a1.GetPolicyId() != a2.GetPolicyId() || a1.GetState() != a2.GetState() {
return false
Expand Down
2 changes: 2 additions & 0 deletions central/policy/service/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ func (s *policyValidator) removeEnforcementsForMissingLifecycles(policy *storage
}
}

// validateEventSource checks that the event source fits the lifecycle stages and that audit log
// policies only use supported criteria, scopes and exclusions.
func (s *policyValidator) validateEventSource(policy *storage.Policy) error {
if policies.AppliesAtRunTime(policy) && policy.GetEventSource() == storage.EventSource_NOT_APPLICABLE {
return s.eventSourceError()
Expand Down
2 changes: 2 additions & 0 deletions compliance/collection/auditlog/auditevent.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ func (u *userRef) ToKubernetesEventUser() *storage.KubernetesEvent_User {
}
}

// ToKubernetesEvent converts the audit event into a KubernetesEvent. Resources not covered by the
// resource type enum are identified by their API resource name.
func (e *auditEvent) ToKubernetesEvent(clusterID string) *storage.KubernetesEvent {
protoTime, err := protocompat.ParseRFC3339NanoTimestamp(e.StageTimestamp)
if err != nil {
Expand Down
2 changes: 2 additions & 0 deletions compliance/collection/auditlog/auditlog_impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ func (s *auditLogReaderImpl) readAndForwardAuditLogs(ctx context.Context, tailer
}
}

// shouldSendEvent reports whether the event is past the start state and matches either the built-in
// resource allow-list or one of the requested API resources.
func (s *auditLogReaderImpl) shouldSendEvent(event *auditEvent) bool {
if s.startState != nil {
protoTime, err := protocompat.ParseRFC3339NanoTimestamp(event.StageTimestamp)
Expand Down
1 change: 1 addition & 0 deletions compliance/compliance.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ func dispatchACK(umh handler.UnconfirmedMessageHandler, label string, action sen
}
}

// startAuditLogCollection starts an audit log reader for this node based on the start request.
func (c *Compliance) startAuditLogCollection(ctx context.Context, client sensor.ComplianceService_CommunicateClient, request *sensor.MsgToCompliance_AuditLogCollectionRequest_StartRequest) auditlog.Reader {
if request.GetCollectStartState() == nil {
log.Infof("Starting audit log reader on node %s in cluster %s with no saved state", c.nodeNameProvider.GetNodeName(), request.GetClusterId())
Expand Down
1 change: 1 addition & 0 deletions pkg/alert/convert/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func AlertToListAlert(alert *storage.Alert) *storage.ListAlert {
return listAlert
}

// populateListAlertEntityInfoForResource sets the resource entity and common entity info on the list alert.
func populateListAlertEntityInfoForResource(listAlert *storage.ListAlert, resource *storage.Alert_Resource) {
listAlert.Entity = &storage.ListAlert_Resource{
Resource: &storage.ListAlert_ResourceEntity{
Expand Down
1 change: 1 addition & 0 deletions pkg/booleanpolicy/field_metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func (f *FieldMetadata) registerFieldMetadata(fieldName string, qb querybuilders
f.fieldsToQB[fieldName] = newFieldMetadata(qb, contextFields, validator, source, fieldTypes, options...)
}

// initializeFieldMetadata registers the query builder, validator and event source of every policy field.
func initializeFieldMetadata() FieldMetadata {
f := FieldMetadata{
fieldsToQB: make(map[string]*metadataAndQB),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ func podAttachViolationMsg(event *storage.KubernetesEvent) (string, []*storage.A
return getAttachMsgHeader(event), getAttachMsgViolationAttr(event)
}

// getDefaultViolationMsgHeader builds a human readable header describing the accessed resource.
func getDefaultViolationMsgHeader(event *storage.KubernetesEvent) string {
object := event.GetObject()
readableResourceName := strings.ToLower(object.GetResource().String())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ export type MostRecentViolationsProps = {
alerts: Alert[];
};

/**
* Lists the most recent critical severity violations with links to their details.
*/
function MostRecentViolations({ alerts }: MostRecentViolationsProps) {
return (
<Flex direction={{ default: 'column' }} spaceItems={{ default: 'spaceItemsMd' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ function EnforcementColumn({ original }: EnforcementColumnProps): ReactElement {
return <span>{message}</span>;
}

/**
* Returns the violations table columns for the given workflow view.
*/
export function getViolationsTableColumnDescriptors(filteredWorkflowView: FilteredWorkflowView) {
return [
{
Expand Down