mcpField
D
dazai — burn-after-reading secret (motokano)

dazai — burn-after-reading secret (motokano)

本地服务
new1direction.github.io安全32 周前更新

关于 dazai — burn-after-reading secret (motokano)

面向需要限制密钥读取次数或绑定 Shell/SSH 会话生命周期的 Agent,提供 Rust 密钥管理工具。其 MCP 服务从锁定内存提供密钥,并可在会话结束时擦除密钥、终止进程。

主要功能

  1. 01通过 MCP 提供密钥
  2. 02达到指定读取次数后擦除密钥
  3. 03通过心跳将守护进程绑定到会话
  4. 04会话中断时终止已注册的 Agent 进程
  5. 05锁定内存及 Linux seccomp 隔离

适用场景

  1. 01向 Agent 提供一次性 API 密钥
  2. 02在 Shell 或 SSH 会话结束时清除密钥
  3. 03会话中断后停止已注册的 Agent

MCP 相关

`motokano` 将已配置工具作为一次性 MCP 服务提供;`dazai mcp` 允许 MCP 客户端注册进程 ID,以提供会话绑定保护。两者均使用 stdio 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

暂未收录安装方式

我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。

代码仓库
安装包
mcpbmotokano-0.1.0.mcpb0.1.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

ningen-shikkaku

CI 文档 许可证:MIT

为 AI Agent 提供阅后即焚的密钥。

ningen-shikkaku 提供两个小型 Rust 二进制程序——dazai(与会话绑定的守护进程)和 motokano(自我销毁的一次性 MCP 服务)。

你的 MCP 配置中到处都是明文 API 密钥,而你运行的每个 Agent 都能读取所有密钥——并且即使 Agent 结束运行,这些密钥仍会继续有效。dazai 颠覆了这种做法:密钥存放在锁定且不可交换的 RAM 中,通过 MCP 提供给 Agent,并且会在读取 N 次后销毁,或者在会话结束的那一刻立即销毁。

阅后即焚演示

motokano --calls 1 --tool 'name=get_key,kind=static,value=s3cr3t' --arm

将任意 MCP 客户端指向它,并调用一次 get_key → 你会收到 s3cr3t → 服务会从锁定内存中擦除该值,并向自身发送 SIGKILL。再次调用 → 进程已不存在。

安装

# prebuilt binaries (macOS arm64/x86_64, Linux x86_64/arm64)
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/New1Direction/ningen-shikkaku/releases/latest/download/dazai-installer.sh | sh

# or homebrew
brew install New1Direction/tap/dazai New1Direction/tap/motokano

# or from source (required for the Linux seccomp build)
git clone https://github.com/New1Direction/ningen-shikkaku
cd ningen-shikkaku/rs
cargo build --release                       # -> target/release/{dazai, motokano}
cargo build --release --features seccomp    # Linux: seccomp syscall allowlist

预构建二进制程序使用默认功能构建;受 seccomp 限制的守护进程需要从源代码构建(它会链接 libseccomp——请先安装 libseccomp-dev + pkg-config)。

与 Claude Code 搭配使用

# a one-shot secret an agent can read exactly once:
claude mcp add burn-once -- motokano --calls 1 --arm \
  --tool 'name=get_key,kind=static,value=YOUR-SECRET'

# or the session-bound daemon: agents register their PID and get SIGKILLed
# the moment your session dies
dazai daemon --arm --grace 5 &
claude mcp add dazai -- dazai mcp

任何 MCP 客户端都能以相同方式工作——传输方式是纯 stdio。

第二幕:为你的 Agent 设置死亡开关

同一个守护进程也是会话终止开关。任何 MCP 客户端都可以注册其 PID; 当你的 shell/SSH 会话结束、心跳停止或收到紧急信号时,dazai 会向所有已注册进程发送 SIGKILL,用编译器无法优化掉的擦除操作覆写密钥,然后退出。转身离开:Agent 消亡,密钥焚毁。

dazai daemon --ping-timeout 15        # terminal A  (dry-run by default; --arm makes it real)
dazai client --interval 5             # terminal B
# close terminal B  ->  the daemon wipes its secrets and exits

它只在你自己的机器上运行,处理你自己的密钥和你自己配置的 工具。它绝不会触碰其他进程、文件或主机。

包含内容

它分为两层:

  • 经过强化的 Rust 守护进程 + 工具——真正的实现:mlock(不使用交换空间)、 madvise(MADV_DONTDUMP) + prctl(PR_SET_DUMPABLE, 0)(不生成核心转储 / 不允许 ptrace)、seccomp 系统调用允许列表(禁止 execve/open/connect/…),以及 不可省略的 explicit_bzero / memset_s 擦除操作;以及
  • Python 参考实现——最初用于验证该机制的概念验证(见 python-reference.md)。
组件功能
dazai daemon看门狗:保存经过 mlock 锁定的密钥 + UNIX 套接字心跳;在会话丢失时擦除密钥并自我销毁。在 Linux 上受 seccomp 限制。
dazai client心跳客户端——将守护进程的生命周期与 shell / SSH 会话绑定。
dazai mcp一个将守护进程作为工具提供的 MCP 服务,任何 Agent 都可以注册自己的 PID,以获得与会话绑定的保护(如果会话结束,该进程会收到 SIGKILL)。
motokano独立的自我销毁型 MCP 服务:处理 N 次工具调用,然后擦除密钥状态并退出。
Python 参考实现secmem.py / deadman.py / heartbeat.py / shellrc.sh——可移植的概念验证。

架构

