Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions backend/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.44.1
github.com/coder/websocket v1.8.15
github.com/crewjam/saml v0.5.1
github.com/crowdstrike/gofalcon v0.21.0
github.com/crowdstrike/gofalcon v0.21.1
github.com/gin-contrib/cors v1.7.7
github.com/gin-gonic/gin v1.12.0
github.com/go-pdf/fpdf v0.9.0
Expand Down Expand Up @@ -131,7 +131,7 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.3.1 // indirect
github.com/yosida95/uritemplate/v3 v3.0.2 // indirect
go.mongodb.org/mongo-driver v1.14.0 // indirect
go.mongodb.org/mongo-driver v1.17.7 // indirect
go.mongodb.org/mongo-driver/v2 v2.6.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
Expand Down
8 changes: 4 additions & 4 deletions backend/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmC
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/crewjam/saml v0.5.1 h1:g+mfp0CrLuLRZCK793PgJcZeg5dS/0CDwoeAX2zcwNI=
github.com/crewjam/saml v0.5.1/go.mod h1:r0fDkmFe5URDgPrmtH0IYokva6fac3AUdstiPhyEolQ=
github.com/crowdstrike/gofalcon v0.21.0 h1:vMHpMtzidy07VxhQHMRH6uzHsOL3Efk6y829efDdOUQ=
github.com/crowdstrike/gofalcon v0.21.0/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8=
github.com/crowdstrike/gofalcon v0.21.1 h1:+n0tbAPCxsZn8q9Z+ss6c09s2/EGS/tqvz8/uE5rlrM=
github.com/crowdstrike/gofalcon v0.21.1/go.mod h1:G3XfEBnyN68Ew/GFXbdy48k11ghlLRAFSdDURyWUtX4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down Expand Up @@ -389,8 +389,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT0
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.einride.tech/aip v0.83.0 h1:TI21IdeOnLTwZEJ3BxtImIZk6bsN2Q+sd0x99SLiQ+M=
go.einride.tech/aip v0.83.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig=
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
go.mongodb.org/mongo-driver v1.17.7 h1:a9w+U3Vt67eYzcfq3k/OAv284/uUUkL0uP75VE5rCOU=
go.mongodb.org/mongo-driver v1.17.7/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
go.mongodb.org/mongo-driver/v2 v2.6.0 h1:b9sJOYrkmt4l8bY43ZenFBcPlhYIjaOfYHLtbB/5qi8=
go.mongodb.org/mongo-driver/v2 v2.6.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
Expand Down
2 changes: 1 addition & 1 deletion backend/modules/eventprocessing/connectors/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type CorrelationRuleUsecase interface {
GetByRelPath(ctx context.Context, relPath string) (*dto.CorrelationRuleResponse, error)
List(ctx context.Context, filters dto.CorrelationRuleFilters) (*ListResult[dto.CorrelationRuleResponse], error)
Delete(ctx context.Context, relPath string) error
SetActive(ctx context.Context, relPath string, active bool) error
SetActive(ctx context.Context, relPath string, active bool) (bool, error)
FindDistinctPropertyValues(ctx context.Context, prop, value string) ([]string, error)
}

Expand Down

This file was deleted.

6 changes: 3 additions & 3 deletions backend/modules/eventprocessing/handler/correlation_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ func (h *CorrelationRuleHandler) Update(c *gin.Context) {
// @Produce json
// @Param id query int64 true "Correlation rule ID"
// @Param active query bool true "true to activate, false to deactivate"
// @Success 204 "No content"
// @Success 200 {object} map[string]bool "changed: true if this call actually flipped the rule's state"
// @Failure 400 {object} map[string]string
// @Failure 500 {object} map[string]string
// @Router /correlation-rule/activate-deactivate [put]
Expand All @@ -140,13 +140,13 @@ func (h *CorrelationRuleHandler) ActivateDeactivate(c *gin.Context) {
return
}

err = h.usecase.SetActive(c.Request.Context(), relPath, active)
changed, err := h.usecase.SetActive(c.Request.Context(), relPath, active)
audit.Record(c, audit_connectors.Event{Action: "correlation_rule.activate"}, audit_domain.CORRELATION_RULE_UPDATE_ATTEMPT, audit_domain.CORRELATION_RULE_UPDATE_SUCCESS, err)
if err != nil {
writeCorrelationError(c, err)
return
}
c.Status(http.StatusNoContent)
c.JSON(http.StatusOK, gin.H{"changed": changed})
}

