Build a Contract-Compliant Hermes Secret-Source Plugin
Bitwarden and 1Password are the bundled secret sources. Other vaults, cloud managers, and OS key stores should integrate as standalone plugins. A plugin fetches candidate values; the Hermes orchestrator retains control of security-sensitive application rules.
Official documentation: https://hermes-agent.nousresearch.com/docs/developer-guide/secret-source-plugin
Respect the division of responsibility
The plugin owns backend communication, reference validation, a human-readable label, and structured fetch errors. The framework owns ordering, mapped-versus-bulk precedence, first-claim conflict warnings, replacement policy, protected bootstrap variables, timeouts, provenance, and the final environment writes. A backend that writes directly to os.environ bypasses the very controls the interface exists to provide.
Choose mapped when users bind explicit variables to references. Choose bulk when the backend returns a project or folder. If a CLI is required, use the shared safe subprocess helper with argv—not a shell—an allowlisted child environment, closed stdin, and bounded execution.
Plugin checklist
- Create a standalone plugin package with metadata and a registration function.
- Implement the current
SecretSourceAPI version. - Return
FetchResult; never raise or prompt fromfetch(). - Declare mapped or bulk shape accurately.
- Protect the backend bootstrap-token variable.
- Validate reference schemes before invoking a CLI.
- Use structured error kinds and safe remediation messages.
- Run the shared secret-source conformance tests.
Common pitfalls
- Adding another vault backend directly to Hermes core.
- Passing the full process environment to a child after all provider keys have loaded.
- Using
shell=Truewith user-controlled references. - Returning empty strings as valid credentials.
- Prompting for unlock or MFA during gateway startup.
- Ignoring API-version mismatch and registration warnings.
- Forgetting that first-process plugin discovery occurs after the earliest dotenv load.
Verification steps
- Test disabled-by-default behavior and malformed configuration.
- Exercise success, missing binary, invalid reference, authentication failure, network error, timeout, and empty-value paths.
- Confirm
fetch()never mutates the environment. - Register the plugin and verify provenance labels in a fresh spawned Hermes process.
- Test conflict behavior against one mapped and one bulk source.
- Confirm the bootstrap variable cannot be overwritten.
- Run the conformance kit and one full
apply_all()round trip before publication.
