Plugin Installation
The @obsigna/opencode-plugin package (Tier B) emits one daemon-signed receipt per native OpenCode tool call. For the MCP channel (Tier A), see MCP Proxy.
Prerequisites
Section titled “Prerequisites”obsigna-daemoninstalled, initialised, and running — it holds the signing key and writes every receipt- OpenCode installed (
npm install -g opencode-aior see the OpenCode docs)
Start the daemon
Section titled “Start the daemon”The plugin holds no key of its own — obsigna-daemon owns the key and signs every receipt (ADR-0010). Initialise it once and start it before launching OpenCode:
obsigna-daemon --init # one-time: generates the Ed25519 signing key pairobsigna-daemon # start the daemon (listens on a Unix socket)The plugin reaches the daemon over its default platform socket automatically — no extra flag needed.
Install the plugin
Section titled “Install the plugin”Add the package to your project and register it in opencode.json:
npm install @obsigna/opencode-plugin{ "$schema": "https://opencode.ai/config.json", "plugin": ["@obsigna/opencode-plugin"]}OpenCode also loads plugins from .opencode/plugin/. To configure the plugin programmatically, export a configured instance from a file there:
import { createObsignaPlugin } from "@obsigna/opencode-plugin";
export const ObsignaPlugin = createObsignaPlugin({ strict: false, deny: ["read", "glob", "grep", "list"], // skip read-only noise});Configuration
Section titled “Configuration”Configure via environment variables (read when the plugin loads):
| Variable | Default | Meaning |
|---|---|---|
AGENTRECEIPTS_SOCKET | per-OS default | Daemon socket path |
AGENT_RECEIPTS_CHANNEL | opencode | Receipt channel label |
AGENT_RECEIPTS_STRICT | false | Re-throw on emit failure instead of warning |
AGENT_RECEIPTS_ALLOW | — | Comma-separated tool allow-list (only these emit) |
AGENT_RECEIPTS_DENY | — | Comma-separated tool deny-list (these never emit) |
createObsignaPlugin(config) accepts the same options plus actionMap (per-tool action-type overrides) and debugLog (a custom log sink). Explicit config wins over environment variables.
Failure posture
Section titled “Failure posture”Default is catch-and-warn (ADR-0025): a tool call is never aborted because the daemon is unreachable; the drop is logged loudly via the configured logger. Because emission is best-effort, a daemon outage produces a chain gap — obsigna receipt verify will report it — rather than silently passing. This is honest-operator-grade auditing, not a completeness guarantee.
Set AGENT_RECEIPTS_STRICT=1 to re-throw emit failures from the tool.execute.after hook so OpenCode surfaces a broken audit pipeline.
Verify the chain end to end
Section titled “Verify the chain end to end”After running a few OpenCode tool calls (e.g. ask it to run a shell command and edit a file), inspect and verify the receipts:
obsigna receipt list # recent receipts — look for channel: opencodeobsigna receipt show 1 # full fields of receipt #1 by sequenceobsigna receipt verify # walk the hash chain and check every signatureA healthy chain prints an OK summary. If the daemon was down for some calls, verify reports the gap — exactly the honest-operator signal the default posture is designed to surface.
To see both channels together, run an MCP tool too (see MCP Proxy): receipts with channel: opencode (native, from the plugin) appear alongside channel: mcp (from the proxy), all in the same daemon chain.