// @Summary List correlation rules by filters
Expand Down

This file was deleted.

5 changes: 0 additions & 5 deletions backend/modules/eventprocessing/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,6 @@ func RegisterRoutes(api *gin.RouterGroup, m *Module, userAuth gin.HandlerFunc) {
cr.GET("/find", read, crh.GetByID)
cr.DELETE("", write, crh.Delete)

// Internal-only: rule-flood-guard plugin disables a rule it identified as
// flooding the alerts list, by display name.
icr := g.Group("/internal/correlation-rule", middleware.RequireInternal())
icr.PUT("/deactivate", crh.InternalDeactivate)

// Filters (file-backed, pipeline: YAML). Identity = relPath query param.
f := g.Group("/filters")
f.POST("", write, fh.Create)
Expand Down
10 changes: 6 additions & 4 deletions backend/modules/eventprocessing/usecase/correlation_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (u *correlationRuleUsecase) Create(_ context.Context, req dto.CreateCorrela
return mapStoreErr(err)
}
if !req.RuleActive {
_ = u.store.SetEnabled(created.RelPath, false)
_, _ = u.store.SetEnabled(created.RelPath, false)
}
return nil
}
Expand Down Expand Up @@ -152,7 +152,8 @@ func (u *correlationRuleUsecase) Update(_ context.Context, req dto.UpdateCorrela
return mapStoreErr(err)
}
// Reconcile the active state (the store keeps it in the filename).
return mapStoreErr(u.store.SetEnabled(req.RelPath, req.RuleActive))
_, err := u.store.SetEnabled(req.RelPath, req.RuleActive)
return mapStoreErr(err)
}

func (u *correlationRuleUsecase) GetByRelPath(_ context.Context, relPath string) (*dto.CorrelationRuleResponse, error) {
Expand Down Expand Up @@ -193,8 +194,9 @@ func (u *correlationRuleUsecase) Delete(_ context.Context, relPath string) error
return mapStoreErr(u.store.Delete(relPath))
}

