hermes-agent/tests/agent
kshitijk4poor a658f3b28b fix(security): strip dynamic Hermes secrets from all subprocess spawn env
Subprocesses spawned by the terminal tool, execute_code, Docker backend, and
the codex app-server could inherit Hermes-internal secrets that the name-based
`_HERMES_PROVIDER_ENV_BLOCKLIST` can't enumerate, because they're injected into
`os.environ` at runtime under dynamic names:

- `AUXILIARY_<TASK>_API_KEY` / `AUXILIARY_<TASK>_BASE_URL` — per-task side-LLM
  credentials bridged from `config.yaml[auxiliary]` by gateway/run.py and cli.py
  (vision, web_extract, approval, compression, plugin-registered tasks). Often
  separate, higher-spend keys plus base URLs pointing at private endpoints.
- `GATEWAY_RELAY_*_SECRET` / `_KEY` / `_TOKEN` — relay-auth material provisioned
  by gateway/relay.

Additionally, agent/transports/codex_app_server.py built its spawn env from a
raw `os.environ.copy()`, bypassing the centralized `hermes_subprocess_env()`
helper entirely — handing every codex subprocess the full Tier-1 secret set
(GH_TOKEN, gateway bot tokens, Modal/Daytona infra tokens, dashboard session
token) unfiltered. This is the #29157 sibling spawn-site gap; copilot_acp_client
already routes through the helper.

Fix — single chokepoint:
- Add `_is_hermes_internal_secret(key)` in tools/environments/local.py as the
  single source of truth for the dynamic secret patterns. Matches
  AUXILIARY_*_API_KEY / _BASE_URL and GATEWAY_RELAY_*_SECRET/_KEY/_TOKEN; leaves
  non-secret AUXILIARY_*_PROVIDER/_MODEL and GATEWAY_RELAY routing hints visible.
- Wire the predicate into every spawn path unconditionally (ignores skill
  env_passthrough opt-in AND inherit_credentials — a model-driving CLI never
  needs these): `_sanitize_subprocess_env` (both loops), `_make_run_env`
  (foreground), `hermes_subprocess_env` (Tier-1), and the Docker forward filter.
- Add the static GATEWAY_RELAY_* names to `_HERMES_PROVIDER_ENV_BLOCKLIST` so the
  exact-match path catches them independently of the predicate.
- Add the GATEWAY_RELAY_ID/_SECRET/_DELIVERY_KEY triplet to `_ALWAYS_STRIP_KEYS`
  (Tier-1) so it is stripped unconditionally on EVERY spawn surface — including
  the codex/copilot `inherit_credentials=True` path that skips the Tier-2
  blocklist. `_SECRET`/`_DELIVERY_KEY` are already predicate-matched; `_ID` has
  no secret suffix, so enumerating it here is what closes its leak on the
  inherit path (self-review W1).
- Defense in depth: env_passthrough.py `_is_hermes_provider_credential()` now
  consults the same predicate, so a skill can't register these names as
  passthrough and tunnel them into an execute_code / terminal child.
- Route codex_app_server through `hermes_subprocess_env(inherit_credentials=True)`
  — strips Tier-1 + dynamic-internal secrets while provider creds (which codex
  needs to authenticate) still flow.

Consolidates PRs #53715 (necoweb3 — the _is_hermes_internal_secret backbone +
Docker filter), #53503 (srojk34 — env_passthrough guard), and #55709 (srojk34 —
codex routing). Retires #52348 (claudlos): its copilot half is already on main,
and its codex half used the full-strip `_sanitize_subprocess_env` which would
break codex provider auth — the correct tier is `inherit_credentials=True`.

Tests: TestHermesInternalDynamicSecrets (terminal + predicate + passthrough
override), TestInternalDynamicSecrets (hermes_subprocess_env both tiers),
TestSpawnEnvSecretStripping (codex spawn env), plus env_passthrough
defense-in-depth cases.

