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 SecretSource API version.
  • Return FetchResult; never raise or prompt from fetch().
  • 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=True with 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

  1. Test disabled-by-default behavior and malformed configuration.
  2. Exercise success, missing binary, invalid reference, authentication failure, network error, timeout, and empty-value paths.
  3. Confirm fetch() never mutates the environment.
  4. Register the plugin and verify provenance labels in a fresh spawned Hermes process.
  5. Test conflict behavior against one mapped and one bulk source.
  6. Confirm the bootstrap variable cannot be overwritten.
  7. Run the conformance kit and one full apply_all() round trip before publication.