Parent Issue
Sub-issue of #410 (Secure Secrets Management Tool). This is Phase 1 of the phased rollout.
Scope
A new agent-facing secrets tool that provides secure secret lifecycle management, plus hardening of existing redaction coverage.
1. New secrets tool (tools/secrets_tool.py)
| Action |
Description |
list |
Show configured secret names (never values) + cross-reference skills with requires_secrets frontmatter |
check |
Verify which specific keys are configured vs missing |
request |
Secure input via getpass() (CLI) or gateway DM+delete flow. Value never enters agent context. |
delete |
Remove a secret from storage |
inject |
Register keys for env_passthrough so the terminal tool includes them in the next subprocess call |
Key security property: secret values never enter LLM context. The request action handles the entire input flow internally and only returns {"stored": true} to the agent.
2. Platform-specific secure ingestion
- CLI:
getpass.getpass() — input not echoed, not in readline history
- Telegram: DM the user, accept reply, immediately delete the message containing the key
- Discord: Same DM+delete pattern
- Other platforms: Best-effort (WhatsApp has limited deletion support)
3. Skill requires_secrets frontmatter
Skills can declare required secrets in SKILL.md:
---
name: twilio
requires_secrets:
- key: TWILIO_ACCOUNT_SID
description: "Twilio Account SID"
instructions: "Find at https://console.twilio.com/"
- key: TWILIO_AUTH_TOKEN
description: "Twilio Auth Token"
---
When loading a skill, the agent checks for missing secrets and prompts via secrets(action="request").
4. Redaction hardening (relates to #363)
- Apply
redact_sensitive_text() to read_file, search_files, patch, and execute_code tool outputs
- Expand
agent/redact.py patterns: add Twilio SIDs/tokens, AWS AKIA*, Stripe keys, JWTs, PEM private key blocks
- File permissions:
chmod 600 on ~/.hermes/.env
5. Storage
Phase 1 continues using ~/.hermes/.env for storage. Encrypted storage comes in Phase 3.
Files to Create/Modify
- New:
tools/secrets_tool.py (~400 lines)
- New:
tests/tools/test_secrets_tool.py
- Modify:
agent/redact.py — expanded patterns
- Modify:
tools/file_tools.py — apply redaction to read/search output
- Modify:
tools/code_execution_tool.py — apply redaction to script output
- Modify:
model_tools.py — add to discovery
- Modify:
toolsets.py — add to _HERMES_CORE_TOOLS
- Modify:
agent/skill_commands.py — parse requires_secrets frontmatter
Acceptance Criteria
References
Parent Issue
Sub-issue of #410 (Secure Secrets Management Tool). This is Phase 1 of the phased rollout.
Scope
A new agent-facing
secretstool that provides secure secret lifecycle management, plus hardening of existing redaction coverage.1. New
secretstool (tools/secrets_tool.py)listrequires_secretsfrontmattercheckrequestgetpass()(CLI) or gateway DM+delete flow. Value never enters agent context.deleteinjectenv_passthroughso the terminal tool includes them in the next subprocess callKey security property: secret values never enter LLM context. The
requestaction handles the entire input flow internally and only returns{"stored": true}to the agent.2. Platform-specific secure ingestion
getpass.getpass()— input not echoed, not in readline history3. Skill
requires_secretsfrontmatterSkills can declare required secrets in SKILL.md:
When loading a skill, the agent checks for missing secrets and prompts via
secrets(action="request").4. Redaction hardening (relates to #363)
redact_sensitive_text()toread_file,search_files,patch, andexecute_codetool outputsagent/redact.pypatterns: add Twilio SIDs/tokens, AWSAKIA*, Stripe keys, JWTs, PEM private key blockschmod 600on~/.hermes/.env5. Storage
Phase 1 continues using
~/.hermes/.envfor storage. Encrypted storage comes in Phase 3.Files to Create/Modify
tools/secrets_tool.py(~400 lines)tests/tools/test_secrets_tool.pyagent/redact.py— expanded patternstools/file_tools.py— apply redaction to read/search outputtools/code_execution_tool.py— apply redaction to script outputmodel_tools.py— add to discoverytoolsets.py— add to_HERMES_CORE_TOOLSagent/skill_commands.py— parserequires_secretsfrontmatterAcceptance Criteria
secrets(action="list")returns secret names, never valuessecrets(action="request")usesgetpass()in CLI, DM+delete in gatewayrequires_secretsparsed from skill frontmatterread_file/search_files/execute_codeoutput is redactedReferences