Documentation
¶
Overview ¶
Package rules is the daemon-side workflow automation engine. It owns rule storage (the rules + rule_runs tables from migration 0014), evaluation (condition tree + action dispatch), and integration with the v1.6 event bus.
The public surface for embedders lives at pkg/compliancekit/rules; this package converts to/from those types at the persistence boundary so internal evaluation can use richer Go types (registered evaluator functions, dispatcher closures) without leaking them onto the v1.x SemVer contract.
Engine lifecycle:
eng := rules.New(store, registry) eng.Start(ctx) // subscribes to bus.Producer defer eng.Stop()
Per-event evaluation:
eng.HandleEvent(ctx, "finding.created", payload)
The HandleEvent path is invoked by the v1.6 event-bus subscriber (Phase 7 wires that). For now this package only exposes the types + storage + registry; phase 1+ layers the condition / action implementations + bus integration on top.
Index ¶
- Variables
- func SetClock(fn func() time.Time) func() time.Time
- func SeverityAtLeast(have, want string) bool
- func SilenceWindow(now time.Time, startHHMM, endHHMM string) bool
- type ActionDispatcher
- type ActionResult
- type ConditionEvaluator
- type CronLoop
- type Engine
- type EvalContext
- type FindingFacts
- type Registry
- func (r *Registry) ActionKinds() []string
- func (r *Registry) ConditionKinds() []string
- func (r *Registry) LookupAction(kind string) (ActionDispatcher, bool)
- func (r *Registry) LookupCondition(kind string) (ConditionEvaluator, bool)
- func (r *Registry) RegisterAction(kind string, fn ActionDispatcher)
- func (r *Registry) RegisterCondition(kind string, fn ConditionEvaluator)
- type Repo
- func (r *Repo) All(ctx context.Context) ([]Rule, error)
- func (r *Repo) ByID(ctx context.Context, id string) (Rule, error)
- func (r *Repo) Create(ctx context.Context, in Rule) (Rule, error)
- func (r *Repo) Delete(ctx context.Context, id string) error
- func (r *Repo) ListByTrigger(ctx context.Context, trigger rules.Trigger) ([]Rule, error)
- func (r *Repo) RecentRuns(ctx context.Context, ruleID string, limit int) ([]RunRecord, error)
- func (r *Repo) RecordRun(ctx context.Context, rec RunRecord) error
- func (r *Repo) Update(ctx context.Context, in Rule) error
- type ResourceFacts
- type Rule
- type RunRecord
- type ScanFacts
- type SimulateOptions
- type SimulateResult
Constants ¶
This section is empty.
Variables ¶
var DefaultRegistry = NewRegistry()
DefaultRegistry is the package-global registry the engine reads from by default. internal/rules/conditions + internal/rules/actions init() into this — same pattern as the v0.x check registry.
Functions ¶
func SeverityAtLeast ¶
SeverityAtLeast returns true when have >= want using the canonical severity ranking. Unknown severity strings rank 0 (never reaches a real threshold).
func SilenceWindow ¶
SilenceWindow is a small helper for time-of-day style conditions. startHHMM / endHHMM are "HH:MM" strings. now is compared against the local time in the rule's timezone, which the caller is expected to have already loaded.
Types ¶
type ActionDispatcher ¶
type ActionDispatcher func(ctx context.Context, rule *Rule, params map[string]any, ec *EvalContext) ActionResult
ActionDispatcher runs one action. The engine passes the matched rule for context (e.g. rule.ID is useful in audit lines) plus the EvalContext + the action's Params.
type ActionResult ¶
type ActionResult struct {
Outcome string `json:"outcome,omitempty"`
Error string `json:"error,omitempty"`
Data map[string]any `json:"data,omitempty"`
}
ActionResult is what an action returns after dispatch. Outcome records human-readable text the audit log + simulator surface.
type ConditionEvaluator ¶
type ConditionEvaluator func(ctx context.Context, params map[string]any, ec *EvalContext) (bool, error)
ConditionEvaluator is the signature every built-in condition implements. The bool return is the predicate value; the error return surfaces malformed Params so the engine can mark the rule as broken in the rule_runs table instead of silently no-matching.
type CronLoop ¶
type CronLoop struct {
// contains filtered or unexported fields
}
CronLoop drives the cron-trigger rules. Construct via NewCronLoop; Run blocks until ctx is canceled.
func NewCronLoop ¶
NewCronLoop wires the loop. Pass the engine that will dispatch matched rule actions. tickEvery defaults to 30s.
type Engine ¶
type Engine struct {
// contains filtered or unexported fields
}
Engine evaluates rules against incoming events. Construct via New + Start; HandleEvent is the single entry point for upstream event-bus subscribers.
func New ¶
New builds an Engine over the given repo + registry. Pass DefaultRegistry in production wiring.
func (*Engine) HandleEvent ¶
HandleEvent walks every enabled rule with the matching trigger and evaluates it against the EvalContext. Each rule's outcome is persisted via Repo.RecordRun.
Returns the slice of matched rules (whether their actions succeeded or not) so callers can correlate the event with the downstream effects.
func (*Engine) Simulate ¶
func (e *Engine) Simulate(ctx context.Context, opts SimulateOptions) ([]SimulateResult, error)
Simulate runs the replay + returns one summary per matched rule. The detailed per-fingerprint outcomes land in rule_runs with simulated=1; callers can read them via Repo.RecentRuns.
func (*Engine) WithSimulator ¶
WithSimulator returns a sibling engine that records every rule outcome with simulated=1 + suppresses every action dispatch. Used by the v1.9 phase 8 simulator.
type EvalContext ¶
type EvalContext struct {
Trigger rules.Trigger
Now time.Time
Finding FindingFacts // populated for finding.* triggers
Scan ScanFacts // populated for scan.* triggers
Resource ResourceFacts // populated when the event names a resource
Extras map[string]any // free-form trigger-specific payload
Simulated bool // true under phase 8 simulator
}
EvalContext is the payload one rule sees during evaluation. The engine builds an EvalContext per trigger event + walks every matching rule against it.
type FindingFacts ¶
type FindingFacts struct {
Fingerprint string
CheckID string
Severity string // "critical"|"high"|...
Status string // "pass"|"fail"|"skip"|"error"
Provider string
ResourceID string
ResourceType string
ResourceName string
Frameworks []string
Tags []string
FirstSeenAt time.Time
LastSeenAt time.Time
}
FindingFacts is the slice of a Finding the engine needs to evaluate conditions. Kept separate from compliancekit.Finding so the engine doesn't have to load the full graph on every event.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds the named condition + action implementations the engine evaluates against. Registration is package-global by convention (one daemon, one rule set); tests may construct their own Registry to isolate fixtures.
func (*Registry) ActionKinds ¶
ActionKinds returns every registered action kind, sorted.
func (*Registry) ConditionKinds ¶
ConditionKinds returns every registered condition kind, sorted. Used by the v1.9 phase 3 UI builder to populate the picker.
func (*Registry) LookupAction ¶
func (r *Registry) LookupAction(kind string) (ActionDispatcher, bool)
LookupAction returns the dispatcher + true, or nil + false.
func (*Registry) LookupCondition ¶
func (r *Registry) LookupCondition(kind string) (ConditionEvaluator, bool)
LookupCondition returns the evaluator + true, or nil + false.
func (*Registry) RegisterAction ¶
func (r *Registry) RegisterAction(kind string, fn ActionDispatcher)
RegisterAction installs a dispatcher under the given kind.
func (*Registry) RegisterCondition ¶
func (r *Registry) RegisterCondition(kind string, fn ConditionEvaluator)
RegisterCondition installs an evaluator under the given kind. Duplicate kinds overwrite (the second wins) — keeps tests simple; production wiring goes through init() and so naturally deduplicates.
type Repo ¶
type Repo struct {
// contains filtered or unexported fields
}
Repo owns the rules + rule_runs tables.
func (*Repo) All ¶
All returns every rule (enabled or not) sorted by name. Drives the /rules list view.
func (*Repo) ListByTrigger ¶
ListByTrigger returns enabled rules with the given trigger, in priority order (lowest first). The engine subscribes on bus events + walks this list.
func (*Repo) RecentRuns ¶
RecentRuns returns the most recent rule_runs entries for a rule. Drives the /rules/{id} history pane + the simulator preview.
type ResourceFacts ¶
ResourceFacts is the slice of a Resource the engine needs.
type Rule ¶
Rule is the daemon-side representation of a rules.Rule including the parsed Condition + Actions. The Repo loads + saves these.
type RunRecord ¶
type RunRecord struct {
RuleID string
TriggerEvent string
Fingerprint string
Matched bool
Actions []ActionResult
Simulated bool
Duration time.Duration
}
RecordRun persists one rule_runs row.
type ScanFacts ¶
type ScanFacts struct {
ID string
Source string
Status string
Score int
Coverage int
TotalFindings int
ActionableFindings int
FinishedAt time.Time
}
ScanFacts is the slice of a Scan the engine needs.
type SimulateOptions ¶
type SimulateOptions struct {
// RuleIDs (optional) restricts the simulation to a subset of
// rules. Empty means "every rule with trigger=finding.created".
RuleIDs []string
// Window is the (start, end) range to replay. Both inclusive.
Start time.Time
End time.Time
// Trigger names the synthetic event class. Defaults to
// finding.created which is the most operator-useful target.
Trigger rsdk.Trigger
// Limit caps the number of findings replayed; 0 = no cap.
// Default 10_000 to keep the rule_runs table bounded.
Limit int
}
SimulateOptions controls the replay.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package actions ships the built-in action library for the v1.9 rules engine.
|
Package actions ships the built-in action library for the v1.9 rules engine. |
|
Package approvals owns the v1.9 phase 5 multi-approver waiver flow.
|
Package approvals owns the v1.9 phase 5 multi-approver waiver flow. |
|
Package conditions ships the built-in condition library for the v1.9 rules engine.
|
Package conditions ships the built-in condition library for the v1.9 rules engine. |
|
Package expiry runs the v1.9 phase 6 waiver-expiry automation loop.
|
Package expiry runs the v1.9 phase 6 waiver-expiry automation loop. |