// 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/pkg/config" "chorus/pkg/ucxl" slurpContext "chorus/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)) }