Skip to content

Commit d55ab69

Browse files
fix(list_runtime_events): enable ML event discovery (#67)
The `list_runtime_events` tool returned zero results when querying for ML-based detections (e.g. "Crypto Mining Detection" with `engine = "machineLearning"`), even though these events were visible in the Sysdig Secure UI. The root cause was a `source != "auditTrail"` clause in the MCP baseFilter that duplicated a filter already applied by the events API. This duplication caused an OpenSearch query interaction that silently excluded ML events from the `events_profiling_detection_v1` index. Tested on both us2 and eu1 environments: - `engine = "machineLearning"` now returns ML events (Crypto Mining Detection confirmed) - `source = "auditTrail"` returns 0 events (API-side filter works correctly) - No audit trail event leakage across 2-week windows with 200k+ total events Co-authored-by: Fede Barcelona <fede_rico_94@hotmail.com>
1 parent e2ef21c commit d55ab69

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

internal/infra/mcp/tools/tool_list_runtime_events.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"github.com/sysdiglabs/sysdig-mcp-server/internal/infra/sysdig"
1111
)
1212

13-
const baseFilter = `source != "audittrail" and not originator in ("benchmarks","compliance","cloudsec","scanning","hostscanning")`
13+
const baseFilter = `not originator in ("benchmarks","compliance","cloudsec","scanning","hostscanning")`
1414

1515
type ToolListRuntimeEvents struct {
1616
sysdigClient sysdig.ExtendedClientWithResponsesInterface
@@ -63,7 +63,7 @@ func toolRequestToEventsV1Params(request mcp.CallToolRequest, clock clock.Clock)
6363

6464
func (h *ToolListRuntimeEvents) RegisterInServer(s *server.MCPServer) {
6565
tool := mcp.NewTool("list_runtime_events",
66-
mcp.WithDescription("List runtime security events from the last given hours, optionally filtered by severity level."),
66+
mcp.WithDescription("List runtime security events from the last given hours, optionally filtered by severity level. Includes both Falco-based and machine learning (ML) detections such as crypto mining, anomalous logins, and other ML-detected threats."),
6767
mcp.WithString("cursor",
6868
mcp.Description("Cursor for pagination."),
6969
),
@@ -72,14 +72,20 @@ func (h *ToolListRuntimeEvents) RegisterInServer(s *server.MCPServer) {
7272
mcp.DefaultNumber(1),
7373
),
7474
mcp.WithNumber("limit",
75-
mcp.Description("Maximum number of events to return."),
75+
mcp.Description("Maximum number of events to return. Maximum allowed value is 200."),
7676
mcp.DefaultNumber(50),
7777
),
7878
mcp.WithString("filter_expr",
7979
mcp.Description(`Logical filter expression to select runtime security events.
8080
Supports operators: =, !=, in, contains, startsWith, exists.
8181
Combine with and/or/not.
82-
Key attributes include: severity (codes "0"-"7"), originator, sourceType, ruleName, rawEventCategory, kubernetes.cluster.name, host.hostName, container.imageName, aws.accountId, azure.subscriptionId, gcp.projectId, policyId, trigger.
82+
Key attributes include: severity (codes "0"-"7"), originator, sourceType, ruleName, rawEventCategory, engine, source, category, kubernetes.cluster.name, host.hostName, container.imageName, aws.accountId, azure.subscriptionId, gcp.projectId, policyId, trigger.
83+
84+
To find machine learning (ML) detections (e.g. crypto mining, anomalous logins), use engine or source filters:
85+
- All ML events: 'engine = "machineLearning"'
86+
- AWS ML detections: 'source = "agentless-aws-ml"'
87+
- Okta ML detections: 'source = "agentless-okta-ml"'
88+
- By category: 'category = "machine-learning"'
8389
8490
You can specify the severity of the events based on the following cases:
8591
- high-severity: 'severity in ("0","1","2","3")'
@@ -96,6 +102,9 @@ You can specify the severity of the events based on the following cases:
96102
`container.imageName = "nginx:latest" and originator = "hostscanning"`,
97103
`aws.accountId = "123456789012"`,
98104
`policyId = "CIS_Docker_Benchmark"`,
105+
`engine = "machineLearning"`,
106+
`source = "agentless-aws-ml"`,
107+
`engine = "machineLearning" and aws.accountId = "123456789012"`,
99108
),
100109
),
101110
mcp.WithOutputSchema[map[string]any](),

internal/infra/mcp/tools/tool_list_runtime_events_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ var _ = Describe("ToolListRuntimeEvents", func() {
9494
It("should use default values when no params are provided", func(ctx SpecContext) {
9595
mockClient.EXPECT().GetEventsV1WithResponse(gomock.Any(), gomock.Any()).DoAndReturn(func(_ context.Context, params *sysdig.GetEventsV1Params, _ ...sysdig.RequestEditorFn) (*sysdig.GetEventsV1Response, error) {
9696
Expect(*params.Limit).To(Equal(int32(50)))
97-
Expect(*params.Filter).To(Equal(`source != "audittrail" and not originator in ("benchmarks","compliance","cloudsec","scanning","hostscanning")`))
97+
Expect(*params.Filter).To(Equal(`not originator in ("benchmarks","compliance","cloudsec","scanning","hostscanning")`))
9898
Expect(*params.To).To(Equal(int64(946684800000000000)))
9999
Expect(*params.From).To(Equal(int64(946681200000000000)))
100100

0 commit comments

Comments
 (0)