DeepSeek Harness 插件

dsh-ocsf-forwarder

Read-side SIEM forwarder for DeepSeek Harness: normalises session activity to OCSF and ships it(英文原文)

跳到安装方式

来源信息

GitHub 仓库
CharlotteN7/dsh-ocsf-forwarder
最近更新
2026年8月18日
分类
记忆
GitHub stars
0
载体类型
plugin
目录证据
上游声明已找到 dsh.bundle
证据路径
package.json#dsh.bundle
核对版本
0.1.0-rc.8
上游核对日期
2026-08-20

该证据由上游目录提供。本站没有安装、运行或安全审核这个插件。

安装

默认先复制一段 Prompt,让 Agent 读 GitHub 仓库和源码;需要自己装时再切到命令。

复制这段 Prompt,发给 DSH、Codex 或其他 Agent,让它先读 GitHub 仓库和源码。

请先不要安装或执行任何命令。阅读这个插件的 GitHub 仓库、README 和关键源码,然后用清楚、直接的方式回答以下问题,帮助我判断它是否适合我的需求:

1. 这个插件是什么,解决什么问题;
2. 适合哪些用户和典型使用场景;
3. 安装后如何使用,并给出一个最小使用示例;
4. 有哪些已知限制,以及隐私、安全、兼容性或维护风险;
5. 给出“推荐 / 有条件推荐 / 不推荐”的明确建议和理由。

请区分仓库明确说明、根据源码推断和未知信息。证据不足时请明确说明,不要猜测或照抄 README。

GitHub:https://github.com/CharlotteN7/dsh-ocsf-forwarder
插件名:dsh-ocsf-forwarder
作者:CharlotteN7

检查来源文件

安装前先看这个插件目录里的 README 和其他文件。

文件资源管理器3 个文件
README.md来源说明 · 只读预览

dsh-ocsf-forwarder

A read-side SIEM forwarder for DeepSeek Harness. It observes the session event firehose, normalises every event to OCSF 1.9.0 with the native ai_operation profile, and writes newline-delimited OCSF JSON to a local append-only spool — optionally shipping it to Splunk HTTP Event Collector or an OTLP/HTTP collector.

📖 Full documentation — including the complete event → OCSF mapping table for all 44 session event types.

What it does

  • Subscribes to session/event, session/created and session/disposed, and sweeps

ctx.sessions.list() at mount.

  • Correlates tool/calltool/result and approval/askedapproval/decided, emitting

approval decision latency — the approval-fatigue signal.

  • Classifies tool calls by what they do: shell and code execution → Process Activity (1007),

file tools → File System Activity (1001), web tools → HTTP Activity (4002), approvals and sandbox changes → Authorize Session (3003), everything else → API Activity (6003).

  • Names the MCP server behind every mcp__<server>__<tool> call.
  • Emits a high-severity record when a tool hands the task to an external harness, stating in

the record that telemetry coverage ends at that boundary.

  • Emits a periodic heartbeat carrying counters, live session count and delivery cursor, so a

host that goes quiet is distinguishable from one that is idle. A spool that has stopped writing reports itself there at severity_id: 5, with the count of what it dropped.

  • Chains every spooled record with the OCSF record_integrity profile, and ships

dsh-ocsf-verify to check the chain.

  • Replays a resumed or forked session's constructor seed, which never reaches the live firehose.
  • Keeps raw values out of the SOC lane: keyed digests, value classifications and lengths instead.

What it does not do

  • It never writes to the session log. Session.append() cannot set the envelope's ignorable

flag, so a plugin-owned event type makes the next resume throw SessionFormatUnsupportedError and refuse the entire session. All durable output goes to our own sink, and the plugin registers no waterfall listener, so it cannot change a tool call, an approval decision or a model request.

  • It is not a containment boundary. It runs in the agent's process at the agent's uid; an agent

that can run bash can delete or rewrite the spool — and can recompute the hash chain over what it wrote, because the algorithm is published. What it buys you is that records leave the host promptly and that a gap is visible — the chain's entry numbering, metadata.sequence holes per session, and a shipper cursor that stopped advancing.

  • It ships no detection content, no alerting and no secret detectors.

The full scope statement →

Install

The profile must already compose a runnable agent — a profile carrying only @deepseek-ai/dsh-base has no agent loop and this plugin would observe nothing:

dsh plugin --profile <name> add @deepseek-ai/dsh-headless@0.1.0-rc.6
dsh plugin --profile <name> add dsh-ocsf-forwarder
dsh --profile <name> --dump-config      # verify the row is mounted

Pin @deepseek-ai/dsh-headless explicitly — its npm latest tag still points at 0.0.1-rc.1. Install from the registry or a packed tarball, not from a git spec: lib/ is a build output git does not carry.

Install in full →

Configure

- id: dsh-ocsf-forwarder
  config:
    spoolPath: /var/log/dsh/ocsf.jsonl      # absolute; created 0640
    splunk:
      endpoint: https://splunk.example:8088
      token: { source: env, variable: SPLUNK_HEC_TOKEN }
    privacy:
      hmacKey: { source: env, variable: DSH_OCSF_KEY }

Every numeric key that is resolved must be a positive finite number, and those counting records or files must be whole numbers — statsIntervalMs is the one exception, where 0 means "only at unload". A value outside those ranges fails at load, because the alternative is worse than a refused mount: batchSize: 0 makes the shipper loop without ever advancing its cursor. A shipper block with no endpoint configures no shipper and is not resolved, so nothing in it is checked.

The default privacy posture keeps raw values out of the SOC lane — argument values and command lines are digested, URLs reduced to their host. A second restricted lane carries verbatim payloads and must be explicitly acknowledged before it will open.

Every configuration key → · Record format and the mapping table →

Shipping to a SIEM

Splunk HEC and OTLP/HTTP are both supported; configure exactly one per spool. Delivery is cursor-based off the spool, so a collector outage costs nothing but disk, and the spool refuses to delete an un-drained generation rather than silently discarding unacknowledged evidence.

Splunk and OTLP setup → · Delivery and failure modes →

Tamper-evidence

Every record carries an OCSF 1.9.0 record_integrity attestation: the SHA-256 fingerprint of the record, plus the uid and fingerprint of the record before it. Editing, deleting, or reordering a spooled record breaks the chain at that record and at the one after it.

dsh-ocsf-verify /var/log/dsh/ocsf.jsonl   # exits 0 intact, 1 broken, 2 unreadable

The fingerprints are unkeyed, so anyone can recompute them — which is the point, and which also means the chain does not resist the agent it observes. What it detects is a later edit by anything that does not recompute the chain, and it makes every record already shipped to a SIEM an anchor the spool can be checked against.

The canonicalisation, the threat model, and the cost →

Running it with dsh-netguard

Both packages emit OCSF into one index and share the correlation_uid scheme <session>:<callId>, so a Network Activity record from netguard joins to this package's Process Activity record for the same tool call — answering which tool call opened this connection.

metadata.uid is deliberately not shared: this package's key is <session>:<seq> over the session log's event sequence, and netguard namespaces its own as <session>:netguard:<seq> so a SIEM deduplicating on that field cannot mistake one package's records for the other's.

Development

nvm use 22           # Node ^22.19.0 || >=24, and pnpm 11
pnpm install
pnpm run typecheck
pnpm run test:coverage
pnpm run test:e2e    # boots a real dsh against a mock model; no API key

Design decisions and their rationale live in [ADR.md](ADR.md). Security policy is in [SECURITY.md](SECURITY.md).

License

MIT