Phase: 1 - Design Date: 2026-01-31 Status: Complete
βββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β DetectionPattern β β SensitiveDataConfig β
βββββββββββββββββββββββββββββββ€ ββββββββββββββββββββββββββββββββ€
β - Name: string β β - Enabled: bool β
β - Regex: string (optional) β β - ScanRequests: bool β
β - Keywords: []string β β - ScanResponses: bool β
β - Severity: Severity β β - MaxPayloadSizeKB: int β
β - Category: Category β β - EntropyThreshold: float64 β
β - Validate: func (optional) β β - Categories: map[string]boolβ
β - Description: string β β - CustomPatterns: []Pattern β
βββββββββββββββββββββββββββββββ β - SensitiveKeywords: []stringβ
ββββββββββββββββββββββββββββββββ
β
β matches
βΌ
βββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββββ
β Detection βββββββ SensitiveDataResult β
βββββββββββββββββββββββββββββββ€ ββββββββββββββββββββββββββββββββ€
β - Type: string β β - Detected: bool β
β - Category: string β β - Detections: []Detection β
β - Severity: string β β - ScanDurationMs: int64 β
β - Location: string β β - Truncated: bool β
β - IsLikelyExample: bool β ββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββββββββββ
β
β stored in
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ActivityRecord.Metadata["sensitive_data_detection"] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β JSON blob containing SensitiveDataResult β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
type Severity string
const (
SeverityCritical Severity = "critical" // Private keys, cloud credentials
SeverityHigh Severity = "high" // API tokens, database credentials
SeverityMedium Severity = "medium" // Credit cards, high entropy
SeverityLow Severity = "low" // Custom patterns, keywords
)type Category string
const (
CategoryCloudCredentials Category = "cloud_credentials"
CategoryPrivateKey Category = "private_key"
CategoryAPIToken Category = "api_token"
CategoryAuthToken Category = "auth_token"
CategorySensitiveFile Category = "sensitive_file"
CategoryDatabaseCredential Category = "database_credential"
CategoryHighEntropy Category = "high_entropy"
CategoryCreditCard Category = "credit_card"
CategoryCustom Category = "custom"
)// DetectionPattern defines a pattern for detecting sensitive data
type DetectionPattern struct {
// Name is the unique identifier for this pattern (e.g., "aws_access_key")
Name string `json:"name"`
// Description is human-readable explanation
Description string `json:"description,omitempty"`
// Regex is the pattern to match (mutually exclusive with Keywords)
Regex string `json:"regex,omitempty"`
// Keywords are exact strings to match (mutually exclusive with Regex)
Keywords []string `json:"keywords,omitempty"`
// Category groups related patterns
Category Category `json:"category"`
// Severity indicates the risk level
Severity Severity `json:"severity"`
// Validate is an optional function for additional validation (e.g., Luhn)
Validate func(match string) bool `json:"-"`
// KnownExamples are test/example values to flag as is_likely_example
KnownExamples []string `json:"known_examples,omitempty"`
}// Detection represents a single sensitive data finding
type Detection struct {
// Type is the pattern name that matched (e.g., "aws_access_key")
Type string `json:"type"`
// Category is the pattern category (e.g., "cloud_credentials")
Category string `json:"category"`
// Severity is the risk level (critical, high, medium, low)
Severity string `json:"severity"`
// Location is the JSON path where the match was found (e.g., "arguments.api_key")
Location string `json:"location"`
// IsLikelyExample indicates if the match is a known test/example value
IsLikelyExample bool `json:"is_likely_example"`
}// SensitiveDataResult is the complete detection result stored in Activity metadata
type SensitiveDataResult struct {
// Detected is true if any sensitive data was found
Detected bool `json:"detected"`
// Detections is the list of findings
Detections []Detection `json:"detections,omitempty"`
// ScanDurationMs is the time taken to scan
ScanDurationMs int64 `json:"scan_duration_ms"`
// Truncated is true if payload exceeded max size
Truncated bool `json:"truncated,omitempty"`
}// SensitiveDataConfig defines user-configurable detection settings
type SensitiveDataConfig struct {
// Enabled turns detection on/off (default: true)
Enabled bool `json:"enabled"`
// ScanRequests enables scanning tool call arguments (default: true)
ScanRequests bool `json:"scan_requests"`
// ScanResponses enables scanning tool responses (default: true)
ScanResponses bool `json:"scan_responses"`
// MaxPayloadSizeKB is the max size to scan before truncating (default: 1024)
MaxPayloadSizeKB int `json:"max_payload_size_kb"`
// EntropyThreshold for high-entropy string detection (default: 4.5)
EntropyThreshold float64 `json:"entropy_threshold"`
// Categories enables/disables specific detection categories
Categories map[string]bool `json:"categories"`
// CustomPatterns are user-defined patterns
CustomPatterns []CustomPatternConfig `json:"custom_patterns,omitempty"`
// SensitiveKeywords are exact strings to flag
SensitiveKeywords []string `json:"sensitive_keywords,omitempty"`
}
// CustomPatternConfig is a user-defined detection pattern
type CustomPatternConfig struct {
Name string `json:"name"`
Regex string `json:"regex,omitempty"`
Keywords []string `json:"keywords,omitempty"`
Severity string `json:"severity"` // critical, high, medium, low
Category string `json:"category,omitempty"` // defaults to "custom"
}func DefaultSensitiveDataConfig() *SensitiveDataConfig {
return &SensitiveDataConfig{
Enabled: true,
ScanRequests: true,
ScanResponses: true,
MaxPayloadSizeKB: 1024,
EntropyThreshold: 4.5,
Categories: map[string]bool{
"cloud_credentials": true,
"private_key": true,
"api_token": true,
"auth_token": true,
"sensitive_file": true,
"database_credential": true,
"high_entropy": true,
"credit_card": true,
},
CustomPatterns: nil,
SensitiveKeywords: nil,
}
}// FilePathPattern defines a sensitive file path pattern
type FilePathPattern struct {
// Name identifies the pattern
Name string `json:"name"`
// Category for grouping (e.g., "ssh", "cloud", "env")
Category string `json:"category"`
// Severity for this path type
Severity Severity `json:"severity"`
// LinuxPatterns are glob patterns for Linux
LinuxPatterns []string `json:"linux_patterns,omitempty"`
// MacOSPatterns are glob patterns for macOS (if different from Linux)
MacOSPatterns []string `json:"macos_patterns,omitempty"`
// WindowsPatterns are glob patterns for Windows
WindowsPatterns []string `json:"windows_patterns,omitempty"`
// UniversalPatterns apply to all platforms
UniversalPatterns []string `json:"universal_patterns,omitempty"`
}No new buckets required. Detection results stored in existing activities bucket as part of ActivityRecord.Metadata.
activities/
βββ {activity_id} β ActivityRecord JSON
βββ metadata
βββ sensitive_data_detection β SensitiveDataResult JSON
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "tool_call",
"server": "github-server",
"tool": "create_secret",
"status": "success",
"timestamp": "2026-01-31T10:30:00Z",
"duration": 150000000,
"metadata": {
"arguments": "{\"key_name\": \"API_KEY\", \"value\": \"sk_live_xxxx\"}",
"response": "{\"created\": true}",
"sensitive_data_detection": {
"detected": true,
"detections": [
{
"type": "stripe_key",
"category": "api_token",
"severity": "high",
"location": "arguments.value",
"is_likely_example": false
}
],
"scan_duration_ms": 8,
"truncated": false
}
}
}// ActivityQueryParams for REST API and CLI
type ActivityQueryParams struct {
// Existing parameters...
Type string `query:"type"`
Status string `query:"status"`
Server string `query:"server"`
RequestID string `query:"request_id"`
// NEW: Sensitive data filters
SensitiveData *bool `query:"sensitive_data"` // true = only with detections
DetectionType string `query:"detection_type"` // e.g., "aws_access_key"
Severity string `query:"severity"` // critical, high, medium, low
}// ActivityResponse includes detection summary
type ActivityResponse struct {
ID string `json:"id"`
Type string `json:"type"`
Server string `json:"server,omitempty"`
Tool string `json:"tool,omitempty"`
Status string `json:"status"`
Timestamp time.Time `json:"timestamp"`
Duration int64 `json:"duration_ms,omitempty"`
Metadata map[string]interface{} `json:"metadata,omitempty"`
// NEW: Detection summary for list view
HasSensitiveData bool `json:"has_sensitive_data"`
DetectionTypes []string `json:"detection_types,omitempty"`
MaxSeverity string `json:"max_severity,omitempty"`
}// SensitiveDataDetectedEvent emitted to event bus for real-time updates
type SensitiveDataDetectedEvent struct {
ActivityID string `json:"activity_id"`
Server string `json:"server"`
Tool string `json:"tool"`
Detections []Detection `json:"detections"`
Timestamp time.Time `json:"timestamp"`
}- Pattern Name: Must be unique, lowercase with underscores
- Regex: Must compile without error
- Severity: Must be one of: critical, high, medium, low
- Category: Must be one of defined categories or "custom"
- EntropyThreshold: Must be between 0.0 and 8.0
- MaxPayloadSizeKB: Must be between 1 and 10240 (10MB max)
- No database migration required (uses existing Metadata field)
- Configuration migration: add
sensitive_data_detectionsection with defaults - Backward compatible: old records without detection metadata treated as "not scanned"