feat(plugins): add signet — cryptographic audit trail plugin (fixes #487)#13082
Open
willamhou wants to merge 1 commit into
Open
feat(plugins): add signet — cryptographic audit trail plugin (fixes #487)#13082willamhou wants to merge 1 commit into
willamhou wants to merge 1 commit into
Conversation
Adds a new bundled plugin at plugins/signet/ that produces a tamper-evident audit log for every tool call, implementing the SHA-256 hash-chained audit design requested in NousResearch#487 (inspired by OpenFang) with optional Ed25519 signatures via the signet-auth library. Zero core code is changed. The plugin piggybacks on the existing post_tool_call hook already invoked by model_tools.py, matching the pattern of plugins/disk-cleanup. Default provider (HashChainSigner) is stdlib-only and writes a hash-chained JSONL under $HERMES_HOME/signet/audit.jsonl. The /signet slash command exposes status / verify / tail / path for operators. Optional provider (SignetSigner) adds Ed25519 per entry via lazy `import signet_auth` — if the package isn't installed the plugin falls back to the default signer and logs a warning. The threat model and its mitigations are documented in the plugin README, following the exchange in NousResearch#487 about chain rewrite resistance vs authorship attestation. Tests: tests/plugins/test_signet_plugin.py — 25 new tests covering append / verify / tamper detection / reopen chain continuation / hook invocation / provider selection / slash command / bundled discovery / (optional) Signet adapter round-trip.
19 tasks
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Adds a new bundled plugin at
plugins/signet/that produces a tamper-evident audit log for every tool call. Directly implements the SHA-256 hash-chained audit design requested in #487 (inspired by OpenFang), with an optional upgrade path to Ed25519-signed receipts via thesignet-authlibrary.Zero core code is modified. The plugin piggybacks on the existing
post_tool_callhook already invoked bymodel_tools.py:540-551, matching the pattern used byplugins/disk-cleanup/.Related Issue
Fixes #487
Type of Change
Changes Made
plugins/signet/plugin.yaml— manifest (hooks: post_tool_call, on_session_end)plugins/signet/audit_signer.py—AuditEventdataclass,AuditSignerABC,HashChainSigner(stdlib-only SHA-256 chain, no deps)plugins/signet/signet_adapter.py—SignetSigner(lazyimport signet_auth, Ed25519 per entry)plugins/signet/__init__.py— hooks +/signetslash command (status,verify,tail,path)plugins/signet/README.md— usage, configuration, schema, threat modeltests/plugins/test_signet_plugin.py— 25 tests: append / verify / tamper detection / reopen chain continuation / hook invocation / provider selection / slash command / bundled discovery / optional Signet adapter round-tripNothing else in the repo is touched.
Design notes
Default provider —
HashChainSigner(stdlib only). Every tool call appends a hash-chained entry to$HERMES_HOME/signet/audit.jsonl. Truncation, reordering, or in-place edit is detected by the/signet verifywalk. This directly implements the "inspired by OpenFang" design from #487. Zero new dependencies.Optional provider —
SignetSigner. Whensignet-authis installed andplugins.signet.provider: signet(orHERMES_SIGNET_PROVIDER=signet) is set, each entry is Ed25519-signed via the local-firstsignet-authpackage. This addresses the chain-rewrite gap discussed in #487 — forging entries requires forging signatures under the agent's private key, not just recomputing hashes. Ifsignet-authis unavailable, the plugin logs a warning and falls back toHashChainSignerso the audit trail is never silently disabled.Why a plugin, not a core modification. Hermes already ships
post_tool_callas a first-class plugin hook (seehermes_cli/plugins.py:61and the existingplugins/disk-cleanupuse). A plugin keeps supply-chain surface flat (no new required deps inpyproject.toml) and lets users opt in via the existinghermes plugins enable signet.Threat model. Documented in the plugin README. Hash chaining alone proves sequence integrity, not authorship; this is the limitation @fernandosmither raised in #487. Ed25519 signatures close the authorship gap; bilateral signing (not in this PR) closes the operator-rewrite gap and is a natural follow-up that does not need new wiring.
How to Test
Checklist
Code
feat(plugins): …)pytest tests/plugins/test_signet_plugin.py tests/plugins/test_disk_cleanup_plugin.py tests/hermes_cli/test_plugins.py— 115 passed, 1 skippedDocumentation & Housekeeping
cli-config.yaml.example— N/A (config key optional, documented in README)CONTRIBUTING.md/AGENTS.md— N/A (no architectural change; plugin mechanics already documented)pathlib+json+hashlibare portableScreenshots / Logs
Happy to iterate on the plugin surface (config keys, slash command semantics, provider naming) — wanted to keep this PR tight and responsive to #487's core ask.