ioc

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: GPL-3.0 Imports: 11 Imported by: 0

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

type TelemetryEvent struct {
	ID         shared.ID
	EventType  string
	Properties map[string]any
}

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL