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 antitamper implements SEC-005 Anti-Tamper Protection.
//
// Provides runtime protection against:
@ -26,11 +30,11 @@ import (
type TamperType string
const (
TamperDebugger TamperType = "debugger_attached"
TamperPtrace TamperType = "ptrace_attempt"
TamperBinaryMod TamperType = "binary_modified"
TamperEnvTamper TamperType = "env_tampering"
TamperMemoryDump TamperType = "memory_dump"
TamperDebugger TamperType = "debugger_attached"
TamperPtrace TamperType = "ptrace_attempt"
TamperBinaryMod TamperType = "binary_modified"
TamperEnvTamper TamperType = "env_tampering"
TamperMemoryDump TamperType = "memory_dump"
// CheckInterval for periodic integrity verification.
DefaultCheckInterval = 5 * time.Minute
@ -51,24 +55,24 @@ type TamperHandler func(event TamperEvent)
// Shield provides anti-tamper protection for SOC processes.
type Shield struct {
mu sync.RWMutex
binaryPath string
binaryHash string // SHA-256 at startup
envSnapshot map[string]string
handlers []TamperHandler
logger *slog.Logger
stats ShieldStats
mu sync.RWMutex
binaryPath string
binaryHash string // SHA-256 at startup
envSnapshot map[string]string
handlers []TamperHandler
logger *slog.Logger
stats ShieldStats
}
// ShieldStats tracks anti-tamper metrics.
type ShieldStats struct {
mu sync.Mutex
TotalChecks int64 `json:"total_checks"`
TamperDetected int64 `json:"tamper_detected"`
DebuggerBlocked int64 `json:"debugger_blocked"`
BinaryIntegrity bool `json:"binary_integrity"`
LastCheck time.Time `json:"last_check"`
StartedAt time.Time `json:"started_at"`
mu sync.Mutex
TotalChecks int64 `json:"total_checks"`
TamperDetected int64 `json:"tamper_detected"`
DebuggerBlocked int64 `json:"debugger_blocked"`
BinaryIntegrity bool `json:"binary_integrity"`
LastCheck time.Time `json:"last_check"`
StartedAt time.Time `json:"started_at"`
}
// NewShield creates a new anti-tamper shield.

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 antitamper
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.
//go:build !windows
package antitamper

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.
//go:build windows
package antitamper
@ -10,7 +14,7 @@ import (
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
kernel32 = syscall.NewLazyDLL("kernel32.dll")
isDebuggerPresent = kernel32.NewProc("IsDebuggerPresent")
)
@ -41,7 +45,7 @@ func (s *Shield) isDebuggerAttached() bool {
// Check parent process name for known debuggers.
// This is a heuristic — not foolproof.
_ = strings.Contains // suppress unused import
_ = strings.Contains // suppress unused import
_ = unsafe.Pointer(nil) // suppress unused import
return false

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 audit
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 audit
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 audit
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 audit provides an append-only audit trail for Zero-G operations.
// The audit logger writes to .rlm/zero_g.audit with O_APPEND semantics,
// making programmatic deletion of records impossible.

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 audit
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 audit
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 auth
import (
@ -62,13 +66,13 @@ func SeedDemoTenant(userStore *UserStore, tenantStore *TenantStore, socRepo doms
// 2. Create demo tenant (demo plan 1000 events max)
demoTenant := &Tenant{
ID: DemoTenantID,
Name: "SYNTREX Demo",
Slug: "demo",
PlanID: "demo",
OwnerUserID: demoUser.ID,
Active: true,
CreatedAt: time.Now(),
ID: DemoTenantID,
Name: "SYNTREX Demo",
Slug: "demo",
PlanID: "demo",
OwnerUserID: demoUser.ID,
Active: true,
CreatedAt: time.Now(),
MonthResetAt: monthStart(time.Now().AddDate(0, 1, 0)),
}

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 auth
import (
@ -31,7 +35,9 @@ func HandleLogin(store *UserStore, secret []byte) http.HandlerFunc {
email := req.Email
if email == "" {
// Try legacy format
var legacy struct{ Username string `json:"username"` }
var legacy struct {
Username string `json:"username"`
}
email = legacy.Username
}

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 auth provides JWT authentication for the SOC HTTP API.
// Uses HMAC-SHA256 (HS256) with configurable secret.
// Zero external dependencies — pure Go stdlib.
@ -16,21 +20,21 @@ import (
// Standard JWT errors.
var (
ErrInvalidToken = errors.New("auth: invalid token")
ErrExpiredToken = errors.New("auth: token expired")
ErrInvalidSecret = errors.New("auth: secret too short (min 32 bytes)")
ErrWrongTokenType = errors.New("auth: wrong token type")
ErrInvalidToken = errors.New("auth: invalid token")
ErrExpiredToken = errors.New("auth: token expired")
ErrInvalidSecret = errors.New("auth: secret too short (min 32 bytes)")
ErrWrongTokenType = errors.New("auth: wrong token type")
)
// Claims represents JWT payload.
type Claims struct {
Sub string `json:"sub"` // Subject (username or user ID)
Role string `json:"role"` // RBAC role: admin, operator, analyst, viewer
TenantID string `json:"tenant_id,omitempty"` // Multi-tenant isolation
Sub string `json:"sub"` // Subject (username or user ID)
Role string `json:"role"` // RBAC role: admin, operator, analyst, viewer
TenantID string `json:"tenant_id,omitempty"` // Multi-tenant isolation
TokenType string `json:"token_type,omitempty"` // "access" or "refresh"
Exp int64 `json:"exp"` // Expiration (Unix timestamp)
Iat int64 `json:"iat"` // Issued at
Iss string `json:"iss,omitempty"` // Issuer
Exp int64 `json:"exp"` // Expiration (Unix timestamp)
Iat int64 `json:"iat"` // Issued at
Iss string `json:"iss,omitempty"` // Issuer
}
// IsExpired returns true if the token has 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 auth
import (
@ -37,9 +41,9 @@ func TestSign_Verify_RoundTrip(t *testing.T) {
func TestVerify_ExpiredToken(t *testing.T) {
token, _ := Sign(Claims{
Sub: "user",
Sub: "user",
Role: "viewer",
Exp: time.Now().Add(-time.Hour).Unix(),
Exp: time.Now().Add(-time.Hour).Unix(),
}, testSecret)
_, err := Verify(token, testSecret)
@ -50,9 +54,9 @@ func TestVerify_ExpiredToken(t *testing.T) {
func TestVerify_InvalidSignature(t *testing.T) {
token, _ := Sign(Claims{
Sub: "user",
Sub: "user",
Role: "viewer",
Exp: time.Now().Add(time.Hour).Unix(),
Exp: time.Now().Add(time.Hour).Unix(),
}, testSecret)
wrongSecret := []byte("wrong-secret-that-is-also-32-bytes-x")

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 auth
import (
@ -13,7 +17,7 @@ const claimsKey ctxKey = "jwt_claims"
// JWTMiddleware validates Bearer tokens on protected routes.
type JWTMiddleware struct {
secret []byte
secret []byte
// PublicPaths are exempt from auth (e.g., /health, /api/auth/login).
PublicPaths map[string]bool
}
@ -23,23 +27,23 @@ func NewJWTMiddleware(secret []byte) *JWTMiddleware {
return &JWTMiddleware{
secret: secret,
PublicPaths: map[string]bool{
"/health": true,
"/healthz": true,
"/readyz": true,
"/metrics": true,
"/api/auth/login": true,
"/api/auth/logout": true,
"/api/auth/refresh": true,
"/api/auth/register": true,
"/api/auth/verify": true,
"/api/auth/plans": true,
"/api/auth/demo": true,
"/api/v1/scan": true, // public demo scanner
"/api/v1/usage": true, // public usage/quota check
"/api/v1/soc/events": true, // sensor ingest (auth via RBAC API key when enabled)
"/health": true,
"/healthz": true,
"/readyz": true,
"/metrics": true,
"/api/auth/login": true,
"/api/auth/logout": true,
"/api/auth/refresh": true,
"/api/auth/register": true,
"/api/auth/verify": true,
"/api/auth/plans": true,
"/api/auth/demo": true,
"/api/v1/scan": true, // public demo scanner
"/api/v1/usage": true, // public usage/quota check
"/api/v1/soc/events": true, // sensor ingest (auth via RBAC API key when enabled)
"/api/soc/events/stream": true, // SSE uses query param auth
"/api/soc/stream": true, // SSE live feed (EventSource can't send headers)
"/api/soc/ws": true, // WebSocket-style SSE push
"/api/soc/stream": true, // SSE live feed (EventSource can't send headers)
"/api/soc/ws": true, // WebSocket-style SSE push
},
}
}

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 auth
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 auth
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 auth
import (
@ -250,8 +254,8 @@ func HandleGetTenant(tenantStore *TenantStore) http.HandlerFunc {
"plan": plan,
"usage": map[string]interface{}{
"events_this_month": tenant.EventsThisMonth,
"events_limit": plan.MaxEventsMonth,
"usage_percent": usagePercent(tenant.EventsThisMonth, plan.MaxEventsMonth),
"events_limit": plan.MaxEventsMonth,
"usage_percent": usagePercent(tenant.EventsThisMonth, plan.MaxEventsMonth),
},
})
}
@ -339,13 +343,13 @@ func HandleBillingStatus(tenantStore *TenantStore) http.HandlerFunc {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{
"plan": plan,
"plan": plan,
"payment_customer_id": tenant.PaymentCustomerID,
"payment_sub_id": tenant.PaymentSubID,
"events_used": tenant.EventsThisMonth,
"events_limit": plan.MaxEventsMonth,
"usage_percent": usagePercent(tenant.EventsThisMonth, plan.MaxEventsMonth),
"next_reset": tenant.MonthResetAt,
"events_used": tenant.EventsThisMonth,
"events_limit": plan.MaxEventsMonth,
"usage_percent": usagePercent(tenant.EventsThisMonth, plan.MaxEventsMonth),
"next_reset": tenant.MonthResetAt,
})
}
}
@ -419,7 +423,7 @@ func HandleListTenants(tenantStore *TenantStore) http.HandlerFunc {
}
tenants := tenantStore.ListTenants()
type tenantResp struct {
ID string `json:"id"`
Name string `json:"name"`
@ -427,7 +431,7 @@ func HandleListTenants(tenantStore *TenantStore) http.HandlerFunc {
PlanID string `json:"plan_id"`
Active bool `json:"active"`
}
res := make([]tenantResp, len(tenants))
for i, t := range tenants {
res[i] = tenantResp{
@ -471,16 +475,16 @@ func HandleImpersonateTenant(tenantStore *TenantStore, jwtSecret []byte) http.Ha
// Issue new token with updated TenantID
accessClaims := Claims{
Sub: claims.Sub,
Role: claims.Role, // Preserves superadmin explicitly
Role: claims.Role, // Preserves superadmin explicitly
TenantID: req.TenantID, // The impersonated tenant ID
TokenType: "access",
Exp: time.Now().Add(15 * time.Minute).Unix(),
}
refreshClaims := Claims{
Sub: claims.Sub,
Role: claims.Role,
TenantID: req.TenantID,
TenantID: req.TenantID,
TokenType: "refresh",
Exp: time.Now().Add(7 * 24 * time.Hour).Unix(),
}
@ -521,8 +525,8 @@ func HandleImpersonateTenant(tenantStore *TenantStore, jwtSecret []byte) http.Ha
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{
"status": "success",
"tenant_id": req.TenantID,
"status": "success",
"tenant_id": req.TenantID,
"csrf_token": csrfToken,
})
}

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 auth
import (
@ -22,17 +26,17 @@ type Plan struct {
Name string `json:"name"`
Description string `json:"description,omitempty"`
MaxUsers int `json:"max_users"`
MaxEventsMonth int `json:"max_events_month"` // SOC event ingestion quota (-1=unlimited)
MaxEventsMonth int `json:"max_events_month"` // SOC event ingestion quota (-1=unlimited)
MaxIncidents int `json:"max_incidents"`
MaxSensors int `json:"max_sensors"`
MaxScansMonth int `json:"max_scans_month"` // /api/v1/scan quota (-1=unlimited, 0=none)
MaxScansMonth int `json:"max_scans_month"` // /api/v1/scan quota (-1=unlimited, 0=none)
RetentionDays int `json:"retention_days"`
SOCEnabled bool `json:"soc_enabled"` // SOC Dashboard access
SOCEnabled bool `json:"soc_enabled"` // SOC Dashboard access
SLAEnabled bool `json:"sla_enabled"`
SOAREnabled bool `json:"soar_enabled"`
ComplianceEnabled bool `json:"compliance_enabled"`
OnPremise bool `json:"on_premise"` // Enterprise: on-premise deployment
PriceMonthCents int `json:"price_month_cents"` // 0 = free, -1 = custom pricing
OnPremise bool `json:"on_premise"` // Enterprise: on-premise deployment
PriceMonthCents int `json:"price_month_cents"` // 0 = free, -1 = custom pricing
}
// DefaultPlans defines the standard pricing tiers (prices in RUB kopecks).
@ -40,64 +44,64 @@ var DefaultPlans = map[string]Plan{
"free": {
ID: "free", Name: "Free",
Description: "Scanner API — 1 000 сканов/мес, все 66 движков, без SOC Dashboard",
MaxUsers: 1, MaxEventsMonth: 1000, MaxIncidents: 100, MaxSensors: 1,
MaxUsers: 1, MaxEventsMonth: 1000, MaxIncidents: 100, MaxSensors: 1,
MaxScansMonth: 1000,
RetentionDays: 3,
SOCEnabled: false, SLAEnabled: false, SOAREnabled: false, ComplianceEnabled: false,
SOCEnabled: false, SLAEnabled: false, SOAREnabled: false, ComplianceEnabled: false,
PriceMonthCents: 0,
},
"demo": {
ID: "demo", Name: "Demo Sandbox",
Description: "Общая демо-песочница. Жёсткий лимит.",
MaxUsers: 10, MaxEventsMonth: 1000, MaxIncidents: 100, MaxSensors: 5,
MaxUsers: 10, MaxEventsMonth: 1000, MaxIncidents: 100, MaxSensors: 5,
MaxScansMonth: 1000,
RetentionDays: 1,
SOCEnabled: true, SLAEnabled: false, SOAREnabled: false, ComplianceEnabled: false,
SOCEnabled: true, SLAEnabled: false, SOAREnabled: false, ComplianceEnabled: false,
PriceMonthCents: 0,
},
"starter": {
ID: "starter", Name: "Starter",
Description: "AI-мониторинг: до 5 сенсоров, базовая корреляция и алерты",
MaxUsers: 10, MaxEventsMonth: 100000, MaxIncidents: 200, MaxSensors: 5,
MaxUsers: 10, MaxEventsMonth: 100000, MaxIncidents: 200, MaxSensors: 5,
MaxScansMonth: 100000,
RetentionDays: 30,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: false, ComplianceEnabled: false,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: false, ComplianceEnabled: false,
PriceMonthCents: 8990000, // 89 900 ₽/мес
},
"professional": {
ID: "professional", Name: "Professional",
Description: "Полный AI SOC: SOAR, compliance, расширенная аналитика",
MaxUsers: 50, MaxEventsMonth: 500000, MaxIncidents: 1000, MaxSensors: 25,
MaxUsers: 50, MaxEventsMonth: 500000, MaxIncidents: 1000, MaxSensors: 25,
MaxScansMonth: 500000,
RetentionDays: 90,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: true, ComplianceEnabled: true,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: true, ComplianceEnabled: true,
PriceMonthCents: 14990000, // 149 900 ₽/мес
},
"enterprise": {
ID: "enterprise", Name: "Enterprise",
Description: "On-premise / выделенный инстанс. Сертификация — на стороне заказчика",
MaxUsers: -1, MaxEventsMonth: -1, MaxIncidents: -1, MaxSensors: -1,
MaxUsers: -1, MaxEventsMonth: -1, MaxIncidents: -1, MaxSensors: -1,
MaxScansMonth: -1, // unlimited
RetentionDays: 365,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: true, ComplianceEnabled: true,
OnPremise: true,
SOCEnabled: true, SLAEnabled: true, SOAREnabled: true, ComplianceEnabled: true,
OnPremise: true,
PriceMonthCents: -1, // по запросу
},
}
// Tenant represents an isolated organization in the multi-tenant system.
type Tenant struct {
ID string `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
PlanID string `json:"plan_id"`
PaymentCustomerID string `json:"payment_customer_id,omitempty"`
PaymentSubID string `json:"payment_sub_id,omitempty"`
OwnerUserID string `json:"owner_user_id"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
EventsThisMonth int `json:"events_this_month"`
MonthResetAt time.Time `json:"month_reset_at"`
ID string `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
PlanID string `json:"plan_id"`
PaymentCustomerID string `json:"payment_customer_id,omitempty"`
PaymentSubID string `json:"payment_sub_id,omitempty"`
OwnerUserID string `json:"owner_user_id"`
Active bool `json:"active"`
CreatedAt time.Time `json:"created_at"`
EventsThisMonth int `json:"events_this_month"`
MonthResetAt time.Time `json:"month_reset_at"`
}
// GetPlan returns the tenant's plan configuration.

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 auth
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 auth
import (
@ -67,7 +71,7 @@ func NewUserStore(db ...*sql.DB) *UserStore {
// Ensure default admin exists or is updated
adminPass := os.Getenv("SYNTREX_ADMIN_PASSWORD")
if adminPass == "" {
// If no env var, use a secure random password to prevent accidental exposure
// If no env var, use a secure random password to prevent accidental exposure
// if the database is clean, but do not override an existing admin's password.
b := make([]byte, 16)
rand.Read(b)
@ -408,12 +412,12 @@ func (s *UserStore) DeleteUser(id string) error {
// APIKey represents an API key for programmatic access.
type APIKey struct {
ID string `json:"id"`
UserID string `json:"user_id"`
Name string `json:"name"`
Role string `json:"role"`
KeyPrefix string `json:"key_prefix"` // first 8 chars for display
CreatedAt time.Time `json:"created_at"`
ID string `json:"id"`
UserID string `json:"user_id"`
Name string `json:"name"`
Role string `json:"role"`
KeyPrefix string `json:"key_prefix"` // first 8 chars for display
CreatedAt time.Time `json:"created_at"`
LastUsed *time.Time `json:"last_used,omitempty"`
}

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 cache
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 cache
import (
@ -6,9 +10,9 @@ import (
"path/filepath"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
)
func newTestCache(t *testing.T) *BoltCache {

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 cache
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 cache
import (
@ -5,9 +9,9 @@ import (
"os"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/vectorstore"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/vectorstore"
bolt "go.etcd.io/bbolt"
)

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 email provides email notification service for the SYNTREX SOC platform.
// Supports Resend (resend.com) as the primary transactional email provider.
package email

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 formalspec implements SEC-012 TLA+ Formal Verification.
//
// Provides a Go representation of the Event Bus pipeline and
@ -26,22 +30,22 @@ import (
type PipelineState string
const (
StateInit PipelineState = "INIT"
StateScanning PipelineState = "SCANNING" // Secret Scanner (Step 0)
StateDedup PipelineState = "DEDUP" // Deduplication
StateCorrelate PipelineState = "CORRELATE" // Correlation Engine
StatePersist PipelineState = "PERSIST" // SQLite Persist
StateInit PipelineState = "INIT"
StateScanning PipelineState = "SCANNING" // Secret Scanner (Step 0)
StateDedup PipelineState = "DEDUP" // Deduplication
StateCorrelate PipelineState = "CORRELATE" // Correlation Engine
StatePersist PipelineState = "PERSIST" // SQLite Persist
StateDecisionLog PipelineState = "DECISION_LOG" // Audit Decision Logger
StateComplete PipelineState = "COMPLETE"
StateError PipelineState = "ERROR"
StateComplete PipelineState = "COMPLETE"
StateError PipelineState = "ERROR"
)
// Transition represents a state transition in the pipeline.
type Transition struct {
From PipelineState `json:"from"`
To PipelineState `json:"to"`
Guard string `json:"guard"` // Condition for transition
Action string `json:"action"` // Side effect
Guard string `json:"guard"` // Condition for transition
Action string `json:"action"` // Side effect
Timestamp time.Time `json:"timestamp"`
}
@ -223,8 +227,8 @@ func (v *SpecVerifier) VerifyPipeline(state PipelineState, history []Transition)
v.mu.Unlock()
results = append(results, InvariantResult{
Name: inv.Name,
Passed: passed,
Name: inv.Name,
Passed: passed,
Details: fmt.Sprintf("%s: %v", inv.Description, passed),
})
}
@ -246,8 +250,8 @@ func (v *SpecVerifier) VerifyChain(chain []ChainEntry) []InvariantResult {
v.mu.Unlock()
results = append(results, InvariantResult{
Name: inv.Name,
Passed: passed,
Name: inv.Name,
Passed: passed,
Details: fmt.Sprintf("%s: %v", inv.Description, passed),
})
}

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 formalspec
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 guard implements the SEC-002 eBPF Runtime Guard policy engine.
//
// The guard monitors SOC processes at the kernel level using eBPF tracepoints
@ -33,23 +37,23 @@ const (
// Policy is the top-level runtime guard policy.
type Policy struct {
Version string `yaml:"version"`
Mode Mode `yaml:"mode"`
Processes map[string]ProcessPolicy `yaml:"processes"`
Alerts AlertConfig `yaml:"alerts"`
Version string `yaml:"version"`
Mode Mode `yaml:"mode"`
Processes map[string]ProcessPolicy `yaml:"processes"`
Alerts AlertConfig `yaml:"alerts"`
}
// ProcessPolicy defines allowed/blocked behavior for a single process.
type ProcessPolicy struct {
Description string `yaml:"description"`
AllowedExec []string `yaml:"allowed_exec"`
Description string `yaml:"description"`
AllowedExec []string `yaml:"allowed_exec"`
BlockedSyscalls []string `yaml:"blocked_syscalls"`
AllowedFiles []string `yaml:"allowed_files"`
BlockedFiles []string `yaml:"blocked_files"`
AllowedNetwork []string `yaml:"allowed_network"`
BlockedNetwork []string `yaml:"blocked_network"`
MaxMemoryMB int `yaml:"max_memory_mb"`
MaxCPUPercent int `yaml:"max_cpu_percent"`
AllowedFiles []string `yaml:"allowed_files"`
BlockedFiles []string `yaml:"blocked_files"`
AllowedNetwork []string `yaml:"allowed_network"`
BlockedNetwork []string `yaml:"blocked_network"`
MaxMemoryMB int `yaml:"max_memory_mb"`
MaxCPUPercent int `yaml:"max_cpu_percent"`
}
// AlertConfig defines alert routing.
@ -63,10 +67,10 @@ type Violation struct {
Timestamp time.Time `json:"timestamp"`
ProcessName string `json:"process_name"`
PID int `json:"pid"`
Type string `json:"type"` // syscall, file, network, resource
Detail string `json:"detail"` // Specific violation description
Severity string `json:"severity"` // LOW, MEDIUM, HIGH, CRITICAL
Action string `json:"action"` // logged, blocked, alerted
Type string `json:"type"` // syscall, file, network, resource
Detail string `json:"detail"` // Specific violation description
Severity string `json:"severity"` // LOW, MEDIUM, HIGH, CRITICAL
Action string `json:"action"` // logged, blocked, alerted
PolicyMode Mode `json:"policy_mode"`
}
@ -79,19 +83,19 @@ type Guard struct {
policy *Policy
handlers []ViolationHandler
logger *slog.Logger
statsMu sync.Mutex // protects stats
statsMu sync.Mutex // protects stats
stats GuardStats
}
// GuardStats tracks guard operation metrics.
// This is a pure data struct (no mutex) so it can be safely returned by value.
type GuardStats struct {
TotalEvents int64 `json:"total_events"`
Violations int64 `json:"violations"`
Blocked int64 `json:"blocked"`
ByProcess map[string]int64 `json:"by_process"`
ByType map[string]int64 `json:"by_type"`
StartedAt time.Time `json:"started_at"`
TotalEvents int64 `json:"total_events"`
Violations int64 `json:"violations"`
Blocked int64 `json:"blocked"`
ByProcess map[string]int64 `json:"by_process"`
ByType map[string]int64 `json:"by_type"`
StartedAt time.Time `json:"started_at"`
}
// New creates a new runtime guard with the given policy.

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 guard
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 hardware provides infrastructure for physical and logical
// security controls: Soft Leash file-based kill switch (v3.1) and
// Zero-G State Machine (v3.2).

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 hardware
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 ipc provides a cross-platform inter-process communication layer
// for SENTINEL SOC Process Isolation (SEC-001).
//
@ -234,10 +238,10 @@ func DialWithRetry(ctx context.Context, name string, maxRetries int) (net.Conn,
// BufferedSender wraps a Sender with an async buffer for non-blocking sends.
// If the downstream pipe is slow, messages are buffered up to BufferSize.
type BufferedSender struct {
sender *Sender
msgCh chan *SOCMessage
done chan struct{}
logger *slog.Logger
sender *Sender
msgCh chan *SOCMessage
done chan struct{}
logger *slog.Logger
}
// NewBufferedSender creates a buffered async sender.

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 ipc
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.
//go:build !windows
package ipc

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.
//go:build windows
package ipc
@ -38,7 +42,7 @@ func platformDial(name string) (net.Conn, error) {
// In production, these would be actual Windows named pipes.
func pipeTCPPort(name string) int {
ports := map[string]int{
"soc-ingest-to-correlate": 19751,
"soc-ingest-to-correlate": 19751,
"soc-correlate-to-respond": 19752,
}
if p, ok := ports[name]; ok {

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.
//go:build !windows
package ipc

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.
//go:build windows
package ipc

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 ipc provides localhost IPC transport for Virtual Swarm peer
// synchronization using Named Pipes (Windows) or Unix Domain Sockets.
// Zero external dependencies — uses Go standard `net` package.

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 ipc_test
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 logging provides structured logging via Go's log/slog.
// Production: JSON output. Development: text output with colors.
//

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 logging
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.
//go:build onnx
package onnx

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.
//go:build onnx
package onnx

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.
//go:build !onnx
package onnx

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.
//go:build onnx
package onnx

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 onnx provides a native Go ONNX Runtime embedder for the Sentinel Local Oracle.
//
// Replaces the Python bridge (pybridge) with direct ONNX inference.

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 postgres provides PostgreSQL persistence for the SENTINEL SOC.
//
// Uses pgx/v5 driver (pure Go, no CGO) with connection pooling.

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 postgres
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 pqcrypto implements SEC-013 (Homomorphic Encryption research)
// and SEC-014 (Post-Quantum Signatures).
//
@ -43,21 +47,21 @@ type HybridSignature struct {
// HybridSigner provides quantum-resistant signing with classical fallback.
type HybridSigner struct {
mu sync.RWMutex
scheme SignatureScheme
mu sync.RWMutex
scheme SignatureScheme
classicalPub ed25519.PublicKey
classicalPriv ed25519.PrivateKey
logger *slog.Logger
stats SignerStats
logger *slog.Logger
stats SignerStats
}
// SignerStats tracks signing metrics.
type SignerStats struct {
mu sync.Mutex
TotalSigns int64 `json:"total_signs"`
TotalVerifies int64 `json:"total_verifies"`
Scheme SignatureScheme `json:"scheme"`
StartedAt time.Time `json:"started_at"`
mu sync.Mutex
TotalSigns int64 `json:"total_signs"`
TotalVerifies int64 `json:"total_verifies"`
Scheme SignatureScheme `json:"scheme"`
StartedAt time.Time `json:"started_at"`
}
// NewHybridSigner creates a new post-quantum hybrid signer.
@ -164,9 +168,9 @@ const (
// EncryptedEvent represents a homomorphically encrypted SOC event.
type EncryptedEvent struct {
CiphertextID string `json:"ciphertext_id"`
Scheme HEScheme `json:"scheme"`
FieldCount int `json:"field_count"`
CiphertextID string `json:"ciphertext_id"`
Scheme HEScheme `json:"scheme"`
FieldCount int `json:"field_count"`
Created time.Time `json:"created"`
}

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 pqcrypto
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 pybridge provides a bridge to the Python RLM toolkit for NLP operations
// that require embeddings, semantic search, and other ML capabilities.
package pybridge

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 pybridge
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 pybridge
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 sbom implements SEC-010 SBOM + Release Signing.
//
// Generates SPDX Software Bill of Materials and provides
@ -23,14 +27,14 @@ import (
// SPDXDocument is an SPDX 2.3 SBOM document.
type SPDXDocument struct {
SPDXVersion string `json:"spdxVersion"`
DataLicense string `json:"dataLicense"`
SPDXID string `json:"SPDXID"`
DocumentName string `json:"name"`
Namespace string `json:"documentNamespace"`
CreationInfo CreationInfo `json:"creationInfo"`
Packages []Package `json:"packages"`
Relationships []Relationship `json:"relationships,omitempty"`
SPDXVersion string `json:"spdxVersion"`
DataLicense string `json:"dataLicense"`
SPDXID string `json:"SPDXID"`
DocumentName string `json:"name"`
Namespace string `json:"documentNamespace"`
CreationInfo CreationInfo `json:"creationInfo"`
Packages []Package `json:"packages"`
Relationships []Relationship `json:"relationships,omitempty"`
}
// CreationInfo describes when and how the SBOM was created.
@ -42,13 +46,13 @@ type CreationInfo struct {
// Package is an SPDX package entry.
type Package struct {
SPDXID string `json:"SPDXID"`
Name string `json:"name"`
Version string `json:"versionInfo"`
Supplier string `json:"supplier,omitempty"`
License string `json:"licenseConcluded"`
DownloadURL string `json:"downloadLocation"`
Checksum string `json:"checksum,omitempty"` // SHA256:hex
SPDXID string `json:"SPDXID"`
Name string `json:"name"`
Version string `json:"versionInfo"`
Supplier string `json:"supplier,omitempty"`
License string `json:"licenseConcluded"`
DownloadURL string `json:"downloadLocation"`
Checksum string `json:"checksum,omitempty"` // SHA256:hex
}
// Relationship links packages.
@ -62,8 +66,8 @@ type Relationship struct {
type ReleaseSignature struct {
Binary string `json:"binary"`
Version string `json:"version"`
Hash string `json:"hash"` // SHA-256
Signature string `json:"signature"` // Ed25519 hex
Hash string `json:"hash"` // SHA-256
Signature string `json:"signature"` // Ed25519 hex
KeyID string `json:"key_id"`
SignedAt string `json:"signed_at"`
}
@ -97,9 +101,9 @@ func (g *Generator) AddDependency(name, version, license string) {
// GenerateSPDX creates an SPDX 2.3 JSON document.
func (g *Generator) GenerateSPDX() (*SPDXDocument, error) {
doc := &SPDXDocument{
SPDXVersion: "SPDX-2.3",
DataLicense: "CC0-1.0",
SPDXID: "SPDXRef-DOCUMENT",
SPDXVersion: "SPDX-2.3",
DataLicense: "CC0-1.0",
SPDXID: "SPDXRef-DOCUMENT",
DocumentName: fmt.Sprintf("%s-%s", g.productName, g.version),
Namespace: fmt.Sprintf("https://sentinel.syntrex.pro/spdx/%s/%s", g.productName, g.version),
CreationInfo: CreationInfo{

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 sbom
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 secureboot implements SEC-007 Secure Boot Integration.
//
// Provides a verification chain from bootloader to SOC binary:
@ -28,24 +32,24 @@ import (
// VerifyResult holds the outcome of a binary verification.
type VerifyResult struct {
Valid bool `json:"valid"`
BinaryPath string `json:"binary_path"`
BinaryHash string `json:"binary_hash"` // SHA-256
SignatureOK bool `json:"signature_ok"`
ChainValid bool `json:"chain_valid"`
TrustedKey string `json:"trusted_key,omitempty"` // Key ID that signed
Error string `json:"error,omitempty"`
VerifiedAt time.Time `json:"verified_at"`
Valid bool `json:"valid"`
BinaryPath string `json:"binary_path"`
BinaryHash string `json:"binary_hash"` // SHA-256
SignatureOK bool `json:"signature_ok"`
ChainValid bool `json:"chain_valid"`
TrustedKey string `json:"trusted_key,omitempty"` // Key ID that signed
Error string `json:"error,omitempty"`
VerifiedAt time.Time `json:"verified_at"`
}
// BootAttestation is a measured boot report.
type BootAttestation struct {
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
Binaries []BinaryRecord `json:"binaries"`
ChainValid bool `json:"chain_valid"`
AllVerified bool `json:"all_verified"`
PCRValues map[string]string `json:"pcr_values,omitempty"`
NodeID string `json:"node_id"`
Timestamp time.Time `json:"timestamp"`
Binaries []BinaryRecord `json:"binaries"`
ChainValid bool `json:"chain_valid"`
AllVerified bool `json:"all_verified"`
PCRValues map[string]string `json:"pcr_values,omitempty"`
}
// BinaryRecord is a single binary in the boot chain.
@ -62,7 +66,7 @@ type BinaryRecord struct {
type TrustedKey struct {
ID string `json:"id"`
Algorithm string `json:"algorithm"` // ed25519, rsa
PublicKey ed25519.PublicKey `json:"-"`
PublicKey ed25519.PublicKey `json:"-"`
PublicHex string `json:"public_hex"`
Purpose string `json:"purpose"` // binary_signing, config_signing
AddedAt time.Time `json:"added_at"`
@ -83,7 +87,7 @@ type BinarySignature struct {
// Verifier validates the boot chain of SOC binaries.
type Verifier struct {
mu sync.RWMutex
mu sync.RWMutex
trustedKeys map[string]*TrustedKey
signatures *SignatureStore
logger *slog.Logger
@ -92,7 +96,7 @@ type Verifier struct {
// VerifierStats tracks verification metrics.
type VerifierStats struct {
mu sync.Mutex
mu sync.Mutex
TotalVerifications int64 `json:"total_verifications"`
Passed int64 `json:"passed"`
Failed int64 `json:"failed"`

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 secureboot
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 sqlite
import (

View file

@ -1,12 +1,16 @@
// 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 sqlite
import (
"context"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/causal"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/causal"
)
func newTestCausalRepo(t *testing.T) *CausalRepo {

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 sqlite
import (

View file

@ -1,12 +1,16 @@
// 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 sqlite
import (
"context"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/crystal"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/crystal"
)
func newTestCrystalRepo(t *testing.T) *CrystalRepo {

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 sqlite provides SQLite-based persistence using modernc.org/sqlite (pure Go, no CGO).
package sqlite

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 sqlite
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 sqlite
import (
@ -5,9 +9,9 @@ import (
"testing"
"time"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
)
func newTestFactRepo(t *testing.T) *FactRepo {

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 sqlite
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 sqlite
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 sqlite
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 sqlite
import (
@ -570,4 +574,3 @@ func (r *SOCRepo) PurgeExpiredIncidents(retentionDays int) (int64, error) {
}
return result.RowsAffected()
}

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 sqlite
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 sqlite
import (

View file

@ -1,12 +1,16 @@
// 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 sqlite
import (
"context"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/session"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/session"
)
func newTestStateRepo(t *testing.T) *StateRepo {

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 sqlite
import (

View file

@ -1,13 +1,17 @@
// 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 sqlite_test
import (
"context"
"testing"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/syntrex-lab/gomcp/internal/domain/memory"
"github.com/syntrex-lab/gomcp/internal/infrastructure/sqlite"
)
func setupSynapseTest(t *testing.T) (*sqlite.SynapseRepo, *sqlite.FactRepo) {

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 tpmaudit implements SEC-006 TPM-Sealed Decision Logger.
//
// Provides hardware-backed integrity for the audit decision chain:
@ -37,57 +41,57 @@ const (
// DecisionEntry is a single audit decision record.
type DecisionEntry struct {
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
Action string `json:"action"` // ingest, correlate, respond, playbook
Decision string `json:"decision"` // allow, deny, escalate
Reason string `json:"reason"`
EventID string `json:"event_id,omitempty"`
IncidentID string `json:"incident_id,omitempty"`
Operator string `json:"operator,omitempty"`
PreviousHash string `json:"previous_hash"` // Chain link
ID string `json:"id"`
Timestamp time.Time `json:"timestamp"`
Action string `json:"action"` // ingest, correlate, respond, playbook
Decision string `json:"decision"` // allow, deny, escalate
Reason string `json:"reason"`
EventID string `json:"event_id,omitempty"`
IncidentID string `json:"incident_id,omitempty"`
Operator string `json:"operator,omitempty"`
PreviousHash string `json:"previous_hash"` // Chain link
}
// SealedEntry wraps a decision with cryptographic sealing.
type SealedEntry struct {
Entry DecisionEntry `json:"entry"`
Hash string `json:"hash"` // SHA-256 of entry
Signature string `json:"signature"` // TPM or HMAC signature
PCRValue string `json:"pcr_value"` // Extended PCR (or simulated)
Hash string `json:"hash"` // SHA-256 of entry
Signature string `json:"signature"` // TPM or HMAC signature
PCRValue string `json:"pcr_value"` // Extended PCR (or simulated)
SealMode SealMode `json:"seal_mode"`
ChainIdx int64 `json:"chain_idx"`
}
// ChainVerification holds the result of verifying an audit chain.
type ChainVerification struct {
Valid bool `json:"valid"`
TotalEntries int `json:"total_entries"`
VerifiedCount int `json:"verified_count"`
BrokenAtIndex int `json:"broken_at_index,omitempty"`
BrokenReason string `json:"broken_reason,omitempty"`
VerifiedAt time.Time `json:"verified_at"`
Mode SealMode `json:"mode"`
Valid bool `json:"valid"`
TotalEntries int `json:"total_entries"`
VerifiedCount int `json:"verified_count"`
BrokenAtIndex int `json:"broken_at_index,omitempty"`
BrokenReason string `json:"broken_reason,omitempty"`
VerifiedAt time.Time `json:"verified_at"`
Mode SealMode `json:"mode"`
}
// SealedLogger provides TPM-sealed (or HMAC-fallback) audit logging.
type SealedLogger struct {
mu sync.Mutex
mode SealMode
hmacKey []byte // Used in software mode
chain []SealedEntry // In-memory chain (also persisted)
currentPCR string // Simulated PCR value
logFile *os.File
logger *slog.Logger
stats LoggerStats
mu sync.Mutex
mode SealMode
hmacKey []byte // Used in software mode
chain []SealedEntry // In-memory chain (also persisted)
currentPCR string // Simulated PCR value
logFile *os.File
logger *slog.Logger
stats LoggerStats
}
// LoggerStats tracks audit logger metrics.
type LoggerStats struct {
TotalEntries int64 `json:"total_entries"`
LastEntry time.Time `json:"last_entry"`
ChainIntegrity bool `json:"chain_integrity"`
Mode SealMode `json:"mode"`
StartedAt time.Time `json:"started_at"`
TotalEntries int64 `json:"total_entries"`
LastEntry time.Time `json:"last_entry"`
ChainIntegrity bool `json:"chain_integrity"`
Mode SealMode `json:"mode"`
StartedAt time.Time `json:"started_at"`
}
// NewSealedLogger creates a TPM-sealed decision logger.

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 tpmaudit
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 tracing
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 tracing provides OpenTelemetry instrumentation for the SOC platform.
//
// Usage:

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 tracing
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 wasmsandbox implements SEC-009 Wasm Sandbox for Playbooks.
//
// Executes playbook actions in isolated WebAssembly modules:
@ -65,7 +69,7 @@ type ActionHandler func(ctx context.Context, params map[string]string) (string,
// SandboxStats tracks execution metrics.
type SandboxStats struct {
mu sync.Mutex
mu sync.Mutex
TotalExecutions int64 `json:"total_executions"`
Succeeded int64 `json:"succeeded"`
Failed int64 `json:"failed"`

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 wasmsandbox
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 watchdog implements the SEC-004 Watchdog Mesh Framework.
//
// Mutual monitoring between SOC agents (immune, sidecar, shield)
@ -49,7 +53,7 @@ type PeerHealth struct {
MissedCount int `json:"missed_count"`
RestartCount int `json:"restart_count"`
LastRestart time.Time `json:"last_restart,omitempty"`
ResponseTimeMs int64 `json:"response_time_ms"`
ResponseTimeMs int64 `json:"response_time_ms"`
}
// EscalationHandler is called when a peer requires escalation action.
@ -57,11 +61,11 @@ type EscalationHandler func(action EscalationAction)
// EscalationAction describes what the mesh decided to do.
type EscalationAction struct {
Timestamp time.Time `json:"timestamp"`
PeerName string `json:"peer_name"`
Action string `json:"action"` // restart, isolate, alert_architect
Reason string `json:"reason"`
Severity string `json:"severity"`
Timestamp time.Time `json:"timestamp"`
PeerName string `json:"peer_name"`
Action string `json:"action"` // restart, isolate, alert_architect
Reason string `json:"reason"`
Severity string `json:"severity"`
}
// Monitor is the watchdog mesh peer monitor.
@ -78,13 +82,13 @@ type Monitor struct {
// MonitorStats tracks mesh health metrics.
type MonitorStats struct {
mu sync.Mutex
TotalChecks int64 `json:"total_checks"`
TotalMisses int64 `json:"total_misses"`
TotalRestarts int64 `json:"total_restarts"`
TotalIsolations int64 `json:"total_isolations"`
StartedAt time.Time `json:"started_at"`
PeerCount int `json:"peer_count"`
mu sync.Mutex
TotalChecks int64 `json:"total_checks"`
TotalMisses int64 `json:"total_misses"`
TotalRestarts int64 `json:"total_restarts"`
TotalIsolations int64 `json:"total_isolations"`
StartedAt time.Time `json:"started_at"`
PeerCount int `json:"peer_count"`
}
// NewMonitor creates a new watchdog mesh monitor.

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 watchdog
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 zerotrust implements SEC-008 Zero-Trust Internal Networking.
//
// Provides mTLS with SPIFFE identity for all internal SOC communication:
@ -62,27 +66,27 @@ var AuthzPolicy = map[SPIFFEID][]SPIFFEID{
// Identity holds a service's mTLS identity.
type Identity struct {
mu sync.RWMutex
spiffeID SPIFFEID
serviceName string
cert *tls.Certificate
caCert *x509.Certificate
caKey *ecdsa.PrivateKey
caPool *x509.CertPool
mu sync.RWMutex
spiffeID SPIFFEID
serviceName string
cert *tls.Certificate
caCert *x509.Certificate
caKey *ecdsa.PrivateKey
caPool *x509.CertPool
allowedCallers []SPIFFEID
logger *slog.Logger
stats IdentityStats
logger *slog.Logger
stats IdentityStats
}
// IdentityStats tracks mTLS metrics.
type IdentityStats struct {
mu sync.Mutex
CertRotations int64 `json:"cert_rotations"`
ConnectionsAccepted int64 `json:"connections_accepted"`
ConnectionsDenied int64 `json:"connections_denied"`
LastRotation time.Time `json:"last_rotation"`
CertExpiry time.Time `json:"cert_expiry"`
StartedAt time.Time `json:"started_at"`
mu sync.Mutex
CertRotations int64 `json:"cert_rotations"`
ConnectionsAccepted int64 `json:"connections_accepted"`
ConnectionsDenied int64 `json:"connections_denied"`
LastRotation time.Time `json:"last_rotation"`
CertExpiry time.Time `json:"cert_expiry"`
StartedAt time.Time `json:"started_at"`
}
// NewIdentity creates a new zero-trust mTLS identity.
@ -211,7 +215,7 @@ func (id *Identity) Stats() IdentityStats {
id.stats.mu.Lock()
defer id.stats.mu.Unlock()
return IdentityStats{
CertRotations: id.stats.CertRotations,
CertRotations: id.stats.CertRotations,
ConnectionsAccepted: id.stats.ConnectionsAccepted,
ConnectionsDenied: id.stats.ConnectionsDenied,
LastRotation: id.stats.LastRotation,

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 zerotrust
import (