Complete BZZZ functionality port to CHORUS

🎭 CHORUS now contains full BZZZ functionality adapted for containers

Core systems ported:
- P2P networking (libp2p with DHT and PubSub)
- Task coordination (COOEE protocol)
- HMMM collaborative reasoning
- SHHH encryption and security
- SLURP admin election system
- UCXL content addressing
- UCXI server integration
- Hypercore logging system
- Health monitoring and graceful shutdown
- License validation with KACHING

Container adaptations:
- Environment variable configuration (no YAML files)
- Container-optimized logging to stdout/stderr
- Auto-generated agent IDs for container deployments
- Docker-first architecture

All proven BZZZ P2P protocols, AI integration, and collaboration
features are now available in containerized form.

Next: Build and test container deployment.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
anthonyrawlins
2025-09-02 20:02:37 +10:00
parent 7c6cbd562a
commit 543ab216f9
224 changed files with 86331 additions and 186 deletions

View File

@@ -0,0 +1,959 @@
// Package crypto_test provides comprehensive tests for role-based encryption.
//
// This test suite validates the enterprise-grade security features including:
// - Multi-layer encryption and decryption operations
// - Role-based access control and permission enforcement
// - Key management and rotation procedures
// - Audit logging and compliance monitoring
// - Performance and security benchmarks
// - Edge cases and error handling
//
// Test Categories:
// - Unit tests for individual components
// - Integration tests for end-to-end workflows
// - Security tests for vulnerability assessment
// - Performance tests for scalability validation
// - Compliance tests for regulatory requirements
package crypto
import (
"context"
"encoding/json"
"fmt"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
"chorus.services/bzzz/pkg/config"
"chorus.services/bzzz/pkg/ucxl"
slurpContext "chorus.services/bzzz/pkg/slurp/context"
)
// RoleCryptoTestSuite provides comprehensive testing for role-based encryption
type RoleCryptoTestSuite struct {
suite.Suite
config *config.Config
ageCrypto *AgeCrypto
auditLogger *MockAuditLogger
roleCrypto *RoleCrypto
keyManager *KeyManager
keyStore *MockKeyStore
accessControl *AccessControlMatrix
}
// MockAuditLogger implements AuditLogger for testing
type MockAuditLogger struct {
accessLogs []*AccessLogEntry
keyRotations []*KeyRotationEvent
securityEvents []*SecurityEvent
}
func (m *MockAuditLogger) LogAccess(entry *AccessLogEntry) error {
m.accessLogs = append(m.accessLogs, entry)
return nil
}
func (m *MockAuditLogger) LogKeyRotation(event *KeyRotationEvent) error {
m.keyRotations = append(m.keyRotations, event)
return nil
}
func (m *MockAuditLogger) LogSecurityEvent(event *SecurityEvent) error {
m.securityEvents = append(m.securityEvents, event)
return nil
}
func (m *MockAuditLogger) GetAuditTrail(criteria *AuditCriteria) ([]*AuditEvent, error) {
events := []*AuditEvent{}
for _, access := range m.accessLogs {
events = append(events, &AuditEvent{
EventID: fmt.Sprintf("access_%s", access.UserID),
EventType: "access",
Timestamp: access.AccessTime,
UserID: access.UserID,
Data: map[string]interface{}{
"access_type": access.AccessType,
"success": access.Success,
},
})
}
return events, nil
}
// MockKeyStore implements KeyStore for testing
type MockKeyStore struct {
keys map[string]*SecureKeyData
}
func NewMockKeyStore() *MockKeyStore {
return &MockKeyStore{
keys: make(map[string]*SecureKeyData),
}
}
func (m *MockKeyStore) StoreKey(keyID string, keyData *SecureKeyData) error {
m.keys[keyID] = keyData
return nil
}
func (m *MockKeyStore) RetrieveKey(keyID string) (*SecureKeyData, error) {
if key, exists := m.keys[keyID]; exists {
return key, nil
}
return nil, fmt.Errorf("key not found: %s", keyID)
}
func (m *MockKeyStore) DeleteKey(keyID string) error {
delete(m.keys, keyID)
return nil
}
func (m *MockKeyStore) ListKeys(filter *KeyFilter) ([]*KeyMetadata, error) {
metadata := []*KeyMetadata{}
for keyID, keyData := range m.keys {
if filter != nil && filter.RoleID != "" {
if roleID, ok := keyData.Metadata["role_id"].(string); !ok || roleID != filter.RoleID {
continue
}
}
meta := &KeyMetadata{
KeyID: keyID,
KeyType: keyData.KeyType,
CreatedAt: keyData.CreatedAt,
Status: keyData.Status,
SecurityLevel: AccessMedium, // Default for tests
}
if roleID, ok := keyData.Metadata["role_id"].(string); ok {
meta.RoleID = roleID
}
metadata = append(metadata, meta)
}
return metadata, nil
}
func (m *MockKeyStore) BackupKeys(criteria *BackupCriteria) (*KeyBackup, error) {
return &KeyBackup{
BackupID: fmt.Sprintf("backup_%d", time.Now().Unix()),
CreatedAt: time.Now(),
KeyCount: len(m.keys),
Checksum: "mock_checksum",
}, nil
}
func (m *MockKeyStore) RestoreKeys(backup *KeyBackup) error {
return nil
}
// MockPolicyEngine implements PolicyEngine for testing
type MockPolicyEngine struct {
policies map[string]*AccessPolicy
}
func NewMockPolicyEngine() *MockPolicyEngine {
return &MockPolicyEngine{
policies: make(map[string]*AccessPolicy),
}
}
func (m *MockPolicyEngine) EvaluatePolicy(ctx context.Context, request *AccessRequest) (*PolicyDecision, error) {
// Simple mock evaluation - permit by default for testing
decision := &PolicyDecision{
RequestID: request.RequestID,
Decision: DecisionPermit,
Reason: "Mock policy evaluation - permit",
MatchedPolicies: []string{"mock_policy"},
AppliedRules: []string{"mock_rule"},
ConfidenceScore: 0.95,
RiskScore: 0.2,
EvaluationTime: 10 * time.Millisecond,
EvaluatedAt: time.Now(),
}
// Deny access for test cases that need denial
if strings.Contains(request.UserID, "unauthorized") {
decision.Decision = DecisionDeny
decision.Reason = "Unauthorized user"
decision.RiskScore = 0.9
}
return decision, nil
}
func (m *MockPolicyEngine) CompilePolicy(policy *AccessPolicy) (*CompiledPolicy, error) {
return &CompiledPolicy{
PolicyID: policy.PolicyID,
CompiledAt: time.Now(),
CompilerVersion: "mock_v1.0",
}, nil
}
func (m *MockPolicyEngine) ValidatePolicy(policy *AccessPolicy) (*PolicyValidationResult, error) {
return &PolicyValidationResult{
Valid: true,
Errors: []string{},
Warnings: []string{},
ValidatedAt: time.Now(),
ValidationTime: 5 * time.Millisecond,
}, nil
}
func (m *MockPolicyEngine) LoadPolicies(policies []*AccessPolicy) error {
for _, policy := range policies {
m.policies[policy.PolicyID] = policy
}
return nil
}
func (m *MockPolicyEngine) ReloadPolicies() error {
return nil
}
// MockAttributeProvider implements AttributeProvider for testing
type MockAttributeProvider struct{}
func (m *MockAttributeProvider) GetUserAttributes(userID string) (*UserAttributes, error) {
return &UserAttributes{
UserID: userID,
Department: "Engineering",
Title: "Software Engineer",
ClearanceLevel: "medium",
EmploymentType: "full_time",
StartDate: time.Now().AddDate(-1, 0, 0),
Location: "headquarters",
}, nil
}
func (m *MockAttributeProvider) GetResourceAttributes(resource string) (*ResourceAttributes, error) {
return &ResourceAttributes{
ResourceID: resource,
Classification: "internal",
Sensitivity: "medium",
DataType: "context",
CreatedAt: time.Now().AddDate(0, -1, 0),
UpdatedAt: time.Now(),
}, nil
}
func (m *MockAttributeProvider) GetEnvironmentAttributes() (*EnvironmentAttributes, error) {
return &EnvironmentAttributes{
CurrentTime: time.Now(),
BusinessHours: true,
NetworkZone: "internal",
DeviceType: "workstation",
DeviceTrust: "trusted",
ConnectionType: "wired",
ThreatLevel: "low",
ComplianceMode: "standard",
MaintenanceMode: false,
}, nil
}
func (m *MockAttributeProvider) GetContextAttributes(ctx context.Context) (*ContextAttributes, error) {
return &ContextAttributes{
RequestType: "api",
ApplicationContext: "slurp_system",
BusinessContext: "development",
TechnicalContext: "microservice",
ComplianceContext: "internal",
RiskContext: "low",
}, nil
}
// SetupSuite initializes the test suite
func (suite *RoleCryptoTestSuite) SetupSuite() {
// Create test configuration
suite.config = &config.Config{
Agent: config.Agent{
ID: "test_agent",
Role: "backend_developer",
},
}
// Initialize components
suite.auditLogger = &MockAuditLogger{
accessLogs: []*AccessLogEntry{},
keyRotations: []*KeyRotationEvent{},
securityEvents: []*SecurityEvent{},
}
suite.ageCrypto = NewAgeCrypto(suite.config)
suite.keyStore = NewMockKeyStore()
var err error
suite.keyManager, err = NewKeyManager(suite.config, suite.keyStore, suite.auditLogger)
suite.Require().NoError(err)
adminKeyManager := NewAdminKeyManager(suite.config, "test_node")
suite.roleCrypto, err = NewRoleCrypto(suite.config, suite.ageCrypto, adminKeyManager, suite.auditLogger)
suite.Require().NoError(err)
// Initialize access control
policyEngine := NewMockPolicyEngine()
attributeProvider := &MockAttributeProvider{}
suite.accessControl, err = NewAccessControlMatrix(suite.config, policyEngine, attributeProvider, suite.auditLogger)
suite.Require().NoError(err)
}
// TestBasicEncryptionDecryption tests basic encryption and decryption functionality
func (suite *RoleCryptoTestSuite) TestBasicEncryptionDecryption() {
// Create test context
address, err := ucxl.Parse("context://test/basic/encryption")
suite.Require().NoError(err)
testContext := &slurpContext.ContextNode{
Path: "/test/basic/encryption",
UCXLAddress: address,
Summary: "Test context for basic encryption",
Purpose: "Testing encryption functionality",
Technologies: []string{"go", "crypto"},
Tags: []string{"test", "encryption"},
Insights: []string{"This is a test insight"},
GeneratedAt: time.Now(),
RAGConfidence: 0.95,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
// Test encryption
targetRoles := []string{"backend_developer", "senior_architect"}
compartmentTags := []string{"development", "testing"}
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(testContext, targetRoles, compartmentTags)
suite.Require().NoError(err)
suite.NotNil(encryptedData)
suite.Equal(address, encryptedData.UCXLAddress)
suite.NotEmpty(encryptedData.EncryptedLayers)
suite.NotNil(encryptedData.AccessControlMeta)
// Test decryption
decryptedContext, err := suite.roleCrypto.DecryptContextForRole(encryptedData, "backend_developer")
suite.Require().NoError(err)
suite.NotNil(decryptedContext)
suite.Equal(testContext.Summary, decryptedContext.Summary)
suite.Equal(testContext.Purpose, decryptedContext.Purpose)
// Verify audit logging
suite.True(len(suite.auditLogger.accessLogs) > 0)
}
// TestRoleBasedAccess tests role-based access control
func (suite *RoleCryptoTestSuite) TestRoleBasedAccess() {
address, err := ucxl.Parse("context://test/rbac/access")
suite.Require().NoError(err)
testContext := &slurpContext.ContextNode{
Path: "/test/rbac/access",
UCXLAddress: address,
Summary: "Test context for RBAC",
Purpose: "Testing role-based access control",
Technologies: []string{"security", "rbac"},
Tags: []string{"test", "security"},
EncryptedFor: []string{"senior_architect"},
AccessLevel: slurpContext.AccessHigh,
GeneratedAt: time.Now(),
RAGConfidence: 0.9,
}
// Encrypt for high-privilege role only
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(testContext, []string{"senior_architect"}, []string{"security"})
suite.Require().NoError(err)
// Test access with authorized role
decryptedContext, err := suite.roleCrypto.DecryptContextForRole(encryptedData, "senior_architect")
suite.Require().NoError(err)
suite.NotNil(decryptedContext)
// Test access with unauthorized role (should fail)
_, err = suite.roleCrypto.DecryptContextForRole(encryptedData, "intern")
suite.Error(err)
suite.Contains(err.Error(), "access denied")
}
// TestMultiLayerEncryption tests multi-layer encryption with different access levels
func (suite *RoleCryptoTestSuite) TestMultiLayerEncryption() {
address, err := ucxl.Parse("context://test/multilayer/encryption")
suite.Require().NoError(err)
testContext := &slurpContext.ContextNode{
Path: "/test/multilayer/encryption",
UCXLAddress: address,
Summary: "Test context for multi-layer encryption",
Purpose: "Testing layered encryption",
Technologies: []string{"encryption", "security"},
Tags: []string{"test", "multilayer"},
Insights: []string{"Multi-layer security insight", "Advanced encryption insight"},
EncryptedFor: []string{"backend_developer", "senior_architect", "devops_engineer"},
AccessLevel: slurpContext.AccessMedium,
GeneratedAt: time.Now(),
RAGConfidence: 0.85,
}
// Encrypt for multiple roles with different access levels
targetRoles := []string{"backend_developer", "senior_architect", "devops_engineer"}
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(testContext, targetRoles, []string{"development"})
suite.Require().NoError(err)
// Verify multiple encryption layers
suite.True(len(encryptedData.EncryptedLayers) > 0)
suite.NotEmpty(encryptedData.KeyFingerprints)
// Test decryption with different roles
for _, role := range targetRoles {
decryptedContext, err := suite.roleCrypto.DecryptContextForRole(encryptedData, role)
suite.Require().NoError(err, "Failed to decrypt for role: %s", role)
suite.NotNil(decryptedContext)
suite.Equal(testContext.Summary, decryptedContext.Summary)
}
}
// TestRoleBasedFiltering tests role-specific context filtering
func (suite *RoleCryptoTestSuite) TestRoleBasedFiltering() {
address, err := ucxl.Parse("context://test/filtering/context")
suite.Require().NoError(err)
testContext := &slurpContext.ContextNode{
Path: "/test/filtering/context",
UCXLAddress: address,
Summary: "Test context for filtering",
Purpose: "Testing role-based filtering",
Technologies: []string{"frontend", "backend", "database"},
Tags: []string{"test", "filtering"},
Insights: []string{"Frontend insight", "Backend insight", "Database insight"},
EncryptedFor: []string{"frontend_developer", "backend_developer"},
AccessLevel: slurpContext.AccessMedium,
GeneratedAt: time.Now(),
RAGConfidence: 0.8,
}
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(testContext, []string{"frontend_developer", "backend_developer"}, []string{"development"})
suite.Require().NoError(err)
// Test frontend developer access (should get frontend-specific insights)
frontendContext, err := suite.roleCrypto.DecryptContextForRole(encryptedData, "frontend_developer")
suite.Require().NoError(err)
suite.Contains(strings.Join(frontendContext.Insights, " "), "Frontend")
// Test backend developer access (should get backend-specific insights)
backendContext, err := suite.roleCrypto.DecryptContextForRole(encryptedData, "backend_developer")
suite.Require().NoError(err)
suite.Contains(strings.Join(backendContext.Insights, " "), "Backend")
}
// TestKeyManagement tests key generation and management
func (suite *RoleCryptoTestSuite) TestKeyManagement() {
// Test key generation
keyPair, err := suite.keyManager.GenerateRoleKey("test_role", "age-x25519")
suite.Require().NoError(err)
suite.NotNil(keyPair)
suite.NotEmpty(keyPair.PublicKey)
suite.NotEmpty(keyPair.PrivateKey)
suite.True(strings.HasPrefix(keyPair.PublicKey, "age1"))
// Test key retrieval
metadata, err := suite.keyManager.GetKeyMetadata(&KeyFilter{RoleID: "test_role"})
suite.Require().NoError(err)
suite.True(len(metadata) > 0)
// Test key integrity verification
keyID := fmt.Sprintf("test_role_age-x25519_v%d", keyPair.Version)
verificationResult, err := suite.keyManager.VerifyKeyIntegrity(keyID)
suite.Require().NoError(err)
suite.NotNil(verificationResult)
suite.True(verificationResult.IntegrityOK)
}
// TestKeyRotation tests automatic key rotation
func (suite *RoleCryptoTestSuite) TestKeyRotation() {
// Create initial key
originalKeyPair, err := suite.keyManager.GenerateRoleKey("rotation_test_role", "age-x25519")
suite.Require().NoError(err)
// Perform key rotation
rotationResult, err := suite.keyManager.RotateKey("rotation_test_role", "test_rotation")
suite.Require().NoError(err)
suite.NotNil(rotationResult)
suite.Contains(rotationResult.RotatedRoles, "rotation_test_role")
suite.NotEmpty(rotationResult.NewKeys)
suite.NotEmpty(rotationResult.RevokedKeys)
// Verify new key is different from original
newKey := rotationResult.NewKeys["rotation_test_role"]
suite.NotEqual(originalKeyPair.PublicKey, string(newKey.KeyData))
// Verify audit logging
suite.True(len(suite.auditLogger.keyRotations) > 0)
rotation := suite.auditLogger.keyRotations[len(suite.auditLogger.keyRotations)-1]
suite.Equal("test_rotation", rotation.Reason)
suite.True(rotation.Success)
}
// TestAccessControlMatrix tests the access control matrix functionality
func (suite *RoleCryptoTestSuite) TestAccessControlMatrix() {
ctx := context.Background()
// Create access request
request := &AccessRequest{
RequestID: "test_request_001",
Timestamp: time.Now(),
UserID: "test_user",
Roles: []string{"backend_developer"},
Resource: "context://test/access/resource",
ResourceType: "context",
Action: "read",
ActionType: "data_access",
SessionID: "test_session_001",
IPAddress: "192.168.1.100",
UserAgent: "TestAgent/1.0",
Priority: 1,
Justification: "Testing access control",
Metadata: make(map[string]interface{}),
}
// Test access evaluation
decision, err := suite.accessControl.CheckAccess(ctx, request)
suite.Require().NoError(err)
suite.NotNil(decision)
suite.Equal(DecisionPermit, decision.Decision)
suite.True(decision.ConfidenceScore > 0)
suite.True(decision.EvaluationTime > 0)
// Test unauthorized access
unauthorizedRequest := &AccessRequest{
RequestID: "test_request_002",
Timestamp: time.Now(),
UserID: "unauthorized_user",
Roles: []string{"intern"},
Resource: "context://test/sensitive/resource",
ResourceType: "context",
Action: "write",
ActionType: "data_modification",
SessionID: "test_session_002",
IPAddress: "192.168.1.200",
UserAgent: "TestAgent/1.0",
Priority: 1,
Justification: "Testing unauthorized access",
Metadata: make(map[string]interface{}),
}
unauthorizedDecision, err := suite.accessControl.CheckAccess(ctx, unauthorizedRequest)
suite.Require().NoError(err)
suite.Equal(DecisionDeny, unauthorizedDecision.Decision)
}
// TestBypassTokens tests bypass token functionality
func (suite *RoleCryptoTestSuite) TestBypassTokens() {
// Create bypass token
token, err := suite.accessControl.CreateBypassToken(
"admin_user",
"Emergency maintenance",
[]string{"context://emergency/*"},
1*time.Hour,
5,
)
suite.Require().NoError(err)
suite.NotNil(token)
suite.Equal(BypassTokenStatusActive, token.Status)
suite.Equal(0, token.UsageCount)
// Test access with bypass token
ctx := context.Background()
request := &AccessRequest{
RequestID: "bypass_test_001",
Timestamp: time.Now(),
UserID: "regular_user",
Roles: []string{"intern"},
Resource: "context://emergency/system",
Action: "read",
Metadata: map[string]interface{}{"bypass_token": token.TokenID},
}
decision, err := suite.accessControl.CheckAccess(ctx, request)
suite.Require().NoError(err)
suite.Equal(DecisionPermit, decision.Decision)
suite.Contains(decision.Reason, "Bypass token")
// Verify token usage was recorded
suite.Equal(1, token.UsageCount)
}
// TestSecurityMetrics tests security metrics collection
func (suite *RoleCryptoTestSuite) TestSecurityMetrics() {
// Get role crypto metrics
metrics := suite.roleCrypto.GetSecurityMetrics()
suite.NotNil(metrics)
suite.Contains(metrics, "total_roles")
suite.Contains(metrics, "security_score")
// Get access control metrics
acMetrics := suite.accessControl.GetAccessControlMetrics()
suite.NotNil(acMetrics)
suite.Contains(acMetrics, "total_evaluations")
suite.Contains(acMetrics, "enforcement_mode")
// Get key management security status
keyStatus := suite.keyManager.GetSecurityStatus()
suite.NotNil(keyStatus)
suite.Contains([]string{"healthy", "warning", "degraded", "critical"}, keyStatus.OverallHealth)
suite.True(keyStatus.SecurityScore >= 0 && keyStatus.SecurityScore <= 1)
}
// TestComplianceFeatures tests compliance and audit features
func (suite *RoleCryptoTestSuite) TestComplianceFeatures() {
// Test audit trail retrieval
criteria := &AuditCriteria{
StartTime: &[]time.Time{time.Now().Add(-1 * time.Hour)}[0],
EndTime: &[]time.Time{time.Now()}[0],
UserID: "test_user",
Limit: 100,
}
auditTrail, err := suite.auditLogger.GetAuditTrail(criteria)
suite.Require().NoError(err)
suite.NotNil(auditTrail)
// Verify audit events have required fields
if len(auditTrail) > 0 {
event := auditTrail[0]
suite.NotEmpty(event.EventID)
suite.NotEmpty(event.EventType)
suite.NotEmpty(event.UserID)
suite.NotZero(event.Timestamp)
}
}
// TestErrorHandling tests error handling and edge cases
func (suite *RoleCryptoTestSuite) TestErrorHandling() {
// Test encryption with invalid context
invalidContext := &slurpContext.ContextNode{
Path: "", // Invalid: empty path
Summary: "", // Invalid: empty summary
GeneratedAt: time.Now(),
}
_, err := suite.roleCrypto.EncryptContextForRoles(invalidContext, []string{"backend_developer"}, []string{})
suite.Error(err)
suite.Contains(err.Error(), "invalid context")
// Test decryption with invalid role
address, _ := ucxl.Parse("context://test/valid/context")
validContext := &slurpContext.ContextNode{
Path: "/test/valid/context",
UCXLAddress: address,
Summary: "Valid test context",
Purpose: "Testing error handling",
GeneratedAt: time.Now(),
RAGConfidence: 0.8,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(validContext, []string{"backend_developer"}, []string{})
suite.Require().NoError(err)
_, err = suite.roleCrypto.DecryptContextForRole(encryptedData, "non_existent_role")
suite.Error(err)
suite.Contains(err.Error(), "access denied")
// Test key generation with invalid parameters
_, err = suite.keyManager.GenerateRoleKey("", "invalid_type")
suite.Error(err)
}
// TestPerformance tests performance characteristics
func (suite *RoleCryptoTestSuite) TestPerformance() {
// Create test context
address, _ := ucxl.Parse("context://test/performance/benchmark")
testContext := &slurpContext.ContextNode{
Path: "/test/performance/benchmark",
UCXLAddress: address,
Summary: "Performance test context",
Purpose: "Testing encryption performance",
Technologies: []string{"performance", "crypto"},
Tags: []string{"test", "benchmark"},
Insights: make([]string, 100), // Large insights array
GeneratedAt: time.Now(),
RAGConfidence: 0.9,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
// Fill insights with test data
for i := 0; i < 100; i++ {
testContext.Insights[i] = fmt.Sprintf("Performance test insight #%d", i+1)
}
// Benchmark encryption
start := time.Now()
encryptedData, err := suite.roleCrypto.EncryptContextForRoles(testContext, []string{"backend_developer"}, []string{"performance"})
encryptionTime := time.Since(start)
suite.Require().NoError(err)
suite.True(encryptionTime < 100*time.Millisecond, "Encryption took too long: %v", encryptionTime)
// Benchmark decryption
start = time.Now()
_, err = suite.roleCrypto.DecryptContextForRole(encryptedData, "backend_developer")
decryptionTime := time.Since(start)
suite.Require().NoError(err)
suite.True(decryptionTime < 50*time.Millisecond, "Decryption took too long: %v", decryptionTime)
// Test concurrent operations
concurrentOps := 10
results := make(chan error, concurrentOps)
for i := 0; i < concurrentOps; i++ {
go func(index int) {
address, _ := ucxl.Parse(fmt.Sprintf("context://test/concurrent/%d", index))
ctx := &slurpContext.ContextNode{
Path: fmt.Sprintf("/test/concurrent/%d", index),
UCXLAddress: address,
Summary: fmt.Sprintf("Concurrent test context %d", index),
Purpose: "Testing concurrent operations",
GeneratedAt: time.Now(),
RAGConfidence: 0.8,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
encrypted, err := suite.roleCrypto.EncryptContextForRoles(ctx, []string{"backend_developer"}, []string{"concurrent"})
if err != nil {
results <- err
return
}
_, err = suite.roleCrypto.DecryptContextForRole(encrypted, "backend_developer")
results <- err
}(i)
}
// Wait for all operations to complete
for i := 0; i < concurrentOps; i++ {
err := <-results
suite.NoError(err, "Concurrent operation %d failed", i)
}
}
// TestSecurityVulnerabilities tests for common security vulnerabilities
func (suite *RoleCryptoTestSuite) TestSecurityVulnerabilities() {
// Test for timing attacks (encryption should take consistent time)
address, _ := ucxl.Parse("context://test/security/timing")
baseContext := &slurpContext.ContextNode{
Path: "/test/security/timing",
UCXLAddress: address,
Summary: "Timing attack test",
Purpose: "Testing for timing vulnerabilities",
GeneratedAt: time.Now(),
RAGConfidence: 0.8,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
// Measure encryption times for different content sizes
var times []time.Duration
for i := 0; i < 10; i++ {
testContext := *baseContext
testContext.Insights = make([]string, i*10) // Varying content size
for j := range testContext.Insights {
testContext.Insights[j] = fmt.Sprintf("Insight %d", j)
}
start := time.Now()
_, err := suite.roleCrypto.EncryptContextForRoles(&testContext, []string{"backend_developer"}, []string{"timing"})
duration := time.Since(start)
suite.Require().NoError(err)
times = append(times, duration)
}
// Check that times don't vary too much (basic timing attack protection)
maxTime := times[0]
minTime := times[0]
for _, t := range times {
if t > maxTime {
maxTime = t
}
if t < minTime {
minTime = t
}
}
// Times should not vary by more than 100% (basic check)
variance := float64(maxTime-minTime) / float64(minTime)
suite.True(variance < 2.0, "Encryption times vary too much: %v", variance)
// Test for privilege escalation (lower privilege role shouldn't access higher privilege content)
highPrivContext := &slurpContext.ContextNode{
Path: "/test/security/privilege",
UCXLAddress: address,
Summary: "High privilege content",
Purpose: "Testing privilege escalation protection",
GeneratedAt: time.Now(),
RAGConfidence: 0.9,
EncryptedFor: []string{"senior_architect"},
AccessLevel: slurpContext.AccessCritical,
}
encryptedHighPriv, err := suite.roleCrypto.EncryptContextForRoles(highPrivContext, []string{"senior_architect"}, []string{"security"})
suite.Require().NoError(err)
// Attempt access with lower privilege role
_, err = suite.roleCrypto.DecryptContextForRole(encryptedHighPriv, "intern")
suite.Error(err, "Lower privilege role should not access higher privilege content")
// Test for information leakage in error messages
suite.NotContains(err.Error(), "senior_architect", "Error message should not leak role information")
suite.NotContains(err.Error(), highPrivContext.Summary, "Error message should not leak content information")
}
// BenchmarkEncryption benchmarks encryption operations
func BenchmarkEncryption(b *testing.B) {
// Setup
config := &config.Config{
Agent: config.Agent{ID: "bench_agent", Role: "backend_developer"},
}
auditLogger := &MockAuditLogger{}
ageCrypto := NewAgeCrypto(config)
adminKeyManager := NewAdminKeyManager(config, "bench_node")
roleCrypto, err := NewRoleCrypto(config, ageCrypto, adminKeyManager, auditLogger)
require.NoError(b, err)
address, _ := ucxl.Parse("context://benchmark/encryption")
testContext := &slurpContext.ContextNode{
Path: "/benchmark/encryption",
UCXLAddress: address,
Summary: "Benchmark context for encryption testing",
Purpose: "Performance testing of encryption operations",
Technologies: []string{"crypto", "benchmark"},
Tags: []string{"benchmark", "performance"},
Insights: []string{"Benchmark insight 1", "Benchmark insight 2"},
GeneratedAt: time.Now(),
RAGConfidence: 0.85,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := roleCrypto.EncryptContextForRoles(testContext, []string{"backend_developer"}, []string{"benchmark"})
if err != nil {
b.Fatalf("Encryption failed: %v", err)
}
}
})
}
// BenchmarkDecryption benchmarks decryption operations
func BenchmarkDecryption(b *testing.B) {
// Setup
config := &config.Config{
Agent: config.Agent{ID: "bench_agent", Role: "backend_developer"},
}
auditLogger := &MockAuditLogger{}
ageCrypto := NewAgeCrypto(config)
adminKeyManager := NewAdminKeyManager(config, "bench_node")
roleCrypto, err := NewRoleCrypto(config, ageCrypto, adminKeyManager, auditLogger)
require.NoError(b, err)
address, _ := ucxl.Parse("context://benchmark/decryption")
testContext := &slurpContext.ContextNode{
Path: "/benchmark/decryption",
UCXLAddress: address,
Summary: "Benchmark context for decryption testing",
Purpose: "Performance testing of decryption operations",
Technologies: []string{"crypto", "benchmark"},
Tags: []string{"benchmark", "performance"},
Insights: []string{"Benchmark insight 1", "Benchmark insight 2"},
GeneratedAt: time.Now(),
RAGConfidence: 0.85,
EncryptedFor: []string{"backend_developer"},
AccessLevel: slurpContext.AccessMedium,
}
// Pre-encrypt context for benchmarking decryption
encryptedData, err := roleCrypto.EncryptContextForRoles(testContext, []string{"backend_developer"}, []string{"benchmark"})
require.NoError(b, err)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := roleCrypto.DecryptContextForRole(encryptedData, "backend_developer")
if err != nil {
b.Fatalf("Decryption failed: %v", err)
}
}
})
}
// BenchmarkAccessControl benchmarks access control evaluation
func BenchmarkAccessControl(b *testing.B) {
// Setup
config := &config.Config{
Agent: config.Agent{ID: "bench_agent", Role: "backend_developer"},
}
auditLogger := &MockAuditLogger{}
policyEngine := NewMockPolicyEngine()
attributeProvider := &MockAttributeProvider{}
accessControl, err := NewAccessControlMatrix(config, policyEngine, attributeProvider, auditLogger)
require.NoError(b, err)
ctx := context.Background()
request := &AccessRequest{
RequestID: "benchmark_request",
Timestamp: time.Now(),
UserID: "bench_user",
Roles: []string{"backend_developer"},
Resource: "context://benchmark/access",
ResourceType: "context",
Action: "read",
ActionType: "data_access",
SessionID: "bench_session",
IPAddress: "192.168.1.100",
UserAgent: "BenchmarkAgent/1.0",
Priority: 1,
Metadata: make(map[string]interface{}),
}
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_, err := accessControl.CheckAccess(ctx, request)
if err != nil {
b.Fatalf("Access control evaluation failed: %v", err)
}
}
})
}
// TestMain sets up and tears down the test suite
func TestMain(m *testing.M) {
// Setup any global test resources here
// Run tests
code := m.Run()
// Cleanup any global test resources here
// Exit with the same code as the test run
fmt.Printf("Test suite completed with exit code: %d\n", code)
}
// Run the test suite
func TestRoleCryptoTestSuite(t *testing.T) {
suite.Run(t, new(RoleCryptoTestSuite))
}