关于 haltproof
haltproof 面向集群运维人员,统一编排 Slurm、Kubernetes 和 IPMI 环境的紧急停机。它默认先运行演练,并为计划或执行的操作生成签名、哈希链式记录。
主要功能
- 01默认以演练模式停机
- 02支持 Slurm、Kubernetes 和 IPMI 后端
- 03Ed25519 签名及哈希链证明
- 04提供结构化 JSON 输出
- 05验证证明签名与哈希链
适用场景
- 01在事故期间预览集群停机计划
- 02记录目标节点与执行命令
- 03检查证明日志是否遭到篡改
MCP 相关
stdio MCP 服务提供 halt、verify、verify_chain、status 和 keygen 工具。它调用与 CLI 相同的核心函数,并保留默认演练行为。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
5收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| nodes | any | 否 | |
| reason | string | 否 | |
| backend | any | 否 | |
| confirm | boolean | 否 | |
| operator_id | any | 否 | |
| target_group | string | 是 |
详细介绍
HaltProof
面向 Slurm、Kubernetes 和 IPMI 集群的紧急关机编排,并生成 Ed25519 签名、哈希链式证明记录,精确记录实际执行的内容。
面向 Slurm、Kubernetes 和 IPMI 集群的签名式关机编排,默认以演练模式运行,并提供防篡改审计跟踪。

HaltProof 是面向计算集群的紧急关机编排和加密审计证明层。它不实现新的底层关机机制,而是协调你已经信任的集群原语(Slurm、Kubernetes、IPMI/BMC),并生成签名、防篡改的记录,精确说明目标对象、执行内容以及授权者。
pip install haltproof-cli
(包括 npm 封装程序在内的完整安装选项见下文的安装。)
为什么
运维人员已经拥有用于排空 Slurm 分区、隔离 Kubernetes 节点池,或通过 IPMI 对物理主机实施断电隔离的工具。通常缺少的是:
- 跨工具统一的接口,以便在事故期间使用,而不是在压力下应付三套不同的命令集。
- 默认以演练模式运行的安全防护,避免因输错目标组而关闭错误的节点。
- 签名、防篡改的事件记录:记录执行者、发出的命令、涉及的节点、每个步骤是否成功,以及记录本身是否被篡改或有所缺失。
HaltProof 就是这一层。它调用 scontrol、kubectl 和 ipmitool(或可通过 mcp 调用的等效工具),并使用 Ed25519 签名和哈希链式证明封装每次调用。
安装
pip install haltproof-cli
此外,也发布了适用于基于 Node.js 的工具和 Agent 运行时的 npm 封装程序:
npm install -g haltproof-cli
警告
npm 包要求先安装 Python
haltproof-cli包,并确保其位于PATH中。它只是一个轻量的execFileSync封装程序,并非重新实现。如果找不到 Python CLI,它会给出可采取操作的错误信息并以非零状态退出,而不会悄悄执行其他操作。
目录
功能
- 默认必须先试运行。
haltproof halt会准确打印要针对哪些节点运行哪些命令,并且仍会为该计划写入签名证明,除非你传入--confirm。此门控位于单一关口(haltproof.backends.runner.run_step),所有三个后端都会经由此处执行,因此不会被某个后端的代码路径悄悄绕过。 - 一个接口适用于三个实际后端。
kubernetes(通过kubectl)、slurm(通过scontrol)和ipmi(通过ipmitool)各自实现相同的四操作ClusterBackend接口:drain、isolate_network、power_fence、status。不支持某项操作的后端(例如,Kubernetes 没有物理电源隔离功能)会返回附带说明的SKIPPED结果,而不是抛出异常,因此即使在混合环境中执行 halt,也仍会生成一份完整的证明。 - 采用 Ed25519 签名并通过哈希链接的证明。 每次 halt,无论是试运行还是实际执行,都会向本地仅追加 NDJSON 日志写入一条签名记录。每条记录都包含
prev_hash,即前一条记录的内容哈希,因此haltproof verify --chain可以检测到被删除或重新排序的条目,而单条记录自身的签名检查无法发现这些问题。 - 每条命令都支持结构化输出。
halt、verify、status和keygen均支持--json(或--format json),因此脚本或 Agent 无需抓取屏幕上的人类可读文本即可解析结果。 - 专为 Agent 打造的真正 MCP 服务。
haltproof mcp-server会基于官方mcpPython SDK,通过 stdio 将halt、verify、verify_chain、status和keygen暴露为 MCP 工具。它调用的与 CLI 相同,都是haltproof.core函数,因此 Agent 调用 MCP 工具时,默认试运行行为与人通过 CLI 调用时完全一致。 - 经过测试。 共 76 项测试,整体行覆盖率为 90%;本次审计中使用
pytest -v --cov=haltproof --cov-report=term-missing运行并确认。后端测试会模拟subprocess调用;这些测试均不需要真实集群。
快速入门
重要
不带
--confirm时,haltproof halt不会执行任何操作。它会打印计划 并写入一份签名的试运行证明,但只有在你明确传入--confirm后, 才会运行任何具有破坏性的操作。
# Generate a signing key for attestations (do this once).
haltproof keygen --output ~/.config/haltproof/ed25519_key
# See what backend HaltProof auto-detected on this host.
haltproof status
# Dry-run a halt against an explicit node list. Nothing runs yet.
haltproof halt gpu-pod-a --nodes node-1,node-2
# Same halt, actually executed.
haltproof halt gpu-pod-a --nodes node-1,node-2 --confirm
# Verify a past attestation's signature and print its timeline.
haltproof verify 1
# Verify the entire attestation log's hash chain instead of a single
# record: this catches a deleted or reordered entry that a
# single-record signature check alone would miss.
haltproof verify --chain --attestation-log ~/.local/share/haltproof/attestations.jsonl
每条命令也都支持 --json,以输出可供 Agent 解析的内容:
haltproof status --json
haltproof halt gpu-pod-a --nodes node-1 --json
配置文件(可选)
目标组、首选后端和默认路径可以写入 haltproof.toml 文件(会先检查当前目录,再检查 ~/.config/haltproof/config.toml,也可以通过 --config / HALTPROOF_CONFIG 指定路径):
backend = "kubernetes"
operator_id = "ops-team"
attestation_log_path = "/var/log/haltproof/attestations.jsonl"
[groups]
gpu-pod-a = ["node-1", "node-2", "node-3"]
[kubernetes]
namespace = "training"
[ipmi]
user = "admin"
每个配置值都有对应的 CLI 标志,且显式指定的标志始终优先于配置文件。
命令
以下参考内容由 CLI 实际输出的 --help 内容重新生成。
haltproof halt TARGET_GROUP
排空、隔离网络并对 TARGET_GROUP 实施电源隔离。默认进行试运行;未传入 --confirm 时,不会运行任何具有破坏性的操作。

