mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-05-18 13:45:13 +02:00
chore: add copyright headers, CI tests, and sanitize gitignore
This commit is contained in:
parent
5cbb3d89d3
commit
d1f844235e
325 changed files with 2267 additions and 902 deletions
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue