Skip to content

feat(plugins): add signet — cryptographic audit trail plugin (fixes #487)#13082

Open
willamhou wants to merge 1 commit into
NousResearch:mainfrom
willamhou:feat/signet-audit-plugin
Open

feat(plugins): add signet — cryptographic audit trail plugin (fixes #487)#13082
willamhou wants to merge 1 commit into
NousResearch:mainfrom
willamhou:feat/signet-audit-plugin

Conversation

@willamhou

Copy link
Copy Markdown

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 the signet-auth library.

Zero core code is modified. The plugin piggybacks on the existing post_tool_call hook already invoked by model_tools.py:540-551, matching the pattern used by plugins/disk-cleanup/.

Related Issue

Fixes #487

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)

Changes Made

  • plugins/signet/plugin.yaml — manifest (hooks: post_tool_call, on_session_end)
  • plugins/signet/audit_signer.pyAuditEvent dataclass, AuditSigner ABC, HashChainSigner (stdlib-only SHA-256 chain, no deps)
  • plugins/signet/signet_adapter.pySignetSigner (lazy import signet_auth, Ed25519 per entry)
  • plugins/signet/__init__.py — hooks + /signet slash command (status, verify, tail, path)
  • plugins/signet/README.md — usage, configuration, schema, threat model
  • tests/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-trip

Nothing 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 verify walk. This directly implements the "inspired by OpenFang" design from #487. Zero new dependencies.

Optional provider — SignetSigner. When signet-auth is installed and plugins.signet.provider: signet (or HERMES_SIGNET_PROVIDER=signet) is set, each entry is Ed25519-signed via the local-first signet-auth package. This addresses the chain-rewrite gap discussed in #487 — forging entries requires forging signatures under the agent's private key, not just recomputing hashes. If signet-auth is unavailable, the plugin logs a warning and falls back to HashChainSigner so the audit trail is never silently disabled.

Why a plugin, not a core modification. Hermes already ships post_tool_call as a first-class plugin hook (see hermes_cli/plugins.py:61 and the existing plugins/disk-cleanup use). A plugin keeps supply-chain surface flat (no new required deps in pyproject.toml) and lets users opt in via the existing hermes 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

# 1. Tests
pytest tests/plugins/test_signet_plugin.py -q

# 2. Enable plugin and run a session
hermes plugins enable signet
hermes -q "list files in current directory"

# 3. Inspect the audit chain
hermes -q "/signet status"
hermes -q "/signet tail 5"
hermes -q "/signet verify"

# 4. Optional: upgrade to Ed25519
pip install signet-auth
export HERMES_SIGNET_PROVIDER=signet
hermes -q "list files in current directory"
hermes -q "/signet verify"   # verifies via signet-auth's signed chain

Checklist

Code

Documentation & Housekeeping

  • Plugin README included
  • 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)
  • Cross-platform: stdlib-only default; pathlib + json + hashlib are portable
  • Tool descriptions — N/A (no new tools; one slash command)

Screenshots / Logs

$ /signet status
Provider: hashchain
Audit dir: /home/user/.hermes/signet
Events: 17
Chain: OK

$ /signet tail 2
#15 2026-04-20T12:41:03Z tool=terminal args=a1b2c3d4e5f6… result=9f8e7d6c5b4a… hash=4c3b2a1f0e9d…
#16 2026-04-20T12:41:04Z tool=read_file args=f6e5d4c3b2a1… result=0a1b2c3d4e5f… hash=7d6c5b4a3c2b…

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.

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.
@alt-glitch alt-glitch added type/feature New feature or request P3 Low — cosmetic, nice to have comp/plugins Plugin system and bundled plugins labels Apr 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/plugins Plugin system and bundled plugins P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Cryptographic Audit Trail — SHA-256 Hash-Chained Action Log for Tamper-Proof Agent Accountability (inspired by OpenFang)

2 participants