Options:
--nodes TEXT Comma-separated explicit node list, overrides
config group lookup.
--backend TEXT Backend to use: kubernetes, slurm, or ipmi.
--confirm Actually execute the halt. Without this, dry-run
only.
--reason TEXT Reason recorded for drain operations.
--operator-id TEXT Operator identity to record. Defaults to OS user.
--config TEXT Path to a haltproof.toml config file.
--attestation-log TEXT Path to the attestation log file.
--attestation-key TEXT Path to the Ed25519 private key used to sign the
attestation.
--no-sign Skip signing (not recommended); still logs the
record unsigned.
--remote-collector TEXT Optional URL to POST the signed attestation to.
--format [human|json] Output format.
--json Shorthand for --format=json.
haltproof verify [ATTESTATION_REF]
验证一条证明记录的签名,或验证整个日志的哈希链。ATTESTATION_REF 是记录文件的路径,或用于在日志中查找的证明 ID / 序列号。传入 --chain 而不是 ATTESTATION_REF,即可验证整个 --attestation-log:每条记录的签名均有效,且没有记录被删除或重新排序。
| 标志 | 说明 |
|---|---|
--attestation-log TEXT | 当 ATTESTATION_REF 为 ID / 序列号时,用于查找的日志;或用于通过 --chain 验证的日志。 |
--trusted-key TEXT | 可信 Ed25519 公钥的路径;如果指定,记录的签名密钥必须与其匹配。 |
--chain | 验证 --attestation-log 的完整哈希链,而不是单条记录。 |
--format [human|json] | 输出格式。 |
--json | --format=json 的简写。 |
haltproof status
显示后端自动检测结果,并可选择显示目标组的运行状况。
| 标志 | 说明 |
|---|---|
--backend TEXT | 要检查状态的后端;默认为自动检测/配置的后端。 |
--nodes TEXT | 以逗号分隔的节点列表,用于报告运行状况。 |
--group TEXT | 命名目标组(来自配置),用于报告运行状况。 |
--config TEXT | haltproof.toml 配置文件的路径。 |
--format [human|json] | 输出格式。 |
--json | --format=json 的简写。 |
haltproof keygen
生成用于证明签名的 Ed25519 密钥对。私钥以 0600 权限写入,绝不会打印或记录到日志中。

