
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@sidclaw/openclaw-plugin
Advanced tools
OpenClaw plugin — SidClaw governance (policy, approvals, audit trail, cost attribution) for OpenClaw agents.
Adds SidClaw governance — policy evaluation, approval workflow, tamper-evident audit trail, and token / cost attribution — to OpenClaw agents.
MIT licensed. Version 0.3.0.
npm install @sidclaw/openclaw-plugin @sidclaw/sdk openclaw
openclaw is an optional peer — install it only if you're wiring the plugin
into a real OpenClaw runtime.
Create sidclaw.openclaw-plugin.ts in your OpenClaw project:
import { definePluginEntry } from 'openclaw/plugin-sdk';
import { AgentIdentityClient } from '@sidclaw/sdk';
import { createSidClawOpenClawPluginEntry } from '@sidclaw/openclaw-plugin';
const client = new AgentIdentityClient({
apiKey: process.env.SIDCLAW_API_KEY!,
apiUrl: process.env.SIDCLAW_BASE_URL ?? 'https://api.sidclaw.com',
agentId: process.env.SIDCLAW_AGENT_ID!,
});
export default definePluginEntry(
createSidClawOpenClawPluginEntry({
client,
mode: 'enforce', // or 'observe'
defaultAgentId: process.env.SIDCLAW_AGENT_ID,
}),
);
createSidClawOpenClawPluginEntry returns an object with
{ id, name, description, version, hooks, register } that definePluginEntry
accepts directly.
The plugin calls api.on(name, handler) (OpenClaw's real
OpenClawPluginApi.on<K extends PluginHookName> surface) for:
| OpenClaw hook | Behavior |
|---|---|
before_tool_call | Classify tool call, POST /api/v1/evaluate, return { block, blockReason } on deny, { requireApproval: { title, description, … } } on approval_required, or nothing on allow |
after_tool_call | Record outcome + error classification on the trace |
llm_output | Translate OpenClaw's { input, output, cacheRead } usage into SidClaw telemetry and attribute cost across this session's open traces (runId-deduped) |
agent_end | Drop pending state for the agent's session |
session_end | Flush session state |
Event payloads and context fields are mapped from OpenClaw's typed
PluginHookBeforeToolCallEvent + PluginHookToolContext (etc.) into the
plugin's internal HookContext shape.
If you are embedding SidClaw governance into a runtime that is not OpenClaw (or into unit tests), use the raw factory directly:
import { createSidClawPlugin } from '@sidclaw/openclaw-plugin';
import { AgentIdentityClient } from '@sidclaw/sdk';
const client = new AgentIdentityClient({
apiKey: process.env.SIDCLAW_API_KEY!,
agentId: 'agent-default',
});
const plugin = createSidClawPlugin({ client, mode: 'enforce' });
// Before every tool call:
const gate = await plugin.hooks.before_tool_call({
tool_name: 'send_email',
tool_args: { to: 'customer@acme.com' },
tool_call_id: 'tc-123',
session_id: 'session-abc',
agent_id: 'agent-default',
});
if (gate && 'abort' in gate && gate.abort) throw new Error(gate.reason);
if (gate && 'requireApproval' in gate) {
// Surface gate.requireApproval.url to the human approver and wait.
}
// After the tool call returns (or errors):
await plugin.hooks.after_tool_call({
tool_call_id: 'tc-123',
session_id: 'session-abc',
output: 'queued',
});
// Optional: attribute LLM usage to open traces for this session.
await plugin.hooks.llm_output({
session_id: 'session-abc',
run_id: 'run-1',
usage: { input_tokens: 2000, output_tokens: 400, model: 'claude-sonnet-4-6' },
});
// When the agent session ends:
await plugin.hooks.agent_end({ session_id: 'session-abc' });
Trace state is scoped by session_id (internally:
Map<sessionId, Map<toolCallId, PendingTrace>>). Two sessions can reuse the
same tool_call_id without collision, and llm_output only attributes
tokens to the traces for its own session.
llm_output keeps a Map<runId, Set<traceId>> so streamed or replayed
emissions within the same LLM run never double-charge telemetry. New runs
attribute fresh.
The default classifier:
read, read_file,
grep, search, glob, list, view, ls, cat, get, fetch).rm, delete, drop,
truncate, destroy, wipe, purge, or erase as destructive.
removeFilter, removeChild, list_delete_candidates are not flagged —
only the first token counts, and remove was dropped because of DOM-style
false positives.data_classification: 'internal' by default (sensitivity, not
destructiveness). Destructive signals are expressed via reversible: false
and risk_score: 70.Override with a custom classifier:
createSidClawOpenClawPluginEntry({
client,
toolClassifier: (toolName, args) => {
if (toolName === 'postgres_query') {
const sql = (args as { sql?: string })?.sql ?? '';
const mutating = /\b(DROP|TRUNCATE|DELETE|UPDATE|INSERT|ALTER)\b/i.test(sql);
return {
operation: mutating ? 'sql.write' : 'sql.read',
target_integration: 'postgres',
resource_scope: 'default',
data_classification: mutating ? 'restricted' : 'confidential',
reversible: !mutating,
};
}
return null; // fall back to the built-in classifier
},
});
@sidclaw/sdk is a peer dependency at ^0.1.11. recordTelemetry is
feature-detected at runtime, so the plugin still works against older SDKs —
telemetry calls simply no-op.openclaw is an optional peer dependency at >=2026.4.0. The plugin
runs against any host that implements the OpenClawPluginApi.on(hookName, handler) shape.MIT
FAQs
OpenClaw plugin — SidClaw governance (policy, approvals, audit trail, cost attribution) for OpenClaw agents.
The npm package @sidclaw/openclaw-plugin receives a total of 8 weekly downloads. As such, @sidclaw/openclaw-plugin popularity was classified as not popular.
We found that @sidclaw/openclaw-plugin demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.