chore: add copyright headers, CI tests, and sanitize gitignore

This commit is contained in:
DmitrL-dev 2026-03-31 22:13:34 +10:00
parent 5cbb3d89d3
commit d1f844235e
325 changed files with 2267 additions and 902 deletions

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -16,13 +20,13 @@ import (
// timeout: 5m — force embedding mode after 5 minutes even if <50 events
// min_events_for_embedding: 50
type AlertCluster struct {
ID string `json:"id"`
Events []string `json:"events"` // Event IDs
Category string `json:"category"` // Dominant category
Severity string `json:"severity"` // Max severity
Source string `json:"source"` // Dominant source
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ID string `json:"id"`
Events []string `json:"events"` // Event IDs
Category string `json:"category"` // Dominant category
Severity string `json:"severity"` // Max severity
Source string `json:"source"` // Dominant source
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// ClusterEngine groups related alerts using configurable strategies.
@ -68,8 +72,8 @@ func DefaultClusterConfig() ClusterConfig {
type ClusterMode int
const (
ClusterModeColdStart ClusterMode = iota // Temporal+session_id fallback
ClusterModeEmbedding // Full embedding-based clustering
ClusterModeColdStart ClusterMode = iota // Temporal+session_id fallback
ClusterModeEmbedding // Full embedding-based clustering
)
func (m ClusterMode) String() string {
@ -247,14 +251,14 @@ func (ce *ClusterEngine) Stats() map[string]any {
}
return map[string]any{
"mode": ce.mode.String(),
"ui_hint": uiHint,
"total_clusters": len(ce.clusters),
"total_events": totalEvents,
"avg_cluster_size": avgSize,
"max_cluster_size": maxSize,
"events_processed": ce.eventCount,
"embedding_model": ce.config.EmbeddingModel,
"mode": ce.mode.String(),
"ui_hint": uiHint,
"total_clusters": len(ce.clusters),
"total_events": totalEvents,
"avg_cluster_size": avgSize,
"max_cluster_size": maxSize,
"events_processed": ce.eventCount,
"embedding_model": ce.config.EmbeddingModel,
"cold_start_threshold": ce.config.MinEventsForEmbedding,
}
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -12,8 +16,8 @@ import (
type SOCCorrelationRule struct {
ID string `json:"id"`
Name string `json:"name"`
RequiredCategories []string `json:"required_categories"` // Co-occurrence (unordered)
SequenceCategories []string `json:"sequence_categories"` // Temporal sequence (ordered A→B→C)
RequiredCategories []string `json:"required_categories"` // Co-occurrence (unordered)
SequenceCategories []string `json:"sequence_categories"` // Temporal sequence (ordered A→B→C)
SeverityTrend string `json:"severity_trend,omitempty"` // "ascending" — detect escalation pattern
TrendCategory string `json:"trend_category,omitempty"` // Category to track for severity trend
MinEvents int `json:"min_events"`

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import "errors"

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
// Package soc defines domain entities for the SENTINEL AI SOC subsystem.
// SOC extends gomcp's alert/oracle layer with multi-source event ingestion,
// incident management, sensor lifecycle, and compliance reporting.
@ -77,7 +81,7 @@ type SOCEvent struct {
Description string `json:"description"`
Payload string `json:"payload,omitempty"` // Raw input for Secret Scanner Step 0
SessionID string `json:"session_id,omitempty"`
ContentHash string `json:"content_hash,omitempty"` // SHA-256 dedup key (§5.2)
ContentHash string `json:"content_hash,omitempty"` // SHA-256 dedup key (§5.2)
DecisionHash string `json:"decision_hash,omitempty"` // SHA-256 chain link
Verdict Verdict `json:"verdict"`
ZeroGMode bool `json:"zero_g_mode,omitempty"` // §13.4: Strike Force operation tag
@ -97,30 +101,30 @@ func (e *SOCEvent) ComputeContentHash() string {
// KnownCategories is the set of recognized event categories.
// Events with unknown categories are still accepted but logged as warnings.
var KnownCategories = map[string]bool{
"jailbreak": true,
"prompt_injection": true,
"tool_abuse": true,
"exfiltration": true,
"pii_leak": true,
"auth_bypass": true,
"encoding": true,
"persistence": true,
"sensor_anomaly": true,
"dos": true,
"model_theft": true,
"supply_chain": true,
"data_poisoning": true,
"evasion": true,
"shadow_ai_usage": true,
"jailbreak": true,
"prompt_injection": true,
"tool_abuse": true,
"exfiltration": true,
"pii_leak": true,
"auth_bypass": true,
"encoding": true,
"persistence": true,
"sensor_anomaly": true,
"dos": true,
"model_theft": true,
"supply_chain": true,
"data_poisoning": true,
"evasion": true,
"shadow_ai_usage": true,
"integration_health": true,
"other": true,
"other": true,
// GenAI EDR categories (SDD-001)
"genai_child_process": true,
"genai_child_process": true,
"genai_sensitive_file_access": true,
"genai_unusual_domain": true,
"genai_credential_access": true,
"genai_persistence": true,
"genai_config_modification": true,
"genai_unusual_domain": true,
"genai_credential_access": true,
"genai_persistence": true,
"genai_config_modification": true,
}
// ValidSeverity returns true if the severity is a known value.
@ -217,4 +221,3 @@ func (e SOCEvent) WithVerdict(v Verdict) SOCEvent {
func (e SOCEvent) IsCritical() bool {
return e.Severity == SeverityHigh || e.Severity == SeverityCritical
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -281,8 +285,8 @@ func (e *NotifyExecutor) Execute(params ActionParams) (string, error) {
// QuarantineExecutor marks a session or IP as quarantined.
// Maintains an in-memory blocklist and logs quarantine actions.
type QuarantineExecutor struct {
mu sync.RWMutex
blocklist map[string]time.Time // IP/session → quarantine expiry
mu sync.RWMutex
blocklist map[string]time.Time // IP/session → quarantine expiry
}
func NewQuarantineExecutor() *QuarantineExecutor {
@ -446,4 +450,3 @@ func (h *ExecutorActionHandler) Handle(action PlaybookAction, incidentID string)
)
return nil
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
// GenAI Process Monitoring & Detection
@ -58,11 +62,11 @@ var LLMDNSEndpoints = []string{
// GenAI event categories for the SOC event bus.
const (
CategoryGenAIChildProcess = "genai_child_process"
CategoryGenAISensitiveFile = "genai_sensitive_file_access"
CategoryGenAIUnusualDomain = "genai_unusual_domain"
CategoryGenAICredentialAccess = "genai_credential_access"
CategoryGenAIPersistence = "genai_persistence"
CategoryGenAIChildProcess = "genai_child_process"
CategoryGenAISensitiveFile = "genai_sensitive_file_access"
CategoryGenAIUnusualDomain = "genai_unusual_domain"
CategoryGenAICredentialAccess = "genai_credential_access"
CategoryGenAIPersistence = "genai_persistence"
CategoryGenAIConfigModification = "genai_config_modification"
)

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import "time"

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -146,8 +150,8 @@ func TestGenAIChildProcessRule(t *testing.T) {
events := []SOCEvent{
{
Source: SourceImmune,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Timestamp: now.Add(-30 * time.Second),
Metadata: map[string]string{
"parent_process": "claude",
@ -170,14 +174,14 @@ func TestGenAISuspiciousDescendantRule(t *testing.T) {
events := []SOCEvent{
{
Source: SourceImmune,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Timestamp: now.Add(-3 * time.Minute),
},
{
Source: SourceImmune,
Category: "tool_abuse",
Severity: SeverityMedium,
Category: "tool_abuse",
Severity: SeverityMedium,
Timestamp: now.Add(-1 * time.Minute),
},
}
@ -196,14 +200,14 @@ func TestGenAICredentialAccessRule(t *testing.T) {
events := []SOCEvent{
{
Source: SourceImmune,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Timestamp: now.Add(-1 * time.Minute),
},
{
Source: SourceImmune,
Category: CategoryGenAICredentialAccess,
Severity: SeverityCritical,
Category: CategoryGenAICredentialAccess,
Severity: SeverityCritical,
Timestamp: now.Add(-30 * time.Second),
Metadata: map[string]string{
"file_path": "/home/user/.config/google-chrome/Default/Login Data",
@ -238,14 +242,14 @@ func TestGenAIPersistenceRule(t *testing.T) {
events := []SOCEvent{
{
Source: SourceImmune,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Category: CategoryGenAIChildProcess,
Severity: SeverityInfo,
Timestamp: now.Add(-8 * time.Minute),
},
{
Source: SourceImmune,
Category: CategoryGenAIPersistence,
Severity: SeverityHigh,
Category: CategoryGenAIPersistence,
Severity: SeverityHigh,
Timestamp: now.Add(-2 * time.Minute),
},
}
@ -264,8 +268,8 @@ func TestGenAIConfigModificationRule(t *testing.T) {
events := []SOCEvent{
{
Source: SourceImmune,
Category: CategoryGenAIConfigModification,
Severity: SeverityMedium,
Category: CategoryGenAIConfigModification,
Severity: SeverityMedium,
Timestamp: now.Add(-2 * time.Minute),
},
}
@ -282,8 +286,8 @@ func TestGenAINonGenAIProcessIgnored(t *testing.T) {
events := []SOCEvent{
{
Source: SourceSentinelCore,
Category: "prompt_injection",
Severity: SeverityHigh,
Category: "prompt_injection",
Severity: SeverityHigh,
Timestamp: now.Add(-1 * time.Minute),
},
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -22,13 +26,13 @@ type GhostSinkhole struct {
type SinkholeResponse struct {
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
Category string `json:"category"` // Threat category that triggered sinkhole
OriginalHash string `json:"original_hash"` // SHA-256 of original request (redacted)
DecoyContent string `json:"decoy_content"` // Fake response that was served
TTPs map[string]string `json:"ttps"` // Captured attacker techniques
Category string `json:"category"` // Threat category that triggered sinkhole
OriginalHash string `json:"original_hash"` // SHA-256 of original request (redacted)
DecoyContent string `json:"decoy_content"` // Fake response that was served
TTPs map[string]string `json:"ttps"` // Captured attacker techniques
SourceIP string `json:"source_ip,omitempty"`
UserAgent string `json:"user_agent,omitempty"`
DecoyTemplate string `json:"decoy_template"` // Which template was used
DecoyTemplate string `json:"decoy_template"` // Which template was used
}
type sinkholeTemplate struct {
@ -157,11 +161,11 @@ func (gs *GhostSinkhole) Stats() map[string]any {
}
return map[string]any{
"total_decoys": len(gs.responses),
"by_category": byCategory,
"by_template": byTemplate,
"buffer_size": gs.maxStore,
"buffer_usage": fmt.Sprintf("%.1f%%", float64(len(gs.responses))/float64(gs.maxStore)*100),
"total_decoys": len(gs.responses),
"by_category": byCategory,
"by_template": byTemplate,
"buffer_size": gs.maxStore,
"buffer_usage": fmt.Sprintf("%.1f%%", float64(len(gs.responses))/float64(gs.maxStore)*100),
}
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -26,34 +30,34 @@ type IncidentNote struct {
// TimelineEntry represents a single event in the incident timeline.
type TimelineEntry struct {
Timestamp time.Time `json:"timestamp"`
Type string `json:"type"` // event, playbook, status_change, note, assign
Actor string `json:"actor"` // system, analyst name, playbook ID
Description string `json:"description"`
Timestamp time.Time `json:"timestamp"`
Type string `json:"type"` // event, playbook, status_change, note, assign
Actor string `json:"actor"` // system, analyst name, playbook ID
Description string `json:"description"`
Metadata map[string]any `json:"metadata,omitempty"`
}
// Incident represents a correlated security incident aggregated from multiple SOCEvents.
// Each incident maintains a cryptographic anchor to the Decision Logger hash chain.
type Incident struct {
ID string `json:"id"` // INC-YYYY-NNNN
TenantID string `json:"tenant_id,omitempty"`
Status IncidentStatus `json:"status"`
Severity EventSeverity `json:"severity"` // Max severity of constituent events
Title string `json:"title"`
Description string `json:"description"`
Events []string `json:"events"` // Event IDs
EventCount int `json:"event_count"`
DecisionChainAnchor string `json:"decision_chain_anchor"` // SHA-256 hash (§5.6)
ChainLength int `json:"chain_length"`
CorrelationRule string `json:"correlation_rule"` // Rule that triggered this incident
KillChainPhase string `json:"kill_chain_phase"` // Reconnaissance/Exploitation/Exfiltration
MITREMapping []string `json:"mitre_mapping"` // T-codes
PlaybookApplied string `json:"playbook_applied,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
AssignedTo string `json:"assigned_to,omitempty"`
ID string `json:"id"` // INC-YYYY-NNNN
TenantID string `json:"tenant_id,omitempty"`
Status IncidentStatus `json:"status"`
Severity EventSeverity `json:"severity"` // Max severity of constituent events
Title string `json:"title"`
Description string `json:"description"`
Events []string `json:"events"` // Event IDs
EventCount int `json:"event_count"`
DecisionChainAnchor string `json:"decision_chain_anchor"` // SHA-256 hash (§5.6)
ChainLength int `json:"chain_length"`
CorrelationRule string `json:"correlation_rule"` // Rule that triggered this incident
KillChainPhase string `json:"kill_chain_phase"` // Reconnaissance/Exploitation/Exfiltration
MITREMapping []string `json:"mitre_mapping"` // T-codes
PlaybookApplied string `json:"playbook_applied,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
AssignedTo string `json:"assigned_to,omitempty"`
Notes []IncidentNote `json:"notes,omitempty"`
Timeline []TimelineEntry `json:"timeline,omitempty"`
}
@ -198,4 +202,3 @@ func (inc *Incident) MTTR() time.Duration {
}
return inc.ResolvedAt.Sub(inc.CreatedAt)
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -20,14 +24,14 @@ type P2PSyncService struct {
// SOCPeer represents a connected SOC peer node.
type SOCPeer struct {
ID string `json:"id"`
Name string `json:"name"`
Endpoint string `json:"endpoint"`
Status string `json:"status"` // connected, disconnected, syncing
LastSync time.Time `json:"last_sync"`
EventsSent int `json:"events_sent"`
EventsRecv int `json:"events_recv"`
TrustLevel string `json:"trust_level"` // full, partial, readonly
ID string `json:"id"`
Name string `json:"name"`
Endpoint string `json:"endpoint"`
Status string `json:"status"` // connected, disconnected, syncing
LastSync time.Time `json:"last_sync"`
EventsSent int `json:"events_sent"`
EventsRecv int `json:"events_recv"`
TrustLevel string `json:"trust_level"` // full, partial, readonly
}
// SyncMessage is a SOC data unit exchanged between peers.
@ -43,10 +47,10 @@ type SyncMessage struct {
type SyncMessageType string
const (
SyncEvent SyncMessageType = "EVENT"
SyncIncident SyncMessageType = "INCIDENT"
SyncIOC SyncMessageType = "IOC"
SyncRule SyncMessageType = "RULE"
SyncEvent SyncMessageType = "EVENT"
SyncIncident SyncMessageType = "INCIDENT"
SyncIOC SyncMessageType = "IOC"
SyncRule SyncMessageType = "RULE"
SyncHeartbeat SyncMessageType = "HEARTBEAT"
)

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import "time"

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -14,12 +18,12 @@ type DataRetentionPolicy struct {
// RetentionRule defines how long data of a given type is kept.
type RetentionRule struct {
DataType string `json:"data_type"` // events, incidents, audit, anomaly_alerts
RetainDays int `json:"retain_days"` // Max age in days
Action string `json:"action"` // archive, delete, compress
Enabled bool `json:"enabled"`
LastRun time.Time `json:"last_run"`
ItemsPurged int `json:"items_purged"`
DataType string `json:"data_type"` // events, incidents, audit, anomaly_alerts
RetainDays int `json:"retain_days"` // Max age in days
Action string `json:"action"` // archive, delete, compress
Enabled bool `json:"enabled"`
LastRun time.Time `json:"last_run"`
ItemsPurged int `json:"items_purged"`
}
// NewDataRetentionPolicy creates default retention rules.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -42,13 +46,13 @@ type IOC struct {
// Feed represents a threat intelligence source.
type Feed struct {
Name string `json:"name"`
URL string `json:"url"`
Type string `json:"type"` // stix, csv, json
Enabled bool `json:"enabled"`
IOCCount int `json:"ioc_count"`
LastSync time.Time `json:"last_sync"`
SyncInterval string `json:"sync_interval"`
Name string `json:"name"`
URL string `json:"url"`
Type string `json:"type"` // stix, csv, json
Enabled bool `json:"enabled"`
IOCCount int `json:"ioc_count"`
LastSync time.Time `json:"last_sync"`
SyncInterval string `json:"sync_interval"`
}
// IOCHit records a match between an event and an IOC.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -23,12 +27,12 @@ const (
// WebhookConfig defines a webhook destination.
type WebhookConfig struct {
ID string `yaml:"id" json:"id"`
URL string `yaml:"url" json:"url"`
ID string `yaml:"id" json:"id"`
URL string `yaml:"url" json:"url"`
Events []WebhookEventType `yaml:"events" json:"events"`
Headers map[string]string `yaml:"headers" json:"headers"`
Active bool `yaml:"active" json:"active"`
Retries int `yaml:"retries" json:"retries"`
Headers map[string]string `yaml:"headers" json:"headers"`
Active bool `yaml:"active" json:"active"`
Retries int `yaml:"retries" json:"retries"`
}
// WebhookPayload is the JSON body sent to webhook endpoints.

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (
@ -18,17 +22,17 @@ type ZeroGMode struct {
// ZeroGRequest represents a pending approval request.
type ZeroGRequest struct {
ID string `json:"id"`
EventID string `json:"event_id"`
IncidentID string `json:"incident_id,omitempty"`
Action string `json:"action"` // What would auto-execute
Severity string `json:"severity"`
Description string `json:"description"`
Status ZeroGStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
ResolvedBy string `json:"resolved_by,omitempty"`
Verdict ZeroGVerdict `json:"verdict,omitempty"`
ID string `json:"id"`
EventID string `json:"event_id"`
IncidentID string `json:"incident_id,omitempty"`
Action string `json:"action"` // What would auto-execute
Severity string `json:"severity"`
Description string `json:"description"`
Status ZeroGStatus `json:"status"`
CreatedAt time.Time `json:"created_at"`
ResolvedAt *time.Time `json:"resolved_at,omitempty"`
ResolvedBy string `json:"resolved_by,omitempty"`
Verdict ZeroGVerdict `json:"verdict,omitempty"`
}
// ZeroGStatus tracks the request lifecycle.
@ -174,11 +178,11 @@ func (z *ZeroGMode) Stats() map[string]any {
}
return map[string]any{
"enabled": z.enabled,
"pending": len(z.queue),
"total_resolved": len(z.resolved),
"approved": approved,
"denied": denied,
"expired": expired,
"enabled": z.enabled,
"pending": len(z.queue),
"total_resolved": len(z.resolved),
"approved": approved,
"denied": denied,
"expired": expired,
}
}

View file

@ -1,3 +1,7 @@
// Copyright 2026 Syntrex Lab. All rights reserved.
// Use of this source code is governed by an Apache-2.0 license
// that can be found in the LICENSE file.
package soc
import (