security_test.py
1 """ 2 Security test to verify permission_mode bypass is prevented. 3 """ 4 import pytest 5 from pathlib import Path 6 from src.core.agent_core import ClaudeAgent 7 from src.core.schemas import AgentConfig 8 from src.core.permission_profiles import PermissionManager 9 from src.core.exceptions import AgentError 10 11 12 def test_permission_mode_is_rejected(): 13 """ 14 Test that setting permission_mode raises an AgentError. 15 This prevents the security bypass where permission_mode causes 16 the SDK to use --permission-prompt-tool stdio which bypasses 17 all permission checks. 18 """ 19 # Create config with permission_mode set 20 config = AgentConfig( 21 model="claude-haiku-4-5-20251001", 22 max_turns=10, 23 timeout_seconds=300, 24 enable_skills=False, 25 enable_file_checkpointing=False, 26 role="default", 27 permission_mode="default", # This should be rejected 28 ) 29 30 # Create permission manager 31 permission_manager = PermissionManager( 32 profile_path=Path("config/security/permissions.yaml") 33 ) 34 35 # Attempting to create ClaudeAgent with permission_mode should raise error 36 with pytest.raises(AgentError) as exc_info: 37 ClaudeAgent( 38 config=config, 39 permission_manager=permission_manager, 40 tracer=False, 41 ) 42 43 assert "permission_mode must be null" in str(exc_info.value).lower() 44 45 46 def test_permission_mode_none_is_accepted(): 47 """ 48 Test that NOT setting permission_mode (None) is accepted. 49 This is the correct configuration for security. 50 """ 51 # Create config without permission_mode 52 config = AgentConfig( 53 model="claude-haiku-4-5-20251001", 54 max_turns=10, 55 timeout_seconds=300, 56 enable_skills=False, 57 enable_file_checkpointing=False, 58 role="default", 59 permission_mode=None, # This is correct 60 ) 61 62 # Create permission manager 63 permission_manager = PermissionManager( 64 profile_path=Path("config/security/permissions.yaml") 65 ) 66 67 # This should succeed 68 agent = ClaudeAgent( 69 config=config, 70 permission_manager=permission_manager, 71 tracer=False, 72 ) 73 74 assert agent is not None 75 assert agent._config.permission_mode is None 76 77 78 def test_permission_mode_empty_string_is_accepted(): 79 """ 80 Test that empty string for permission_mode is accepted. 81 """ 82 # Create config with empty permission_mode 83 config = AgentConfig( 84 model="claude-haiku-4-5-20251001", 85 max_turns=10, 86 timeout_seconds=300, 87 enable_skills=False, 88 enable_file_checkpointing=False, 89 role="default", 90 permission_mode="", # Empty string should be treated as None 91 ) 92 93 # Create permission manager 94 permission_manager = PermissionManager( 95 profile_path=Path("config/security/permissions.yaml") 96 ) 97 98 # This should succeed (empty string is acceptable) 99 agent = ClaudeAgent( 100 config=config, 101 permission_manager=permission_manager, 102 tracer=False, 103 ) 104 105 assert agent is not None