Co-authored-by: necoweb3 <sswdarius@gmail.com>
Co-authored-by: srojk34 <286497132+srojk34@users.noreply.github.com>
Co-authored-by: claudlos <claudlos@agentmail.to>
2026-07-01 14:37:22 +05:30
..
lsp feat(lsp): add PowerShellEditorServices language server (#55930) 2026-06-30 16:22:18 -07:00
transports fix(security): strip dynamic Hermes secrets from all subprocess spawn env 2026-07-01 14:37:22 +05:30
__init__.py
test_anthropic_adapter.py fix(anthropic): preserve ordered replay cache markers 2026-07-01 02:03:40 -07:00
test_anthropic_billing_guidance.py feat(classifier): Anthropic-specific guidance for subscription exhaustion 2026-07-01 01:36:34 -07:00
test_anthropic_keychain.py fix(anthropic): adopt Claude Code's already-refreshed token before racing refresh 2026-06-27 19:14:43 -07:00
test_anthropic_kwargs_sanitize.py
test_anthropic_mcp_prefix_strip.py
test_anthropic_oauth_pkce.py
test_anthropic_output_field_leak.py
test_anthropic_thinking_block_order.py
test_arcee_trinity_overrides.py
test_async_utils.py fix(ci): rip out some xdist legacy stuff... how did these ever work?? 2026-06-26 19:15:18 -07:00
test_auxiliary_client.py fix(runtime): honor NOUS_INFERENCE_BASE_URL across pool/explicit/aux paths 2026-07-01 01:52:06 -07:00
test_auxiliary_client_anthropic_custom.py
test_auxiliary_client_azure_foundry.py
test_auxiliary_client_base_url_host_validation_52608.py fix(auxiliary): gate Anthropic base_url override on Anthropic-compatible host (#52608) 2026-06-26 11:21:05 +05:30
test_auxiliary_client_proxy_env.py test(auxiliary): cover env-only proxy policy for auxiliary clients (#53702) 2026-06-27 21:22:49 -07:00
test_auxiliary_client_xai_oauth_recovery.py
test_auxiliary_config_bridge.py fix(vision): cap vision_analyze fan-out concurrency process-wide 2026-06-29 01:27:10 -07:00
test_auxiliary_main_first.py fix(moa): resolve auxiliary tasks to the aggregator, not the preset name (#53827) 2026-06-27 14:21:26 -07:00
test_auxiliary_named_custom_providers.py
test_auxiliary_transport_autodetect.py
test_auxiliary_user_default_headers.py
test_azure_identity_adapter.py
test_bedrock_1m_context.py
test_bedrock_adapter.py
test_bedrock_integration.py
test_billing_view.py
test_cascading_interrupt_6600.py
test_chat_completion_helpers_provider_sort.py fix(agent): validate OpenRouter provider sort before request dispatch 2026-06-27 11:43:08 -07:00
test_close_interrupted_tool_sequence.py
test_codex_cloudflare_headers.py
test_codex_responses_adapter.py
test_codex_ttfb_watchdog.py
test_coding_context.py feat(agent): add configurable coding_instructions 2026-06-30 00:59:59 -05:00
test_compress_focus.py
test_compressed_summary_metadata.py
test_compression_concurrent_fork.py test(compression): tolerate safe contention rollback in concurrent-fork test (#55597) 2026-06-30 04:22:47 -07:00
test_compression_count_warning_36908.py
test_compression_interrupt_protection.py
test_compression_logging_session_context.py
test_compression_progress.py
test_compression_rotation_state.py
test_compressor_assistant_tail_anchor.py fix(compressor): skip context-summary markers as last-user tail anchor 2026-07-01 01:20:02 -07:00
test_compressor_historical_media.py
test_compressor_image_tokens.py
test_compressor_media_stripping.py
test_compressor_tool_call_budget.py
test_context_breakdown.py feat(desktop): add context usage breakdown popover 2026-06-29 09:18:10 -04:00
test_context_compressor.py test(compressor): tidy blank-line spacing + assert placeholder never overwrites text 2026-07-01 14:24:41 +05:30
test_context_compressor_cross_session_guard.py
test_context_compressor_summary_continuity.py
test_context_compressor_temporal_anchoring.py
test_context_engine.py fix(context): clamp -1 post-compression sentinel in sibling status paths 2026-07-01 13:36:50 +05:30
test_context_engine_host_contract.py fix(agent): keep cooldown state on the active session (#54465) 2026-06-30 13:36:29 +05:30
test_context_references.py
test_context_refs_concurrent.py perf(context-refs): expand @-references concurrently 2026-06-30 00:19:49 -07:00
test_copilot_acp_client.py fix(agent): stream copilot ACP chat completions 2026-06-28 22:52:51 -07:00
test_copilot_acp_deprecation.py
test_credential_pool.py fix(pool): sync anthropic entry on access_token change, not just refresh_token 2026-06-30 03:45:12 -07:00
test_credential_pool_oauth_writethrough.py
test_credential_pool_routing.py
test_credits_cold_start.py
test_credits_fixture_snapshot.py
test_credits_policy.py
test_credits_tracker.py
test_credits_view.py
test_crossloop_client_cache.py
test_curator.py fix(curator): never archive cron-referenced skills + floor use=0 pruning (#54443) 2026-06-28 15:10:21 -07:00
test_curator_activity.py
test_curator_backup.py
test_curator_classification.py
test_curator_reports.py
test_custom_pool_mismatch_guard.py
test_custom_provider_extra_body.py
test_custom_providers_vision.py
test_deepseek_anthropic_thinking.py
test_direct_provider_url_detection.py
test_display.py feat(display): friendly human-phrased tool labels for built-in tools (#55166) 2026-06-29 20:31:17 -07:00
test_display_emoji.py
test_display_todo_progress.py
test_display_tool_failure.py
test_empty_tool_name_loop_dampening.py
test_error_classifier.py fix(classifier): treat Anthropic "out of extra usage" 400 as billing 2026-07-01 01:36:34 -07:00
test_external_skills.py
test_external_skills_dirs_cache.py
test_failover_identity.py
test_file_safety.py fix(file): block credential paths from search results 2026-07-01 01:02:35 -07:00
test_file_safety_container_mirror.py
test_file_safety_credentials.py fix(file): block credential paths from search results 2026-07-01 01:02:35 -07:00
test_file_safety_cross_profile.py
test_file_safety_sandbox_mirror.py
test_gemini_fast_fallback.py
test_gemini_free_tier_gate.py
test_gemini_native_adapter.py Merge consecutive same-role contents for native Gemini 2026-06-30 11:51:22 -07:00
test_gemini_schema.py
test_i18n.py
test_image_gen_registry.py
test_image_routing.py test(vision): cover Ollama /api/show vision capability routing (#54511) 2026-06-28 22:52:59 -07:00
test_insights.py
test_intent_ack_continuation.py fix(agent): flatten multi-part user_message in codex intermediate-ack detector 2026-06-30 03:20:11 -07:00
test_jiter_preload.py
test_kimi_coding_anthropic_thinking.py
test_last_total_tokens.py
test_learn_prompt.py fix(learn): honor requirements mixed with sources in /learn requests (#55956) 2026-06-30 16:56:01 -07:00
test_learning_graph.py fix(desktop): scope memory graph cache by profile 2026-06-30 03:44:41 -05:00
test_learning_graph_render.py fix(journey): swap skill/memory inks so drillable rows read as clickable 2026-06-30 11:54:16 -05:00
test_learning_mutations.py test(journey): lock memory write format-parity with the memory tool 2026-06-30 15:16:25 -05:00
test_local_stream_timeout.py
test_markdown_tables.py
test_memory_async_sync.py
test_memory_provider.py
test_memory_session_switch.py
test_memory_skill_scaffolding.py
test_memory_user_id.py
test_memory_write_bridge.py
test_message_content.py
test_minimax_auxiliary_url.py
test_minimax_provider.py
test_moa_slot_api_mode.py fix(moa): propagate api_mode from slot runtime to call_llm 2026-06-30 03:39:50 -07:00
test_moa_switch_api_mode.py fix(moa): pin chat_completions on live switch to a MoA preset 2026-06-30 03:39:50 -07:00
test_model_extra_type_guard.py test+chore: real-path regression test for #15157 model_extra guard + AUTHOR_MAP 2026-06-30 03:27:12 -07:00
test_model_metadata.py fix(moa): resolve context window from the aggregator, not the 256K default (#53780) 2026-06-27 12:08:09 -07:00
test_model_metadata_local_ctx.py fix: normalize lmstudio base urls 2026-06-28 20:46:44 -07:00
test_model_metadata_ssl.py
test_models_dev.py
test_moonshot_schema.py
test_non_stream_stale_timeout.py
test_nous_credits_gauge.py
test_nous_credits_snapshot.py
test_nous_oauth_401_guidance.py
test_nous_rate_guard.py
test_onboarding.py
test_oneshot.py
test_openrouter_response_cache.py
test_pet_engine.py fix(pet): snap kitty frames to whole cells 2026-06-30 15:41:44 -05:00
test_pet_generate.py
test_platform_hint_overrides.py
test_plugin_llm.py
test_portal_tags.py
test_preflight_compression_gate.py
test_prompt_builder.py test(agent): cover .hermes.md no-git-root cwd-only behavior 2026-06-28 20:46:32 -07:00
test_prompt_caching.py
test_proxy_and_url_validation.py
test_rate_limit_tracker.py
test_reasoning_stale_timeout_floor.py test(reasoning-floor): isolate stale-timeout floor tests from config-module reload races (#54775) 2026-06-29 02:42:54 -07:00
test_redact.py refactor(redact): consolidate CDP-URL log redaction into one chokepoint 2026-07-01 13:43:58 +05:30
test_replay_cleanup.py fix(tui): sanitize replay history on WebUI/TUI session resume (#29086) (#53939) 2026-06-27 20:56:49 -07:00
test_restore_primary_pool_reselect.py fix(pool): re-select from credential pool on primary runtime restore 2026-06-27 20:04:45 -07:00
test_resume_stale_active_task.py
test_runtime_cwd.py
test_save_url_image.py
test_secret_scope.py
test_set_runtime_main_custom_provider.py
test_shell_hooks.py feat(agent): add pre_verify hook and verify-on-stop coding guidance 2026-06-30 00:59:29 -05:00
test_shell_hooks_consent.py
test_skill_bundles.py
test_skill_commands.py
test_skill_commands_reload.py fix(ci): rip out some xdist legacy stuff... how did these ever work?? 2026-06-26 19:15:18 -07:00
test_skill_utils.py
test_ssl_ca_guard.py
test_stream_read_timeout_floor.py
test_streaming_context_scrubber.py
test_subagent_progress.py
test_subagent_stop_hook.py
test_subdirectory_hints.py
test_summary_prefix_semantics.py
test_system_prompt.py
test_system_prompt_restore.py
test_think_scrubber.py
test_thinking_timeout_guidance.py
test_thread_scoped_output.py fix(bg-review): scope stdout/stderr silencing to the worker thread (#55966) 2026-06-30 17:28:33 -07:00
test_title_generator.py
test_tool_call_arg_no_redaction.py fix(agent): stop redacting tool-call args in history; fix auth-header quote-eating 2026-06-28 02:44:06 -07:00
test_tool_dispatch_helpers.py fix(agent): defang untrusted-tool-result delimiter against tag injection 2026-07-01 01:54:45 -07:00
test_tool_guardrails.py
test_tool_result_classification.py
test_transcription_registry.py
test_tts_registry.py
test_turn_context.py fix(agent): persist compression backoff across resume (#54465) 2026-06-30 13:36:29 +05:30
test_turn_finalizer_cleanup_guard.py
test_turn_finalizer_interrupt_alternation.py
test_turn_retry_state.py fix(agent): route content-filter stream stalls to fallback chain (#32421) 2026-06-28 01:15:21 -07:00
test_unsupported_parameter_retry.py
test_unsupported_temperature_retry.py
test_usage_pricing.py
test_verification_evidence.py
test_verification_stop.py feat(agent): restore surface-aware "auto" default for verify_on_stop 2026-06-30 01:43:08 -05:00
test_verify_hooks.py feat(agent): add pre_verify hook and verify-on-stop coding guidance 2026-06-30 00:59:29 -05:00
test_video_gen_registry.py
test_vision_resolved_args.py
test_vision_routing_31179.py