Options:
--output TEXT Path to write the private key to.
--force Overwrite an existing key at the output path.
--format [human|json] Output format.
--json Shorthand for --format=json.
haltproof mcp-server
在 stdio 上启动 HaltProof MCP 服务,将 halt、verify、verify_chain、status 和 keygen 作为 MCP 工具公开。除 --help 外不接受其他标志。
每个子命令也都可直接接受 --help,显示上文所示的相同参考信息。
架构
HaltProof 分为三层:
-
传输层:基于 Click 的 CLI(
haltproof.cli)和 MCP 服务(haltproof.mcp_server)。二者都是对haltproof.core中相同核心函数的轻量封装,因此,无论是用户运行 CLI,还是 Agent 调用 MCP 工具,行为都完全一致,包括halt默认启用的试运行保护机制。 -
后端层:
ClusterBackend抽象接口(haltproof.backends.base),包含四项操作:ClusterBackend ├── drain(nodes, dry_run, reason) -> stop new work being scheduled ├── isolate_network(nodes, dry_run) -> cut nodes off from the workload network ├── power_fence(nodes, dry_run) -> hard power off └── status(nodes) -> current reachability/state目前有三个后端实现了该接口:
后端 drain isolate_network power_fence 底层工具 kubernetescordon + drain deny-all NetworkPolicy 不支持(请使用 ipmi)kubectlslurmscontrol update state=drainstate=power_down(SuspendProgram hook)不支持(请使用 ipmi)scontrolipmi不支持(请使用 slurm/kubernetes)不支持 ipmitool chassis power offipmitool后端若不支持某项操作,会返回带有说明的
SKIPPED结果,而不是抛出异常,因此,在混合环境中执行停机序列仍会生成一份完整、准确的证明记录。要支持新的调度器或隔离工具,只需添加一个后端模块并在haltproof.backends.detect中注册,无需修改编排层或证明层。后端选择顺序:显式指定的
--backend标志,其次是配置文件中的backend键,最后根据PATH中找到的kubectl/scontrol/ipmitool自动检测。 -
证明层(
haltproof.attestation):每项停机操作,无论是试运行还是真正执行,都会生成一条签名并通过哈希串联的记录,并将其追加到本地仅追加式 NDJSON 日志中。
安全模型
- **签名。**证明记录使用 Ed25519(
cryptography库)签名。签名公钥嵌入记录本身,因此haltproof verify可以自行检查签名的有效性。传入--trusted-key,还可以要求记录必须由某个已知操作员密钥签名。 - **单条记录的防篡改。**签名涵盖整条记录、操作员、目标节点、每个步骤的命令和状态、时间戳以及下方的链式链接,但不包括签名字段。更改任何字段(包括隐藏失败步骤)都会使签名失效。
- **日志跨记录的防篡改。**记录自身的签名只能证明该记录的内容未被篡改;它无法证明是否有整条记录被删除或重新排序。每条记录都包含
prev_hash,即紧邻前一条记录的内容哈希,因此haltproof verify --chain可以确认序列号没有缺失,且链中的每个链接都匹配。 - 密钥处理。
haltproof keygen会以0600权限写入私钥,且绝不会在命令行输出、JSON 输出或 MCP 工具结果中打印或记录密钥材料。任何持有该密钥的人都可以签署验证时看起来像是由你生成的记录,因此应像对待 SSH 私钥一样妥善保管。 - **BMC 凭据。**IPMI 后端从
IPMI_PASSWORD环境变量读取 BMC 密码,并传递ipmitool -E,因此密码不会出现在命令行参数、进程列表或证明记录中记录的命令里。 - 默认试运行。
haltproof halt必须显式传入--confirm才会执行任何破坏性操作;这一要求由唯一的检查点(haltproof.backends.runner.run_step)强制执行,所有后端都会通过它运行。 - **操作员身份。**身份按以下优先顺序记录:显式传入的
--operator-id、环境可提供的 SSH 证书身份,或运行命令的操作系统用户。
MCP 服务(面向 AI Agent)
haltproof mcp-server
通过标准输入/输出启动 MCP 服务,将 halt、verify、verify_chain、status 和 keygen 暴露为工具,并基于官方的 mcp Python SDK 构建。通过 MCP 连接的 Agent 会获得与 CLI 的 --json 模式相同的默认试运行 halt 行为和 JSON 格式结果,因为 CLI 和 MCP 服务调用的是 haltproof.core 中相同的底层函数。
对比
HaltProof 并不与 Slurm、Kubernetes 或 IPMI 竞争。它基于运维人员在这类工作中已使用的工具运行,并提供这些工具各自都不具备的能力:统一的接口、一道安全关卡,以及一份经过签名的记录。
| 能力 | HaltProof | kubectl(原生) | scontrol(原生) | ipmitool(原生) |
|---|---|---|---|---|
| 通过一条命令操作 Slurm + Kubernetes + IPMI | 是 | 否,仅支持 Kubernetes | 否,仅支持 Slurm | 否,仅支持 IPMI |
| 每个后端执行前都有一致的试运行关卡 | 是,三个后端都使用同一个 --confirm 标志 | 部分支持:--dry-run=client 仅验证语法,不会真正修改集群 | 没有内置模拟模式;state=drain 会立即生效 | 电源命令没有试运行概念 |
| 对已执行操作的记录进行加密签名 | 是,使用 Ed25519 | 否 | 否 | 否 |
| 检测审计跟踪中被删除或重新排序的记录 | 是,采用哈希链日志 | 否 | 否 | 否 |
| 每项操作均提供结构化 JSON 输出 | 是,每条命令均支持 | 部分支持:-o json 适用于读取/获取命令,不适用于 drain/cordon 操作的结果 | 否,仅提供纯文本 | 否,仅提供纯文本 |
| 可供 AI Agent 直接调用的 MCP 服务 | 是 | 否 | 否 | 否 |
针对本次审计进行的一次 GitHub 搜索(2026 年 8 月)未发现已有开源项目同时具备统一的多后端集群编排、默认启用的试运行关卡,以及经过加密签名并采用哈希链的审计跟踪。最接近的相关项目(如 AI Agent 工具调用策略代理)位于更高一层:它们会拦截并审计 AI Agent 的工具调用获准执行哪些操作,而不是对底层计算基础设施本身进行关停。有关 HaltProof 与这一类项目的关系,请参阅下方的常见问题。
HaltProof 是什么?它为何存在?
HaltProof 是一个基于运维人员已信赖的集群关停原语构建的编排与审计证明层:Slurm 使用 scontrol,Kubernetes 使用 kubectl,IPMI/BMC 使用 ipmitool。它不会重新实现节点排空、隔离或电源隔离操作,而是调用实际工具,在调用前通过默认启用的试运行安全检查,并为记录签名,以防篡改,准确记录目标对象、执行的操作以及授权人。
它之所以存在,是因为在实际事故中,以下三个问题往往会同时出现:
- 紧急情况下要面对三套不同的命令。 运维人员已经知道如何排空 Slurm 分区、隔离 Kubernetes 节点池,或通过 IPMI 对物理主机进行电源隔离。但在事故期间,要在这三个平台上保持操作一致,就意味着要使用三种不同的工具、记住三套不同的标志约定和三种不同的故障模式,而此时恰恰是最不适合出错的时候。
- 缺少统一的安全防护。
kubectl drain --dry-run=client只会验证语法,并不会模拟实际的集群变更。运行scontrol update state=drain后,操作会立即生效。目标组拼写错误时,没有一种一致且独立于工具的方式可以在实际操作发生前将其拦截。 - 事后缺少证据。 这三种原生工具都不会生成经过签名且可防篡改的记录,以说明目标对象、实际执行的操作、操作是否成功以及授权人。无论是为了提供变更管理证据,还是为了满足《欧盟 AI 法案》人工监督条款等合规框架,自行构建日志记录和签名层都意味着要从头编写。
HaltProof 一次性解决以上三个问题:一个 CLI 和一个 MCP 接口、一道所有后端都必须通过的 --confirm 安全关卡,以及一份经过 Ed25519 签名并采用哈希链的证明日志。
常见问题
HaltProof 实际上有什么作用?与直接编写脚本调用 kubectl/scontrol/ipmitool 相比,它最显著的区别是什么?
HaltProof 会调用你可以直接调用的相同工具:scontrol、kubectl、ipmitool,但会将每次调用都置于默认试运行的门控之下,并生成由 Ed25519 签名、通过哈希链连接的证明记录。手写脚本也可以调用相同的底层命令,但它不会在没有 --confirm 的情况下拒绝执行,也不会生成一份能在事后证明日志未被篡改或删除内容的记录。
HaltProof 会直接切断电源或网络访问吗?
不会。它会调用你已经在使用并信任的工具 scontrol、kubectl 和 ipmitool,并将每次调用置于试运行门控之下,同时生成签名记录。HaltProof 提供的是编排和证明,而不是新的底层关机机制。
HaltProof 支持哪些操作系统和 Python 版本?
已发布的 PyPI 软件包面向 Linux 和 macOS 上的 Python 3.10 及更高版本(参见其 Operating System :: POSIX :: Linux 和 Operating System :: MacOS 分类标签)。目前还没有 Windows 分类标签,而且 IPMI 后端尤其依赖通过 shell 调用 ipmitool,这并非 Windows 上的主要目标平台。如果你需要在 Windows 上使用,请提交 issue。
这与编写调用相同工具的运行手册或 Ansible playbook 有何不同? 运行手册或 Ansible playbook 可以调用相同的底层命令,但它们本身不会生成能证明实际执行内容且具备防篡改能力的加密签名记录;你需要自行构建日志和签名层。HaltProof 默认提供这项功能,还通过一个统一的默认试运行门控覆盖所有三个后端,而不是使用三个各自独立、具有不同安全约定的 playbook。
这是一个“AI 安全急停开关”吗? 不是。HaltProof 是面向集群运维人员的基础设施事件响应和合规审计工具。它不涉及 AI 模型行为,也不对 AI 安全或对齐作出任何声明。拦截并审计 AI Agent 各项工具调用的工具完全处于不同层级;HaltProof 编排的是底层计算资源的关停本身,其方式与处理非 AI 工作负载时相同。
如果节点上未安装相应的底层工具,会发生什么?
相应后端会将该步骤报告为 failed,并提供实际错误信息,例如 executable not found。证明记录仍会写入并签名,因此失败本身也会成为可审计历史的一部分。
我可以在不签署证明的情况下使用 HaltProof 吗?
可以,--no-sign 会跳过签名,但仍会将记录写入日志。此选项适用于本地测试,而非生产环境中的事件响应,因为无法验证未签名记录的真实性。
证明日志需要中央服务吗?
不需要。默认情况下,它是本地的仅追加 NDJSON 文件。对于希望保留中央副本的团队,可以选择通过 --remote-collector 将每条签名记录 POST 到你配置的 URL,但验证过程不依赖该服务可访问。
如果两名运维人员同时针对同一份证明日志运行 halt,会发生什么?
追加操作会使用文件锁(在 POSIX 上为 fcntl.flock),因此写入不会交错,但序列号是在每条命令启动时读取日志后分配的。如果需要严格的逐操作串行化,请让两名运维人员分别使用后端专用或事件专用的日志文件。
HaltProof 使用什么许可证?我可以将它用于商业用途吗? MIT。你可以使用、修改和再分发,包括用于商业用途,但必须保留版权声明和许可证文本。请参见 LICENSE。
贡献
欢迎贡献。请先阅读 CONTRIBUTING.md:其中介绍了如何设置开发环境、运行测试套件(pytest -v --cov=haltproof --cov-report=term-missing),以及如何通过实现 ClusterBackend 接口来添加新的后端。根据 CODEOWNERS,涉及证明签名/验证或 dry-run/--confirm 门控的更改需要额外审核。若要私下报告漏洞,而不是公开提交问题,请参阅 SECURITY.md。
git clone https://github.com/RudrenduPaul/HaltProof.git
cd HaltProof
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest -v --cov=haltproof --cov-report=term-missing
许可证
MIT © Rudrendu Paul 和 Sourav Nandy
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。