mirror of
https://github.com/syntrex-lab/gomcp.git
synced 2026-06-20 15:28:05 +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 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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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)),
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
}
|
||||
|
||||
|
|
|
|||
4
internal/infrastructure/cache/bolt_cache.go
vendored
4
internal/infrastructure/cache/bolt_cache.go
vendored
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 (
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue