hermes-agent-features/tests/tools
Ubuntu a3014a4481 fix(docker): add SETUID/SETGID caps so gosu drop in entrypoint succeeds
The Docker terminal backend runs containers with `--cap-drop ALL`
and re-adds only DAC_OVERRIDE, CHOWN, FOWNER. Since commit fee0e0d3
("run as non-root user, use virtualenv") the image entrypoint drops
from root to the `hermes` user via `gosu`, which requires CAP_SETUID
and CAP_SETGID. Without them every sandbox container exits
immediately with:

    Dropping root privileges
    error: failed switching to 'hermes': operation not permitted

Breaking every terminal/file tool invocation in `terminal.backend: docker`
mode.

Fix: add SETUID and SETGID to the cap-add list. The `no-new-privileges`
security-opt is kept, so gosu still cannot escalate back to root after
the one-way drop — the hardening posture is preserved.

Reproduction
------------
With any image whose ENTRYPOINT calls `gosu <user>`, the container
exits immediately under the pre-fix cap set. Post-fix, the drop
succeeds and the container proceeds normally.

    docker run --rm \
        --cap-drop ALL \
        --cap-add DAC_OVERRIDE --cap-add CHOWN --cap-add FOWNER \
        --security-opt no-new-privileges \
        --entrypoint /usr/local/bin/gosu \
        hermes-claude:latest hermes id
    # -> error: failed switching to 'hermes': operation not permitted

    # Same command with SETUID+SETGID added:
    # -> uid=10000(hermes) gid=10000(hermes) groups=10000(hermes)

Tests
-----
Added `test_security_args_include_setuid_setgid_for_gosu_drop` that
asserts both caps are present and the overall hardening posture
(cap-drop ALL + no-new-privileges) is preserved.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 18:13:14 -07:00
..
__init__.py
test_accretion_caps.py
test_ansi_strip.py
test_approval_heartbeat.py
test_approval.py
test_base_environment.py
test_browser_camofox_persistence.py
test_browser_camofox_state.py
test_browser_camofox.py
test_browser_cdp_override.py
test_browser_cdp_tool.py
test_browser_cleanup.py
test_browser_cloud_fallback.py
test_browser_console.py
test_browser_content_none_guard.py
test_browser_hardening.py
test_browser_homebrew_paths.py
test_browser_orphan_reaper.py
test_browser_secret_exfil.py
test_browser_ssrf_local.py
test_budget_config.py
test_checkpoint_manager.py
test_clarify_tool.py
test_clipboard.py
test_code_execution_modes.py
test_code_execution.py
test_command_guards.py
test_config_null_guard.py
test_credential_files.py
test_cron_approval_mode.py
test_cron_prompt_injection.py
test_cronjob_tools.py
test_daytona_environment.py
test_debug_helpers.py
test_delegate_toolset_scope.py
test_delegate.py
test_discord_tool.py
test_docker_environment.py fix(docker): add SETUID/SETGID caps so gosu drop in entrypoint succeeds 2026-04-22 18:13:14 -07:00
test_docker_find.py
test_env_passthrough.py
test_feishu_tools.py
test_file_operations_edge_cases.py
test_file_operations.py
test_file_ops_cwd_tracking.py
test_file_read_guards.py
test_file_staleness.py
test_file_state_registry.py
test_file_sync_back.py
test_file_sync_perf.py
test_file_sync.py
test_file_tools_container_config.py
test_file_tools_live.py
test_file_tools.py
test_file_write_safety.py
test_force_dangerous_override.py
test_fuzzy_match.py
test_hidden_dir_filter.py
test_homeassistant_tool.py
test_image_generation_env.py
test_image_generation.py
test_interrupt.py
test_llm_content_none_guard.py
test_local_background_child_hang.py
test_local_env_blocklist.py
test_local_interrupt_cleanup.py
test_local_shell_init.py
test_local_tempdir.py
test_managed_browserbase_and_modal.py
test_managed_media_gateways.py
test_managed_modal_environment.py
test_managed_server_tool_support.py
test_managed_tool_gateway.py
test_mcp_circuit_breaker.py
test_mcp_dynamic_discovery.py
test_mcp_oauth_bidirectional.py
test_mcp_oauth_cold_load_expiry.py
test_mcp_oauth_integration.py
test_mcp_oauth_manager.py
test_mcp_oauth.py
test_mcp_probe.py
test_mcp_reconnect_signal.py
test_mcp_stability.py
test_mcp_structured_content.py
test_mcp_tool_401_handling.py
test_mcp_tool_issue_948.py
test_mcp_tool.py
test_memory_tool_import_fallback.py
test_memory_tool.py
test_mixture_of_agents_tool.py
test_modal_bulk_upload.py
test_modal_sandbox_fixes.py
test_modal_snapshot_isolation.py
test_notify_on_complete.py
test_osv_check.py
test_parse_env_var.py
test_patch_parser.py
test_process_registry.py
test_read_loop_detection.py
test_registry.py
test_resolve_path.py
test_rl_training_tool.py
test_search_hidden_dirs.py
test_send_message_missing_platforms.py
test_send_message_tool.py
test_session_search.py
test_signal_media.py
test_singularity_preflight.py
test_skill_env_passthrough.py
test_skill_improvements.py
test_skill_manager_tool.py
test_skill_size_limits.py
test_skill_view_path_check.py
test_skill_view_traversal.py
test_skills_guard.py
test_skills_hub_clawhub.py
test_skills_hub.py
test_skills_sync.py
test_skills_tool.py
test_ssh_bulk_upload.py
test_ssh_environment.py
test_symlink_prefix_confusion.py
test_sync_back_backends.py
test_terminal_compound_background.py
test_terminal_exit_semantics.py
test_terminal_foreground_timeout_cap.py
test_terminal_none_command_guard.py
test_terminal_output_transform_hook.py
test_terminal_requirements.py
test_terminal_timeout_output.py
test_terminal_tool_pty_fallback.py
test_terminal_tool_requirements.py
test_terminal_tool.py
test_threaded_process_handle.py
test_tirith_security.py
test_todo_tool.py
test_tool_backend_helpers.py
test_tool_call_parsers.py
test_tool_result_storage.py
test_transcription_tools.py
test_transcription.py
test_tts_gemini.py
test_tts_kittentts.py
test_tts_max_text_length.py
test_tts_mistral.py
test_tts_speed.py
test_url_safety.py
test_vision_tools.py
test_voice_cli_integration.py
test_voice_mode.py
test_watch_patterns.py
test_web_tools_config.py
test_web_tools_tavily.py
test_website_policy.py
test_windows_compat.py
test_write_deny.py
test_yolo_mode.py
test_zombie_process_cleanup.py