Documentation
¶
Overview ¶
Package ioc wires Indicators of Compromise to the runtime telemetry stream. When an agent reports an event whose properties match a known IOC, the source finding is auto-reopened — the loop edge named "invariant B6" in the CTEM model.
The correlator is deliberately passive: it never deletes telemetry, never alters the event, and records every match in ioc_matches so an operator can answer "why was this finding reopened?" after the fact.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExtractCandidates ¶
func ExtractCandidates(event TelemetryEvent) []iocdom.Candidate
ExtractCandidates pulls every IOC-matchable token out of an event's properties. Kept as a package-level function so the postgres ingest path + tests can reuse the exact same extraction logic without instantiating a Correlator.
Property keys come from pkg/domain/telemetry — the agent wire contract. Unknown properties are ignored (whitelist) so a garbage field in properties can't generate false candidate IOCs.
Types ¶
type AuditLogger ¶
type AuditLogger interface {
LogEvent(ctx context.Context, actx app.AuditContext, event app.AuditEvent) error
}
AuditLogger is the narrow surface the adapter uses to record the reopen. *app.AuditService satisfies it structurally.
type Correlator ¶
type Correlator struct {
// contains filtered or unexported fields
}
Correlator consumes (tenantID, telemetry event) pairs and fires match + reopen side effects.
func NewCorrelator ¶
func NewCorrelator(iocs iocdom.Repository, reopener FindingReopener, log *logger.Logger) *Correlator
NewCorrelator wires deps.
func (*Correlator) Correlate ¶
func (c *Correlator) Correlate( ctx context.Context, tenantID shared.ID, event TelemetryEvent, ) ([]*iocdom.Indicator, error)
Correlate scans one telemetry event against the tenant's active IOC catalogue, records a match for each hit, and reopens any closed source finding the IOC points at.
Returns the matched indicators so callers that want to surface the hit count on a dashboard can do so. Errors are logged and continued-through per-IOC — one bad finding update must not block the other matches in the same event.
func (*Correlator) CorrelateBatch ¶
func (c *Correlator) CorrelateBatch( ctx context.Context, tenantID shared.ID, events []TelemetryEvent, ) (map[shared.ID][]*iocdom.Indicator, error)
CorrelateBatch correlates N events in ONE IOC lookup instead of N. The handler should use this for agent batches (up to 100 events) so the ingest path is not N DB roundtrips.
Per-event error isolation preserved: a hit on event A that fails its reopen never blocks the match row on event B.
Returns a map keyed by telemetry event ID → the indicators that matched THAT event, so callers can build per-event metrics.
type FindingReopener ¶
type FindingReopener interface {
ReopenForIOCMatch(ctx context.Context, tenantID, findingID shared.ID, reason string) (reopened bool, err error)
}
FindingReopener is the narrow surface the correlator needs to reopen a closed finding when an IOC fires. The implementation is expected to:
- no-op when the finding is already open (not closed)
- transition closed → in_progress atomically
- emit an audit event describing the reopen
- return (true, nil) when a real reopen happened; (false, nil) when the finding was already open
Kept here as an interface so the correlator does not drag the full FindingActionsService into its import graph; the wire-up passes a thin adapter.
func NewFindingReopener ¶
func NewFindingReopener(repo FindingRepo, auditor AuditLogger) FindingReopener
NewFindingReopener returns a FindingReopener backed by the real finding repo + audit service. Pass a nil auditor to skip audit logging (not recommended; B6 promises an audit trail).
type FindingRepo ¶
type FindingRepo interface {
GetByID(ctx context.Context, tenantID, id shared.ID) (*vulnerability.Finding, error)
Update(ctx context.Context, f *vulnerability.Finding) error
}
FindingRepo is the narrow surface the adapter needs — load + persist. *postgres.FindingRepository satisfies it structurally.
type TelemetryEvent ¶
TelemetryEvent is the minimal shape the correlator needs from a runtime_telemetry_events row. The handler already has the full row; it projects down to this struct before calling Correlate so the correlator does not depend on the telemetry storage layout.