flowchart LR
    A["MCP client / AI agent<br/>(stdio transport)"]

    subgraph Daemon["dazai daemon (kikka Watchdog)"]
        D["dazai daemon<br/>mlock'd SecretBuffers (goodnight)<br/>seccomp-confined on Linux (kekkai)"]
        SOCK[("UNIX socket 0600<br/>HELLO heartbeat + REGISTER / ARM / STATUS")]
    end

    MCPD["dazai mcp<br/>(rei · rmcp server)"]
    HB["dazai client<br/>(heartbeat: HELLO / PING)"]
    MOTO["motokano<br/>(self-immolating MCP server)<br/>static values in SecretBuffer"]
    KILL{{"wipe (explicit_bzero / memset_s)<br/>+ SIGKILL"}}

    A -->|"register pid / status / panic"| MCPD
    A -->|"get_key (static, N reads)"| MOTO
    MCPD -->|"relay verbs + signals via pidfile"| SOCK
    HB -->|"holds liveness connection"| SOCK
    SOCK --- D
    MOTO -. "optional --dazai-socket: register + monitor" .-> SOCK
    D ==>|"on trigger: SIGKILL registered PIDs, then wipe + self-SIGKILL"| KILL
    MOTO ==>|"after N calls / EOF / daemon death: wipe + exit"| KILL
    HB -. "drop / ping-timeout / panic signal" .-> D

Korg 互操作

dazai daemon 和 motokano 可以将数据写入 Korg 防篡改账本:--korg-sink PATH(对于预先打开的描述符,也可使用 /dev/fd/N)会在每个启用、会话、读取、擦除 和终止步骤中追加一条符合 Korg 追加格式的记录。记录仅包含固定词汇表字段和计数器。绝不会记录密钥 值、长度、摘要、工具名称、参数、路径或环境信息。Korg 会通过其 ningen-shikkaku.lifecycle@v2 封装配置文件导入该文件,并分配序列号、哈希和签名。请参阅 Korg 生命周期记录。

威胁模型

daZai 缩小了明文密钥可被访问的时间窗口和攻击面,并确保会话结束时将其确定性地销毁。

它可以防护以下风险:

风险方式
密钥被换出到 swapmlock 将缓冲区锁定在 RAM 中
密钥被捕获在核心转储中madvise(MADV_DONTDUMP) + prctl(PR_SET_DUMPABLE, 0)(Linux)
会话丢失导致密钥仍留在内存中心跳中断/登出 → 擦除 + SIGKILL
密钥使用后残留在进程内存中explicit_bzero / memset_s — 编译器可能不会省略的擦除操作
受限进程逃逸seccomp 允许列表拒绝 execve / open / connect / ptrace / …(Linux)
通过 ptrace 窥探守护进程prctl(PR_SET_DUMPABLE, 0)(Linux)

它不能防护以下情况(项目对此刻意保持坦诚):

  • GPU VRAM。 如果接入的 LLM/Agent 将密钥复制到 GPU 内存,终止主机进程也不会擦除 VRAM。daZai 控制主机 RAM 及其监管的进程,而不控制加速器的内存。
  • exec 工具的标准输出。 motokano 的 kind=exec 工具会返回命令的标准输出,该输出由操作系统缓冲,且不会保存在锁定缓冲区中。需要擦除保障时,请使用 kind=static(预加载、已锁定且可擦除的值)。
  • 托管运行时残留(Python 参考实现)。 CPython 会随意复制 bytes,因此密钥在锁定缓冲区之前/之后可能会暂时存在于未锁定的堆中。Rust 实现消除了自身缓冲区中的这一问题(数据写入锁定映射,绝不会复制到 GC 堆);Python 层是参考实现,不提供硬性保证。
  • 在运行中的机器上拥有特权或相同 UID 的攻击者(root、/proc/<pid>/mem、调试器)在擦除之前读取内存。mlock 可阻止换出,但不能阻止读取内存;seccomp + PR_SET_DUMPABLE 会提高 Linux 上的攻击门槛,但已拥有运行中机器特权访问权限的攻击者不在防护范围内。
  • 对 RAM 的冷启动/DMA/物理攻击。
  • 严重崩溃(内核 OOM、外部 kill -9、断电):擦除路径无法执行,因此不会将任何内容清零。此类情况下该机制只能尽力而为,绝不声称能做到更多。

简而言之:daZai 并非、也不可能保证防范已经控制你运行中机器的攻击者。它是一种强力工具,可让密钥短暂存在并绑定到会话,同时明确说明所有限制。

验证

  • Rust 工作区中有 81 项测试(安全内存、panic 策略、线协议、MCP 层、一次性生命周期、Korg 生命周期契约),另有 Python 参考实现的 29 项测试。
  • Linux seccomp 在真实的 KillProcess 过滤器下通过了两种架构的验证 — aarch64(本地)和 x86_64(CI)— 守护进程会安装正在生效的过滤器,完整集成测试套件也会在该过滤器下运行,且没有出现 SIGSYS。
  • 每次推送都会运行完整测试套件(默认配置和 --features seccomp)、clippy -D warnings,并在 x86_64 Linux 上运行 rustfmt --check,作为长期回归检查门禁。

深入的技术文档(各 crate 的设计、seccomp 允许列表、对抗性审查历史)位于 rs/README.md;Python 概念验证位于 python-reference.md。

名称由来

名称取自小说家 太宰治。他的作品反复探讨消失与自我抹除的主题,这很适合这样一种软件:一旦不再有人看护,就会立刻将自身抹除。仓库以他的小说《人间失格》(人間失格,Ningen Shikkaku)命名。这只是风格上的呼应,并非宣言;软件只会按指令自毁。

许可证

MIT © 2026 New1Direction。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。