feat(secrets): add phase 1 secrets tool and redaction hardening

Implements the first pragmatic slice of issue #3627 / #410:
- add agent-facing  tool with list/check/request/delete/inject
  actions
- reuse existing secure CLI secret capture path via getpass-backed callback
  so secret values never enter model context
- support  as an alias for the existing
   skill frontmatter
- redact execute_code stdout/stderr before returning tool output
- expand redaction patterns for Twilio SIDs and JWTs
- register the new tool in discovery/core toolsets and add regression tests

Gateway DM+delete secret capture remains scoped as follow-up work per the
Phase 1 issue discussion.
This commit is contained in:
Shannon Sands
2026-03-29 09:44:17 +10:00
parent f007284d05
commit c1ef64a0ac
13 changed files with 544 additions and 2 deletions

4
cli.py
View File

@@ -492,6 +492,7 @@ from cron import get_job
from tools.terminal_tool import cleanup_all_environments as _cleanup_all_terminals
from tools.terminal_tool import set_sudo_password_callback, set_approval_callback
from tools.skills_tool import set_secret_capture_callback
from tools.secrets_tool import set_secrets_request_callback
from hermes_cli.callbacks import prompt_for_secret
from tools.browser_tool import _emergency_cleanup_all_sessions as _cleanup_all_browsers
@@ -5587,6 +5588,7 @@ class HermesCLI:
# Single-query and direct chat callers do not go through run(), so
# register secure secret capture here as well.
set_secret_capture_callback(self._secret_capture_callback)
set_secrets_request_callback(self._secret_capture_callback)
# Refresh provider credentials if needed (handles key rotation transparently)
if not self._ensure_runtime_credentials():
@@ -6292,6 +6294,7 @@ class HermesCLI:
set_sudo_password_callback(self._sudo_password_callback)
set_approval_callback(self._approval_callback)
set_secret_capture_callback(self._secret_capture_callback)
set_secrets_request_callback(self._secret_capture_callback)
# Ensure tirith security scanner is available (downloads if needed).
# Warn the user if tirith is enabled in config but not available,
@@ -7495,6 +7498,7 @@ class HermesCLI:
set_sudo_password_callback(None)
set_approval_callback(None)
set_secret_capture_callback(None)
set_secrets_request_callback(None)
# Flush + shut down Honcho async writer (drains queue before exit)
if self.agent and getattr(self.agent, '_honcho', None):
try: