Skip to content

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

Open
shannonsands wants to merge 1 commit into
mainfrom
feat/secrets-phase1
Open

feat(secrets): add phase 1 secrets tool and redaction hardening#3651
shannonsands wants to merge 1 commit into
mainfrom
feat/secrets-phase1

Conversation

@shannonsands

Copy link
Copy Markdown
Contributor

What does this PR do?
Implements the scoped Phase 1 slice of secure secrets management from #3627 / #410.

This PR adds a first-class secrets tool for the agent (list, check, request, delete, inject), reuses Hermes’ existing secure CLI secret capture path so secret values never enter model context, adds requires_secrets as an alias for skill frontmatter, and hardens output redaction by covering execute_code and patch results plus additional token formats.

This intentionally does not implement gateway DM+delete secret capture yet. That part was explicitly scoped as follow-up work on #3627 because it needs gateway-level secure prompt plumbing rather than a local tool-only change.

Related Issue
Fixes #3627

Type of Change
[x] ✨ New feature (non-breaking change that adds functionality)
[x] 📝 Documentation update
[x] ✅ Tests (adding or improving test coverage)
Changes Made
Added tools/secrets_tool.py
secrets(action="list")
secrets(action="check")
secrets(action="request")
secrets(action="delete")
secrets(action="inject")
Wired secure CLI secret capture into the new tool via existing callback flow in cli.py
Added requires_secrets alias support in tools/skills_tool.py
Registered the tool in:
model_tools.py
toolsets.py
Hardened redaction:
tools/code_execution_tool.py now redacts stdout/stderr before returning
tools/file_tools.py now redacts serialized patch output
agent/redact.py now covers:
Twilio Account SID
bare Twilio auth token style values
JWTs
Tightened secret-name filtering in tools/secrets_tool.py
only secret-like names are accepted
non-secret env vars like PATH, HOME, SSH_AUTH_SOCK, etc. are rejected
Fixed delete semantics so secrets(delete) removes the key from ~/.hermes/.env instead of leaving KEY=
Added tests:
tests/tools/test_secrets_tool.py
tests/agent/test_skill_commands.py
tests/tools/test_code_execution.py
tests/agent/test_redact.py
tests/test_model_tools.py
How to Test
Run the focused suite:

uv run --extra dev python -m pytest \

tests/tools/test_secrets_tool.py \

tests/tools/test_code_execution.py \

tests/agent/test_skill_commands.py \

tests/agent/test_redact.py \

tests/test_model_tools.py \

-q -o "addopts="

Verify the secrets tool behavior:
list returns secret names only
check reports configured vs missing secret-like vars
request uses secure CLI callback flow
delete removes the key from .env
inject registers env passthrough only for allowed secret-like vars
Verify redaction hardening:
execute_code output is redacted
patch output is redacted
Twilio/JWT cases are covered by tests/agent/test_redact.py
Checklist
Code
[x] I've read the Contributing Guide
[x] My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
[x] I searched for existing PRs to make sure this isn't a duplicate
[x] My PR contains only changes related to this fix/feature (no unrelated commits)
[ ] I've run pytest tests/ -q and all tests pass
[x] I've added tests for my changes (required for bug fixes, strongly encouraged for features)
[x] I've tested on my platform: macOS
Documentation & Housekeeping
[ ] I've updated relevant documentation (README, docs/, docstrings) — or N/A
[x] I've updated cli-config.yaml.example if I added/changed config keys — or N/A
[x] I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
[x] I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A
[x] I've updated tool descriptions/schemas if I changed tool behavior — or N/A
Screenshots / Logs
Focused suite result after rebase on latest main:

71 passed, 62 skipped, 1 warning
Scoped note:

This PR intentionally does not implement gateway DM+delete secret capture.
That follow-up remains tracked in the Phase 1 issue discussion on #3627.

@github-actions

Copy link
Copy Markdown
Contributor

⚠️ Supply Chain Risk Detected

This PR contains patterns commonly associated with supply chain attacks. This does not mean the PR is malicious — but these patterns require careful human review before merging.

⚠️ WARNING: marshal/pickle/compile usage

These can deserialize or construct executable code objects.

Matches:

607:+_ENV_VAR_NAME_RE = __import__("re").compile(r"^[A-Z][A-Z0-9_]*$")

Automated scan triggered by supply-chain-audit. If this is a false positive, a maintainer can approve after manual review.

@vulcan-artivus

Copy link
Copy Markdown

CI note:

The current failing test check on this PR does not appear to be introduced by this branch.

Failing test on this PR

From the failed Actions log for this PR (run 23698468229, job 69038157332):

  • tests/agent/test_skill_commands.py::TestBuildSkillInvocationMessage::test_preserves_remaining_remote_setup_warning

CI summary on this PR run:

  • 1 failed, 6704 passed, 166 skipped

Evidence this is pre-existing / flaky on main

The same exact test is also failing on recent pushes to main:

  1. run 23698498644 (main)

    • failed on tests/agent/test_skill_commands.py::TestBuildSkillInvocationMessage::test_preserves_remaining_remote_setup_warning
  2. run 23698056421 (main)

    • failed on tests/agent/test_skill_commands.py::TestBuildSkillInvocationMessage::test_preserves_remaining_remote_setup_warning

This indicates the current PR is hitting a pre-existing flaky or broken CI test rather than introducing a regression in this branch.

Additional context

Other recent PRs/main runs are also failing on unrelated tests, e.g.:

So the repo’s Tests workflow is currently not reliably green across branches.

What this PR changes

This branch touches:

  • tools/secrets_tool.py
  • tools/skills_tool.py
  • tools/code_execution_tool.py
  • tools/file_tools.py
  • agent/redact.py
  • registration/tests around those changes

The CI failure is in a pre-existing skill_commands remote-environment warning path, and the same failure reproduces independently on recent main CI runs.

I’m doing a broader sample of recent failing PRs/main runs separately to identify which test failures are genuine repo-wide CI issues vs branch-specific regressions.

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.
@jeremyjh

Copy link
Copy Markdown

⚠️ WARNING: marshal/pickle/compile usage
607:+_ENV_VAR_NAME_RE = __import__("re").compile(r"^[A-Z][A-Z0-9_]*$")

This is compilation of a regular expression.

@alt-glitch alt-glitch added type/security Security vulnerability or hardening P2 Medium — degraded but workaround exists comp/tools Tool registry, model_tools, toolsets comp/cli CLI entry point, hermes_cli/, setup wizard tool/code-exec execute_code sandbox tool/file File tools (read, write, patch, search) tool/skills Skills system (list, view, manage) labels May 2, 2026
@avassdal

Copy link
Copy Markdown

Why hasn't this been merged yet?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/tools Tool registry, model_tools, toolsets P2 Medium — degraded but workaround exists tool/code-exec execute_code sandbox tool/file File tools (read, write, patch, search) tool/skills Skills system (list, view, manage) type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(secrets): Phase 1 — Core Secrets Tool + Redaction Hardening

5 participants