商业产业 Hacker News Agent 2026-07-06T13:17 正文 ok 982 words

🔶 Show HN: 扫描你的 AI 代理,发现危险能力

英文标题:🔶 Show HN: Scan your AI agents for dangerous capabilities

MakerChecker 是一个开源的 AI 代理安全层,提供默认拒绝执行、人工审批和加密签名的审计追踪。它无需安装即可扫描代理的现有能力,按风险分类标记危险操作,并能自动生成治理代码。通过嵌入式和自托管服务器,开发者可确保代理只能执行已授予的技能,且无法自行审批高风险工作,所有决策都记录在防篡改的哈希链日志中。该项目为使用 LangChain、Claude SDK 等框架的开发者提供了即插即用的治理方案,对于需要满足合规和审计要求的行业场景具有重要价值。
打开原文相关 3 · 机会 1
media2.2 KB media1.3 KB media1.4 KB media2.7 KB media58.2 KB

中文

AI 代理的开源安全层。

默认拒绝执行、人工审批和加密签名的审计追踪——让你的代理仅运行已授予的权限,并可证明无法自行审批自己的工作。

持续集成状态 发布版本 许可证 星标

网站 · 在线演示 · mc scan · 文档

你的代理继续在现有框架(LangChain、Claude SDK、CrewAI)中运行。MakerChecker 位于每个工具调用的前方作为检查点,后方作为签名的分类账:代理仅通过角色行动,仅运行已授予的技能,无法超出其权限,且无法自行审批自己的工作。


发现你的代理目前已能独自完成的操作,并按风险分类。无需安装,所有数据不离开你的机器:

它会标记每一个有后果的操作——删除数据、转移资金、执行 shell 命令、窃取机密——并用其对应的真实事件命名,还可以通过 --fix 为你编写治理代码。→ packages/scan

2 — 保证其行为

导入控制并包装任意工具。代理现在只能运行其角色被授予的操作——未被允许的调用在执行之前便被拒绝:

npm i @makerchecker/embedded

javascript import { createGovernor, GovernanceDeniedError } from "@makerchecker/embedded";

const gov = createGovernor() .defineSkill("place-order@1", { riskTier: "high" }) .defineRole("agent") .defineRole("risk-desk") .grant("risk-desk", "place-order@1") // 代理未被授予此技能——默认拒绝 .defineAgent("trader", "agent");

// 包装你的工具。现在代理在结构上无法触发它。 const placeOrder = gov.governedTool("trader", "place-order@1", (order) => broker.submit(order));

