DeepSeek Harness会话活动通过OCSF 1.9.0记录发送至SIEM
Ships DeepSeek Harness session activity to your SIEM as OCSF 1.9.0 records
安装
dsh plugin --profile web add github:CharlotteN7/dsh-ocsf-forwarderGitHub 源码安装:首次需按提示配置 allowBuilds 构建授权后重试
安装与环境配置指引、插件开发教程见 DSH 中文社区文档 ↗
安装即在你的机器上以你的权限运行第三方代码——它可读写文件、使用凭据、访问网络,DSH 的工具审批不会为插件代码加沙箱。「检测到 manifest」仅代表发现 dsh.bundle / dsh.plugin 清单,不构成兼容性或安全审查;安装前请审阅源码,不熟悉的插件先在不含密钥的环境试用。
README
目录
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/createdandsession/disposed, and sweepsctx.sessions.list()at mount. - Correlates
tool/call↔tool/resultandapproval/asked↔approval/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_integrityprofile, and shipsdsh-ocsf-verifyto 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'signorableflag, so a plugin-owned event type makes the next resume throwSessionFormatUnsupportedErrorand 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
bashcan 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.sequenceholes per session, and a shipper cursor that stopped advancing. - It ships no detection content, no alerting and no secret detectors.
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.
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. Security policy is in SECURITY.md.
License
MIT
原始 README: https://github.com/CharlotteN7/dsh-ocsf-forwarder/blob/main/README.md ↗
同类插件
查看全部 →
archify
Agent 技能:生成美观、可校验的架构图、工作流图、时序图、数据流图与生命周期图——自包含 HTML、带动画与清晰导出

dsh-turn-rewind
对话回退:基于持久 Change Ledger 回滚会话与工作区状态。

dsh-plugin-cc
把 DeepSeek Harness 接入 Claude Code:评审、批评、委派与会话导入

dsh-interconnect
跨实例互联:经 interconnect 服务在多个 DSH 实例间转发消息与事件。

dsh-chat-import
把 13 家 coding agent(Claude Code、Codex、ChatGPT、Cursor、Gemini、opencode 等)的完整对话历史导入为可续聊的 DeepSeek Harness 会话,并支持反向导出回 Claude Code。

dsh-crew
DSH 插件:从 Claude Code / Codex 向 DSH agent 派活——原生 subagent 进度、宿主内 worker 会话(分级预设),以及为纯文本宿主补上视觉与图像生成的多模态桥