Documentation
¶
Index ¶
- Constants
- func AllowedEventType(eventType string) bool
- func CorrelationClass(source, method, containerID string, confidence float64) string
- func IngestFiltered(db *sql.DB, event IngestEvent) (string, error)
- func NativeStreamRunning(paths store.Paths) (bool, error)
- func RebuildEventWindows(db *sql.DB, runID string) (int, error)
- func SelfLaunched(source, bindingSource string) bool
- func TelemetrySource(source string, correlationMethod string) bool
- func ValidateRawPayload(eventType, payload string) error
- func ValidateStoredPayload(eventType, payload string) error
- type BatchRecord
- type CorrelationBinding
- type CorrelationContext
- type CorrelationEvent
- type CorrelationEvidence
- type CorrelationIdentity
- type CorrelationMatch
- type CorrelationReport
- type CorrelationReportOptions
- type EventExplanation
- type EventRecord
- type EventWindow
- type EventWindowFilter
- type EventWindowResult
- type FalcoIngestOptions
- type Filter
- type IngestEvent
- type JSONLIngestOptions
- type JSONLIngestResult
- type ListOptions
- type ListResult
- type NativeStream
- type NativeStreamOptions
- type NativeStreamStatus
- type ProducerCoverageHealth
- type ProducerEventHealth
- type ProducerHealthOptions
- type ProducerHealthReport
- type ProducerLimits
- type ProducerSpoolHealth
- type ReceiverSummary
- type RetentionOptions
- type RetentionResult
- type RowResult
- type SpoolBackpressureError
- type SpoolBatch
- type SpoolEnqueueRequest
- type SpoolProcessResult
- type SpoolProcessedBatch
- type SpoolQueueStats
- type SpoolService
- func (s SpoolService) CountQueued() (int, error)
- func (s SpoolService) Enqueue(req SpoolEnqueueRequest) (SpoolBatch, error)
- func (s SpoolService) List(runID string) ([]SpoolBatch, error)
- func (s SpoolService) Process(limit int) (SpoolProcessResult, error)
- func (s SpoolService) QueueStats() (SpoolQueueStats, error)
Constants ¶
const ProducerHealthSchemaVersion = "agentprovenance.producer_health/v1"
Variables ¶
This section is empty.
Functions ¶
func AllowedEventType ¶
func CorrelationClass ¶ added in v0.2.0
CorrelationClass labels the PROVENANCE of an event's correlation so a security consumer can distinguish a self-join from independent corroboration. It is the correlation-STRENGTH axis only; whether the scope launched the process is a separate, orthogonal fact (see SelfLaunched). The two combine in the UI: a sensor event matched to a self-launched binding is kernel_correlated AND self_launched. It is a pure function of already-stored fields:
- self_observed: we only know about this event because AgentProvenance itself produced the observation (record's own process-tree sampling / file diff / direct record events, or the zero_sdk_process_tree method). There is no independent kernel witness, so its confidence is self-consistency, NOT independent evidence. Keyed on the event SOURCE, not on any synthetic container-id string: a real kernel event that merely matched a record-launched binding is independently witnessed and stays kernel_correlated (that is what SelfLaunched is for).
- context_asserted: the caller provided full run/session/tool_call context; no correlation was performed.
- kernel_correlated: independent system telemetry (Falco/Tetragon/own eBPF sensor) joined to app context through a binding. This is the real claim.
- uncorrelated: could not be resolved.
func IngestFiltered ¶
func IngestFiltered(db *sql.DB, event IngestEvent) (string, error)
func NativeStreamRunning ¶ added in v0.8.0
NativeStreamRunning tests the process-held collector lock; persisted probe reports alone are historical snapshots and cannot establish liveness.
func SelfLaunched ¶ added in v0.5.0
SelfLaunched reports whether the process behind this event was started by AgentProvenance itself (zero-SDK record mode / control-plane launch). It is orthogonal to CorrelationClass: an independently-witnessed kernel event can be self_launched too. It is derived from the event source (record's own events are self-launched by construction) and from the binding_source of the binding the event resolved against, so it survives onto agentprov_ebpf sensor events that matched a record/control-plane binding.
func TelemetrySource ¶
func ValidateRawPayload ¶
func ValidateStoredPayload ¶
Types ¶
type BatchRecord ¶
type BatchRecord struct {
ID string `json:"id"`
RunID string `json:"run_id"`
Format string `json:"format"`
Path string `json:"path"`
FileSHA256 string `json:"file_sha256"`
Read int `json:"read"`
Ingested int `json:"ingested"`
Skipped int `json:"skipped"`
Failed int `json:"failed"`
EventIDsSHA256 string `json:"event_ids_sha256"`
CreatedAt string `json:"created_at"`
}
func ListBatches ¶
func ListBatches(db *sql.DB, runID string) ([]BatchRecord, error)
type CorrelationBinding ¶
type CorrelationBinding struct {
ID string `json:"id"`
RunID string `json:"run_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
AttemptID string `json:"attempt_id,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ProcessID string `json:"process_id,omitempty"`
ContainerID string `json:"container_id,omitempty"`
CgroupID string `json:"cgroup_id,omitempty"`
RootPID int64 `json:"root_pid,omitempty"`
PID int64 `json:"pid,omitempty"`
StartedAt string `json:"started_at,omitempty"`
EndedAt string `json:"ended_at,omitempty"`
BindingSource string `json:"binding_source,omitempty"`
Confidence float64 `json:"confidence"`
IdentityKeys []string `json:"identity_keys,omitempty"`
}
type CorrelationContext ¶
type CorrelationContext struct {
RunID string `json:"run_id,omitempty"`
SessionID string `json:"session_id,omitempty"`
AttemptID string `json:"attempt_id,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
ProcessID string `json:"process_id,omitempty"`
SnapshotID string `json:"snapshot_id,omitempty"`
}
type CorrelationEvent ¶
type CorrelationEvidence ¶
type CorrelationEvidence struct {
Event CorrelationEvent `json:"event"`
RawIdentity CorrelationIdentity `json:"raw_identity"`
ResolvedContext CorrelationContext `json:"resolved_context"`
Binding *CorrelationBinding `json:"binding,omitempty"`
Match CorrelationMatch `json:"match"`
Drilldowns []string `json:"drilldowns,omitempty"`
}
type CorrelationIdentity ¶
type CorrelationIdentity struct {
RunID string `json:"run_id,omitempty"`
ProcessID string `json:"process_id,omitempty"`
ContainerID string `json:"container_id,omitempty"`
CgroupID string `json:"cgroup_id,omitempty"`
PID int64 `json:"pid,omitempty"`
TGID int64 `json:"tgid,omitempty"`
PPID int64 `json:"ppid,omitempty"`
Keys []string `json:"keys,omitempty"`
}
type CorrelationMatch ¶
type CorrelationMatch struct {
Status string `json:"status"`
Method string `json:"method"`
Confidence float64 `json:"confidence"`
BindingID string `json:"binding_id,omitempty"`
MatchedKeys []string `json:"matched_keys,omitempty"`
Reason string `json:"reason"`
TimeWindow string `json:"time_window,omitempty"`
}
type CorrelationReport ¶
type CorrelationReport struct {
SchemaVersion string `json:"schema_version"`
RunID string `json:"run_id,omitempty"`
EventID string `json:"event_id,omitempty"`
ResultSetID string `json:"result_set_id"`
PageHash string `json:"page_hash"`
Count int `json:"count"`
Items []CorrelationEvidence `json:"correlations"`
}
func BuildCorrelationReport ¶
func BuildCorrelationReport(db *sql.DB, opts CorrelationReportOptions) (CorrelationReport, error)
type EventExplanation ¶
type EventExplanation struct {
Receiver string `json:"receiver"`
SourceFormat string `json:"source_format"`
RawEventID string `json:"raw_event_id,omitempty"`
NormalizedEventType string `json:"normalized_event_type"`
SchemaStatus string `json:"schema_status"`
SchemaError string `json:"schema_error,omitempty"`
IdentityKeys []string `json:"identity_keys,omitempty"`
CorrelationMethod string `json:"correlation_method,omitempty"`
CorrelationConfidence float64 `json:"correlation_confidence,omitempty"`
CorrelationClass string `json:"correlation_class,omitempty"`
CorrelationStatus string `json:"correlation_status"`
}
func ExplainEventRecord ¶
func ExplainEventRecord(event EventRecord) EventExplanation
type EventRecord ¶
type EventRecord struct {
ID string `json:"id"`
RunID string `json:"run_id"`
SessionID string `json:"session_id"`
ToolCallID string `json:"tool_call_id"`
ProcessID string `json:"process_id"`
SnapshotID string `json:"snapshot_id"`
RawEventID string `json:"raw_event_id"`
CorrelationMethod string `json:"correlation_method"`
CorrelationConfidence float64 `json:"correlation_confidence"`
CorrelationClass string `json:"correlation_class,omitempty"`
BindingSource string `json:"binding_source,omitempty"`
SelfLaunched bool `json:"self_launched,omitempty"`
ContainerID string `json:"container_id"`
CgroupID string `json:"cgroup_id"`
PID int64 `json:"pid"`
TGID int64 `json:"tgid"`
PPID int64 `json:"ppid"`
Source string `json:"source"`
EventType string `json:"event_type"`
Payload string `json:"payload"`
CreatedAt string `json:"created_at"`
}
func ListEvents ¶
func ListEvents(db *sql.DB, runID, sessionID string) ([]EventRecord, error)
func ListEventsFiltered ¶
func ListEventsFiltered(db *sql.DB, filter Filter) ([]EventRecord, error)
type EventWindow ¶
type EventWindow struct {
RunID string `json:"run_id"`
SessionID string `json:"session_id,omitempty"`
ToolCallID string `json:"tool_call_id,omitempty"`
Source string `json:"source"`
EventType string `json:"event_type"`
WindowSeconds int `json:"window_seconds"`
WindowStart string `json:"window_start"`
EventCount int `json:"event_count"`
ResolvedCount int `json:"resolved_count"`
UnresolvedCount int `json:"unresolved_count"`
HighRiskCount int `json:"high_risk_count"`
UpdatedAt string `json:"updated_at"`
}
type EventWindowFilter ¶
type EventWindowResult ¶
type EventWindowResult struct {
SchemaVersion string `json:"schema_version"`
Filter EventWindowFilter `json:"filter"`
WindowCount int `json:"window_count"`
ResultSetID string `json:"result_set_id"`
PageHash string `json:"page_hash"`
Windows []EventWindow `json:"windows"`
}
func ListEventWindows ¶
func ListEventWindows(db *sql.DB, filter EventWindowFilter) (EventWindowResult, error)
type FalcoIngestOptions ¶
type IngestEvent ¶
type IngestEvent struct {
RunID string
RolloutID string
AttemptID string
SessionID string
ToolCallID string
ProcessID string
SnapshotID string
RawEventID string
ContainerID string
CgroupID string
PID int64
TGID int64
PPID int64
Timestamp string
Source string
EventType string
Payload string
// BindingSource records which binding tier produced this event's
// correlation (e.g. ai_asserted, zero_sdk_record, control_plane). When the
// event is resolved against a stored binding it is overwritten from the
// matched binding; callers with directly-provided context may set it so the
// self-launched dimension is preserved on the provided_context path.
BindingSource string
}
type JSONLIngestOptions ¶
type JSONLIngestOptions struct {
Format string
Path string
RunID string
SessionID string
AttemptID string
ToolCallID string
ProcessID string
SnapshotID string
RolloutID string
// ExcludePathPrefixes drops file-oriented events whose path is under any of
// these prefixes. Used to keep the streaming sensor from observing (and
// ingesting, and thereby generating more of) AgentProvenance's OWN I/O --
// its data-dir snapshot copies and store DB writes -- which otherwise forms
// a self-feedback storm that buries and drops real scope events.
ExcludePathPrefixes []string
// ExcludeCgroupIDs drops events whose cgroup id matches -- typically the
// supervisor's own cgroup, so the sensor never ingests its own process's
// activity. A second, cgroup-granular guard alongside ExcludePathPrefixes.
ExcludeCgroupIDs []string
// scope (method unresolved / confidence 0). The always-on streaming sensor
// sees host-wide activity; events belonging to no ToolCallScope are host
// noise. Persisting them pollutes the store and -- because the ingest batch
// references them -- fails per-run graph verify. Dropping them keeps a
// capture clean and verifiable. Off by default (a per-node security
// deployment may want unattributed activity retained).
DropUncorrelated bool
}
type JSONLIngestResult ¶
type JSONLIngestResult struct {
BatchID string `json:"batch_id,omitempty"`
Format string `json:"format"`
Path string `json:"path"`
FileSHA256 string `json:"file_sha256,omitempty"`
Read int `json:"read"`
Ingested int `json:"ingested"`
Skipped int `json:"skipped"`
Failed int `json:"failed"`
EventIDs []string `json:"event_ids,omitempty"`
EventIDsSHA256 string `json:"event_ids_sha256,omitempty"`
Excluded int `json:"excluded,omitempty"`
Dropped int `json:"dropped_uncorrelated,omitempty"`
PolicyDecisions int `json:"policy_decisions"`
PolicyDecisionIDs []string `json:"policy_decision_ids,omitempty"`
ReceiverSummary ReceiverSummary `json:"receiver_summary"`
Rows []RowResult `json:"row_results,omitempty"`
RowsTruncated bool `json:"row_results_truncated,omitempty"`
Errors []string `json:"errors,omitempty"`
}
func IngestFalco ¶
func IngestFalco(db *sql.DB, opts FalcoIngestOptions, input io.Reader) (JSONLIngestResult, error)
func IngestJSONL ¶
func IngestJSONL(db *sql.DB, opts JSONLIngestOptions) (JSONLIngestResult, error)
func IngestJSONLReader ¶ added in v0.2.0
func IngestJSONLReader(db *sql.DB, opts JSONLIngestOptions, input io.Reader) (JSONLIngestResult, error)
IngestJSONLReader ingests JSONL telemetry from any reader, so the agentprov sensor (or any substrate) can pipe its stdout straight into the receiver (`--file -`) instead of staging a file first. FileSHA256 is computed over the exact bytes streamed, so a pipe and the equivalent saved file hash identically.
type ListOptions ¶
type ListResult ¶
type ListResult struct {
SchemaVersion string `json:"schema_version"`
Filter Filter `json:"filter"`
Limit int `json:"limit"`
Cursor string `json:"cursor,omitempty"`
NextCursor string `json:"next_cursor,omitempty"`
HasMore bool `json:"has_more"`
EventCount int `json:"event_count"`
TotalCount int `json:"total_count"`
ResultSetID string `json:"result_set_id"`
PageHash string `json:"page_hash"`
Events []EventRecord `json:"events"`
}
func ListEventsPage ¶
func ListEventsPage(db *sql.DB, opts ListOptions) (ListResult, error)
type NativeStream ¶ added in v0.8.0
type NativeStream struct {
// contains filtered or unexported fields
}
NativeStream accepts JSONL writes from the sensor, normalizes/redacts them before persistence, fsyncs accepted rows, and seals bounded spool batches. Only counters and one partial JSON line are retained in memory. A store lock prevents two collectors from reclaiming each other's in-flight batches.
func NewNativeStream ¶ added in v0.8.0
func NewNativeStream(db *sql.DB, paths store.Paths, options NativeStreamOptions) (*NativeStream, error)
func (*NativeStream) Close ¶ added in v0.8.0
func (n *NativeStream) Close() error
func (*NativeStream) Flush ¶ added in v0.8.0
func (n *NativeStream) Flush() error
Flush seals live batches. Processing is independent of capture; a slow database fills the bounded disk queue rather than accumulating event IDs.
func (*NativeStream) Process ¶ added in v0.8.0
func (n *NativeStream) Process(limit int) error
func (*NativeStream) Run ¶ added in v0.8.0
func (n *NativeStream) Run(ctx context.Context, report func(error)) error
Run retries all eligible batches fairly: pending batches wait one second, while new batches remain immediately eligible. A failed batch stays queued and its error/counter are durable; shutdown leaves pending rows for restart.
type NativeStreamOptions ¶ added in v0.8.0
type NativeStreamOptions struct {
Ingest JSONLIngestOptions
BatchEvents int
BatchBytes int64
FlushInterval time.Duration
PendingTTL time.Duration
MaxQueuedBytes int64
MaxQueuedBatches int
PolicyEnabled bool
}
NativeStreamOptions bounds both resident memory and the on-disk backlog. PendingTTL starts at capture, not at replay, so restarts cannot renew it.
type NativeStreamStatus ¶ added in v0.8.0
type NativeStreamStatus struct {
Counters map[string]int64 `json:"counters"`
QueuedBatches int `json:"queued_batches"`
QueuedBytes int64 `json:"queued_bytes"`
PendingEvents int64 `json:"pending_events"`
CleanupPendingBatches int `json:"cleanup_pending_batches"`
LastError string `json:"last_error,omitempty"`
}
func ReadNativeStreamStatus ¶ added in v0.8.0
func ReadNativeStreamStatus(db *sql.DB) (NativeStreamStatus, error)
func ReadNativeStreamStatusContext ¶ added in v0.8.0
type ProducerCoverageHealth ¶ added in v0.7.2
type ProducerEventHealth ¶ added in v0.7.2
type ProducerHealthOptions ¶ added in v0.7.2
type ProducerHealthReport ¶ added in v0.7.2
type ProducerHealthReport struct {
SchemaVersion string `json:"schema_version"`
GeneratedAt string `json:"generated_at"`
RunID string `json:"run_id,omitempty"`
Limits ProducerLimits `json:"limits"`
Spool ProducerSpoolHealth `json:"spool"`
Events ProducerEventHealth `json:"events"`
Coverage ProducerCoverageHealth `json:"coverage"`
// NativeCapture is node-wide even when RunID filters the event view: an
// unresolved or dropped row cannot honestly be assigned to a particular run.
NativeCapture NativeStreamStatus `json:"native_node_capture"`
}
func BuildProducerHealth ¶ added in v0.7.2
func BuildProducerHealth(db *sql.DB, opts ProducerHealthOptions) (ProducerHealthReport, error)
type ProducerLimits ¶ added in v0.7.2
type ProducerSpoolHealth ¶ added in v0.7.2
type ProducerSpoolHealth struct {
ReceivedBatches int `json:"received_batches"`
QueuedBatches int `json:"queued_batches"`
QueuedBytes int64 `json:"queued_bytes"`
ProcessingBatches int `json:"processing_batches"`
ProcessedBatches int `json:"processed_batches"`
DroppedBatches int `json:"dropped_batches"`
DroppedBytes int64 `json:"dropped_bytes"`
FailedBatches int `json:"failed_batches"`
IngestedEvents int `json:"ingested_events"`
FailedEvents int `json:"failed_events"`
ByStatus map[string]int `json:"by_status"`
}
type ReceiverSummary ¶
type ReceiverSummary struct {
DetectedFormats map[string]int `json:"detected_formats,omitempty"`
EventTypes map[string]int `json:"event_types,omitempty"`
IdentityKeys map[string]int `json:"identity_keys,omitempty"`
Resolved int `json:"resolved"`
Unresolved int `json:"unresolved"`
Skipped int `json:"skipped"`
Failed int `json:"failed"`
}
type RetentionOptions ¶
type RetentionResult ¶
type RetentionResult struct {
SchemaVersion string `json:"schema_version"`
RunID string `json:"run_id,omitempty"`
Cutoff string `json:"cutoff"`
MaxDelete int `json:"max_delete"`
Scanned int `json:"scanned"`
Deleted int `json:"deleted"`
Protected int `json:"protected"`
DeletedIDs []string `json:"deleted_ids,omitempty"`
}
func PruneRawEvents ¶
func PruneRawEvents(db *sql.DB, opts RetentionOptions) (RetentionResult, error)
type RowResult ¶
type RowResult struct {
Line int `json:"line"`
Status string `json:"status"`
DetectedFormat string `json:"detected_format,omitempty"`
EventID string `json:"event_id,omitempty"`
EventType string `json:"event_type,omitempty"`
Source string `json:"source,omitempty"`
RawEventID string `json:"raw_event_id,omitempty"`
IdentityKeys []string `json:"identity_keys,omitempty"`
CorrelationMethod string `json:"correlation_method,omitempty"`
Error string `json:"error,omitempty"`
}
type SpoolBackpressureError ¶
type SpoolBackpressureError struct {
Queued int `json:"queued"`
QueuedBytes int64 `json:"queued_bytes"`
IncomingBytes int64 `json:"incoming_bytes"`
MaxQueued int `json:"max_queued"`
MaxQueuedBytes int64 `json:"max_queued_bytes"`
MaxBatchBytes int64 `json:"max_batch_bytes"`
Reason string `json:"reason"`
}
func (SpoolBackpressureError) Error ¶
func (e SpoolBackpressureError) Error() string
type SpoolBatch ¶
type SpoolBatch struct {
ID string `json:"id"`
RunID string `json:"run_id"`
Format string `json:"format"`
SourcePath string `json:"source_path"`
SpoolPath string `json:"spool_path"`
FileSHA256 string `json:"file_sha256"`
SizeBytes int64 `json:"size_bytes"`
Status string `json:"status"`
Priority int `json:"priority"`
Attempts int `json:"attempts"`
PolicyEnabled bool `json:"policy_enabled"`
IngestBatchID string `json:"ingest_batch_id"`
IngestedCount int `json:"ingested_count"`
FailedCount int `json:"failed_count"`
Error string `json:"error"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
ProcessedAt string `json:"processed_at"`
DroppedAt string `json:"dropped_at"`
DropReason string `json:"drop_reason"`
}
type SpoolEnqueueRequest ¶
type SpoolProcessResult ¶
type SpoolProcessResult struct {
Processed int `json:"processed"`
Failed int `json:"failed"`
Batches []SpoolProcessedBatch `json:"batches,omitempty"`
Errors []string `json:"errors,omitempty"`
}
type SpoolProcessedBatch ¶
type SpoolQueueStats ¶ added in v0.7.2
type SpoolService ¶
func (SpoolService) CountQueued ¶
func (s SpoolService) CountQueued() (int, error)
func (SpoolService) Enqueue ¶
func (s SpoolService) Enqueue(req SpoolEnqueueRequest) (SpoolBatch, error)
func (SpoolService) List ¶
func (s SpoolService) List(runID string) ([]SpoolBatch, error)
func (SpoolService) Process ¶
func (s SpoolService) Process(limit int) (SpoolProcessResult, error)
func (SpoolService) QueueStats ¶ added in v0.7.2
func (s SpoolService) QueueStats() (SpoolQueueStats, error)