try { await placeOrder({ symbol: "BTC", qty: 10 }); } catch (err) { if (err instanceof GovernanceDeniedError) console.log(err.code); // "skill_not_granted" }

高风险技能归属于一个独立的角色,这样代理永远无法自行批准自己的工作——每一个决策,无论是允许还是拒绝,都会写入签名的审计日志。→ packages/embedded

3 — 与审计人员协作?

步骤 2 已经在写入签名日志。当审计人员需要一个持久、可查询、防篡改的记录——外加一个人工审批收件箱和审查控制台时——可以运行自托管服务器:

每一项决策都经过 Ed25519 签名和哈希链连接:更改任何一行都会导致验证失败。导出一个捆绑包,任何人都可以离线验证——不需要数据库,也无需信任产生它的过程。→ 完整服务器设置见下文

这是三个独立的包 —— mc scan, @makerchecker/embedded, 和 server —— 它们执行相同的控制并写入相同的签名审计格式。你可以单独采用其中任何一个。


通过人工关卡执行重要工作的代理可运行示例:

  • 药物警戒病例处理 —— 代理对不良事件报告进行分类,但在加速 15 天监管报告传输之前,需要医学审查员签字。 examples/pv-icsr-processing
  • 医疗器械(MDR)投诉分类 —— 监管人员在关卡后决定是否可报告,然后才生成报告草稿。 examples/mdr-reportability-triage
  • 肿瘤科患者准入 —— 代理处理福利匹配,但若无专科医生签字,则被阻止提交共付额登记。 examples/oncology-patient-access
  • 每日现金对账 —— 财务代理对账交易,但在异常关卡处锁定,直到现金专员签字放行。 examples/daily-cash-reconciliation

🔌 与你的框架集成

即插即用的连接器管理你现有的工具:

javascript import { createClient, governedTool, GovernanceDeniedError } from "@makerchecker/sdk";

const client = createClient({ baseUrl: "http://localhost:3000", apiKey: "mk_..." }); const { session } = await client.proxy.openSession({ label: "recon-run" });

const match = governedTool( client, session.id, "recon-preparer", // 代理,其角色授权将被评估 "txn-match@1", // skillRef: name@version (input) => matchTxns(input), );

await match({ statement, ledger }); // 若被拒绝则抛出 GovernanceDeniedError await client.proxy.closeSession(session.id);


🖥️ 自托管服务器(可选)

当需要在多个代理之间进行集中强制执行、拥有一个人工审批收件箱和一个审查控制台时,运行完整的网关。docker compose up 会启动 Postgres、位于 localhost:3000 的服务器以及一个种子演示,并打印两个 API 密钥——一个管理员密钥(你的代理用于身份验证运行)和一个官员密钥(人工审查者用于批准关卡操作)。

种子药物警戒流程停在一个医学审查关卡,在此请求者不能作为自己的审批人而被拒绝:

shell export H='authorization: Bearer mk_...' # 管理员密钥 export OFFICER='authorization: Bearer mk_...' # 官员密钥

curl -X POST localhost:3000/api/flows/pv-icsr-processing/runs -H "$H" -H 'content-type: application/json' -d '{}' curl localhost:3000/api/approvals -H "$H"

请求者无法批准自己的运行——返回 403

curl -X POST localhost:3000/api/approvals//decision -H "$H" -H 'content-type: application/json'
-d '{"decision":"approved","reason":"self-approval attempt"}'

一个独立的官员签字;只有这样做才能继续执行

curl -X POST localhost:3000/api/approvals//decision -H "$OFFICER" -H 'content-type: application/json'
-d '{"decision":"approved","reason":"严重性已确认;提交 15 天加速 ICSR。"}'

curl localhost:3000/api/audit/verify -H "$H"

完整设置、Kubernetes/Helm 以及使用实时模型运行:docs/quickstart.md。


每一项决策和工具调用都提交到一个哈希链日志中——每个事件都是事件 RFC 8785 规范 JSON 的 SHA-256 哈希,通过 prev_hash 从创世块链接起来,并经过 Ed25519 签名。更改任何一行都会导致验证失败。任何人都可以离线验证导出的捆绑包——无需数据库,也无需信任产生它的过程:

npx @makerchecker/proof-verifier verify bundle.json

规范:docs/audit-spec.md。


贡献指南:CONTRIBUTING.md · 安全:SECURITY.md · 行为准则:CODE_OF_CONDUCT.md

English / 原文

The open-source security layer for AI agents.

Deny-by-default enforcement, human approvals, and a cryptographically signed audit trail — so your agent runs only what it's granted and provably can't approve its own work.

CI Release License Stars

Website · Live Demo · mc scan · Docs

Your agents keep running in their existing framework (LangChain, Claude SDK, CrewAI). MakerChecker sits in front of every tool call as a checkpoint and behind it as a signed ledger: an agent acts only through a role , runs only the skills it was granted , cannot exceed its limits, and cannot approve its own work.


Find what your agent can already do on its own, classified by risk. No install, nothing leaves your machine:

It flags every consequential action — deleting data, moving money, running shell commands, exfiltrating secrets — names each against the real incident it resembles, and can write the governance code for you with --fix. → packages/scan

2 — Guarantee its behavior

Import the controls and wrap any tool. The agent can now only run what its role was granted — a call it isn't allowed is denied before it executes:

npm i @makerchecker/embedded


import { createGovernor, GovernanceDeniedError } from "@makerchecker/embedded";

const gov = createGovernor()
  .defineSkill("place-order@1", { riskTier: "high" })
  .defineRole("agent")
  .defineRole("risk-desk")
  .grant("risk-desk", "place-order@1")   // the agent is NOT granted it — deny by default
  .defineAgent("trader", "agent");

// Wrap your tool once. Now the agent structurally can't fire it.
const placeOrder = gov.governedTool("trader", "place-order@1", (order) => broker.submit(order));

try {
  await placeOrder({ symbol: "BTC", qty: 10 });
} catch (err) {
  if (err instanceof GovernanceDeniedError) console.log(err.code); // "skill_not_granted"
}

High-risk skills go to a separate role, so an agent can never approve its own work — and every decision, allowed or denied, commits to a signed audit log. → packages/embedded

3 — Working with auditors?

Step 2 already writes a signed log. When auditors need a durable, queryable, tamper-evident record — plus a human-approval inbox and a review console — run the self-hosted server:

Every decision is Ed25519-signed and hash-chained: change any row and verification breaks. Export a bundle and anyone verifies it offline — no database, no trust in the process that produced it. → full server setup below

These are three independent packages — mc scan, @makerchecker/embedded, and the server — that enforce the same controls and write the same signed audit format. Adopt any one on its own.


Runnable examples of agents doing consequential work behind a human gate:

  • Pharmacovigilance case processing — an agent triages adverse-event reports, but a medical reviewer signs before an expedited 15-day regulatory report transmits. examples/pv-icsr-processing
  • Medical-device (MDR) complaint triage — a regulatory officer decides reportability behind a gate before draft reports are generated. examples/mdr-reportability-triage
  • Oncology patient access — an agent handles benefit matching but is blocked from submitting copay enrollments without a specialist signing. examples/oncology-patient-access
  • Daily cash reconciliation — a finance agent reconciles transactions but locks at exception gates until a cash officer signs off. examples/daily-cash-reconciliation

🔌 Integrate With Your Framework

Drop-in connectors govern the tools you already have:

When you run the server, the SDK's governedTool routes each call through a proxy session for centralized authorization and recording:

import { createClient, governedTool, GovernanceDeniedError } from "@makerchecker/sdk";

const client = createClient({ baseUrl: "http://localhost:3000", apiKey: "mk_..." });
const { session } = await client.proxy.openSession({ label: "recon-run" });

const match = governedTool(
  client, session.id,
  "recon-preparer",   // agent whose role grants are evaluated
  "txn-match@1",       // skillRef: name@version
  (input) => matchTxns(input),
);

await match({ statement, ledger });   // throws GovernanceDeniedError if denied
await client.proxy.closeSession(session.id);

🖥️ Self-Hosted Server (optional)

Run the full gateway when you need centralized enforcement across many agents, a human-approval inbox, and a review console. docker compose up brings up Postgres, the server on localhost:3000, and a seeded demo, printing two API keys — an admin key (your agent authenticates runs) and an officer key (a human reviewer approves gated actions).

The seeded pharmacovigilance flow parks at a medical-review gate where the requester is refused as its own approver:

export H='authorization: Bearer mk_...'         # admin key
export OFFICER='authorization: Bearer mk_...'   # officer key

curl -X POST localhost:3000/api/flows/pv-icsr-processing/runs -H "$H" -H 'content-type: application/json' -d '{}'
curl localhost:3000/api/approvals -H "$H"

# The requester cannot approve their own run — rejected with 403
curl -X POST localhost:3000/api/approvals/<id>/decision -H "$H" -H 'content-type: application/json' \
  -d '{"decision":"approved","reason":"self-approval attempt"}'

# A separate officer signs; only now does the action proceed
curl -X POST localhost:3000/api/approvals/<id>/decision -H "$OFFICER" -H 'content-type: application/json' \
  -d '{"decision":"approved","reason":"Seriousness confirmed; file 15-day expedited ICSRs."}'

curl localhost:3000/api/audit/verify -H "$H"

Full setup, Kubernetes/Helm, and running with live models: docs/quickstart.md.


Every decision and tool call commits to a hash-chained log — each event a SHA-256 over the RFC 8785 canonical JSON of the event, chained through prev_hash from genesis and Ed25519-signed. Change any row and verification breaks. Anyone can verify an exported bundle offline — no database, and no trust in the process that produced it:

npx @makerchecker/proof-verifier verify bundle.json

Spec: docs/audit-spec.md.



Contributing: CONTRIBUTING.md · Security: SECURITY.md · Code of Conduct: CODE_OF_CONDUCT.md