func (u *correlationRuleUsecase) SetActive(_ context.Context, relPath string, active bool) error {
return mapStoreErr(u.store.SetEnabled(relPath, active))
func (u *correlationRuleUsecase) SetActive(_ context.Context, relPath string, active bool) (bool, error) {
changed, err := u.store.SetEnabled(relPath, active)
return changed, mapStoreErr(err)
}

func (u *correlationRuleUsecase) FindDistinctPropertyValues(_ context.Context, prop, value string) ([]string, error) {
Expand Down
4 changes: 2 additions & 2 deletions backend/modules/eventprocessing/usecase/rule_bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func (b *RuleBootstrap) migrateLegacyRules(ctx context.Context) error {
// System rules ship as files; only carry over a disable.
if !row.RuleActive {
if relPath, ok := systemByName[row.RuleName]; ok {
if err := b.store.SetEnabled(relPath, false); err != nil {
if _, err := b.store.SetEnabled(relPath, false); err != nil {
_ = catcher.Error("eventprocessing: reconciling disabled system rule failed", err,
map[string]any{"rule": row.RuleName})
failed++
Expand All @@ -262,7 +262,7 @@ func (b *RuleBootstrap) migrateLegacyRules(ctx context.Context) error {
continue
}
if !row.RuleActive {
if err := b.store.SetEnabled(created.RelPath, false); err != nil {
if _, err := b.store.SetEnabled(created.RelPath, false); err != nil {
_ = catcher.Error("eventprocessing: disabling migrated user rule failed", err,
map[string]any{"rule": row.RuleName})
failed++
Expand Down
17 changes: 12 additions & 5 deletions backend/modules/eventprocessing/usecase/rule_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,23 +345,30 @@ func (s *RuleStore) Delete(relPath string) error {
// (disabledRules, keyed by ruleIdentity) rather than on the file itself, so it
// works identically for system and user rules (disabling is the one mutation
// allowed on a system rule) and never touches file content.
func (s *RuleStore) SetEnabled(relPath string, enabled bool) error {
//
// The returned bool is the authoritative "did this call actually flip the
// state" signal: false when the rule was already in the requested state (a
// no-op) or when the call failed, true only when this call performed the
// transition. Callers that need to know whether THEY caused a state change
// (e.g. to decide whether to notify) must use this return value rather than
// re-deriving it from a value read before the call.
func (s *RuleStore) SetEnabled(relPath string, enabled bool) (bool, error) {
s.mu.Lock()
defer s.mu.Unlock()

sr, ok := s.index[relPath]
if !ok {
return ErrRuleNotFound
return false, ErrRuleNotFound
}
if sr.enabled == enabled {
return nil
return false, nil
}

if err := s.writer.SetRuleDisabled(ruleIdentity(relPath), !enabled); err != nil {
return err
return false, err
}
sr.enabled = enabled
return nil
return true, nil
}

// DistinctValues returns the distinct values of a rule property, optionally
Expand Down
5 changes: 3 additions & 2 deletions backend/modules/mcp/tools_eventprocessing.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,11 @@ func registerEPCorrelationRules(m *Module) {
Annotations: &mcp.ToolAnnotations{IdempotentHint: true},
}, Gate{Permission: "eventprocessing.write"},
func(ctx context.Context, _ *authz.Actor, in epRuleSetActiveInput) (any, error) {
if err := uc.SetActive(ctx, in.RelPath, in.Active); err != nil {
changed, err := uc.SetActive(ctx, in.RelPath, in.Active)
if err != nil {
return nil, err
}
return map[string]any{"rel_path": in.RelPath, "active": in.Active}, nil
return map[string]any{"rel_path": in.RelPath, "active": in.Active, "changed": changed}, nil
})

Add(m, &mcp.Tool{
Expand Down
2 changes: 1 addition & 1 deletion plugins/crowdstrike/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/utmstack/UTMStack/plugins/crowdstrike
go 1.25.5

require (
github.com/crowdstrike/gofalcon v0.21.0
github.com/crowdstrike/gofalcon v0.21.1
github.com/fsnotify/fsnotify v1.10.1
github.com/google/uuid v1.6.0
github.com/threatwinds/go-sdk v1.1.26
Expand Down
4 changes: 2 additions & 2 deletions plugins/crowdstrike/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudwego/base64x v0.1.7 h1:NppS+Fgzg5ovhn4NkUXaDT3x9jldgH5ToMCqzBSi2zI=
github.com/cloudwego/base64x v0.1.7/go.mod h1:Cu1PV9zfrSf7ET2tIbWbbEy7jO7HHJ13q4X2SQ8aWYg=
github.com/crowdstrike/gofalcon v0.21.0 h1:vMHpMtzidy07VxhQHMRH6uzHsOL3Efk6y829efDdOUQ=
github.com/crowdstrike/gofalcon v0.21.0/go.mod h1:GYbhi35odSf8qFrcxAX6Sx7N/QIJyz8vKmUzuam7Xd8=
github.com/crowdstrike/gofalcon v0.21.1 h1:+n0tbAPCxsZn8q9Z+ss6c09s2/EGS/tqvz8/uE5rlrM=
github.com/crowdstrike/gofalcon v0.21.1/go.mod h1:G3XfEBnyN68Ew/GFXbdy48k11ghlLRAFSdDURyWUtX4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
Expand Down
2 changes: 1 addition & 1 deletion plugins/rule-flood-guard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ plugins:
| `windowHours` | `24` | Time window used to count alerts. |
| `intervalSeconds` | `300` | How often the guard checks. |

If the file doesn't exist, the guard just runs with these defaults.
If the file doesn't exist, the plugin creates it with these defaults the first time it starts — it never overwrites a file that's already there.


Loading
Loading