关于 Seal
Seal 是用于跨进程协调支付等不可逆操作的 Python 库和 MCP 服务。它通过共享 Postgres 原子准入,并结合支付服务商确认记录,防止重复执行和核验结果。
主要功能
- 01通过共享 Postgres 原子准入
- 02哈希链式操作证书
- 03服务商见证与结果核验
- 04支付路径的自主等级
- 05执行前检查世界数据是否过期
适用场景
- 01阻止并发 Agent 重复扣款
- 02向支付服务商核实不确定的付款
- 03发现网关外扣款后暂停支出
MCP 相关
Seal 向 MCP 主机提供 12 个工具,用于提议、准入、执行和核验不可逆操作;网关模式使用一次性票据,而非暴露服务商密钥。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
seal
公开登记册:重试安全性索引列出了哪些 Agent 付款实现会在答案丢失时只付款一次,包括已验证安全、已发现并修复(附修复耗时),以及如何获得验证。每一行都链接到相应的证明。
让你的 Agent 赢得无需你介入即可支出的权利。
Seal 与 Coherence 不同
Seal 和 EffectFence 会在不可逆操作发生时阻止它重复执行——在资金转移过程中进行运行时强制执行。Coherence 从不接触你的运行时;它会在事后读取记录,并对照 Agent 的声明与其证明进行评估。**预防与证明。**解决的问题不同,代码不同,彼此没有重叠。
免费:提交任何会转移资金的客户端、支付协调器、SDK 或工具包——无论是你自己的还是别人的——我们都会阅读并在重试安全性索引上免费发布评估结果。反馈会附上机制、文件和行号,以及一个失败测试。在你发布修复之前,我们只统计,不公布名称。提交评估 →
Seal 是一个 MCP 服务(seal-mcp、stdio、JSON-RPC 2.0),也是一个 Python
库。它为 MCP 主机提供 12 个工具,用于不可逆操作的恰好一次执行:seal_propose、seal_execute、seal_paths(网关模式——Agent 持有一次性票据,而非服务提供方密钥),以及
seal_admit、seal_commit、seal_abort、seal_heartbeat、seal_get、
seal_verify、seal_incident_receipt、seal_expect、seal_obligations。
docker run -i ghcr.io/aurumflux20/seal # or: python -m seal.mcp_server
启动时处于仅检查模式,无需环境配置——initialize 和
tools/list 无需数据库即可响应,因此主机或注册表探测可以立即连接。
设置 SEAL_DSN 为 Postgres DSN 才能实际准入操作;网关模式则需设置
SEAL_EXECUTORS=your.module。
// claude_desktop_config.json
{ "mcpServers": { "seal": { "command": "python", "args": ["-m", "seal.mcp_server"],
"env": { "SEAL_DSN": "postgres://..." } } } }
不是工程师?请改读 docs/PLAIN-ENGLISH.md—— 内容相同,但没有术语,也包括我们做不到的事。
其他人提供的都是锁:设定一次就不再过问的支出上限。上限永远不会学习,因此,已经顺利结算一万笔付款的 Agent,与今天早上刚安装的 Agent 得到的信任程度完全相同——而你仍然要不断点击“批准”。
Seal 提供的是解锁。它会读取付款路径实际证明了什么——服务提供方确认的结算,以及表明没有资金在其背后转移的清扫记录——并计算该路径赢得的自主权。L0 OBSERVED → L5 AUTONOMOUS。 无需任何人手动输入等级。
████████············ L2 ASSISTED 50 proven · 100% confirmed [human required]
fifty settlements — but volume alone is not trust.
████████████········ L3 DELEGATED 50 proven · 100% confirmed [unattended]
one clean sweep later: the human stops clicking Approve.
···················· L0 OBSERVED 50 proven · 100% confirmed [SUSPENDED]
one charge the gateway never admitted. fifty clean ones don't outweigh it.
SEAL_DSN="..." python3 license_demo.py # watch a path earn L3 and lose it
自 0.4.0 起,许可证会驱动实际执行,而不只是仪表板。启用
自主权解锁——使用 Gateway(seal, earned_autonomy=True),或为 MCP 服务设置
SEAL_EARNED_AUTONOMY=1——网关就只会在路径凭自身记录赢得相应权限(L3+)的范围内,在操作方设定的上限内,允许该路径无人值守地转移资金,绝不会超出上限。三种情况会立即将控制权交还给人工:路径尚未赢得相应权限、服务暂停(资金绕过网关发生了转移),以及暂停等待——执行已到达服务提供方,但结果未知,因此路径会暂停,直到 settle() 向服务提供方查询结果。世界给出答复后,暂停等待会自动解除。人工仍可通过同一个制作者-复核者流程(tier=LICENCE)批准任何单笔操作。此功能默认关闭:切换启用前,一切照旧。
你能证明你的 Agent 不会向客户重复收费吗? 三档服务,一条晋级路径,仅书面交付:300 美元创始合规测试——对你的实现运行整套测试,并将结果发布到 Index(仅限前三位; 预订)· 1,200 美元认证测试 ——针对你的在线端点测试所有模糊结果,签署测试结果,五个工作日内提供调查结果,通过测试后在 24 小时内签署认证 (预订)· 12,000 美元固定范围的 资金路径审查——在 7–10 天内读取、测试并认证一条生产资金路径,如果没有证据表明你运行的路径会实际触发重复操作,则不收费。如需先免费自查, hostile-facilitator 会在 60 秒内给出结果。
信誉建立缓慢,失去却只需一瞬——这才是让过往记录真正有意义的唯一方式。完整的等级定义见:docs/AUTONOMY-LEVELS.md。
Seal 的模糊结果处理原则——“无法确定”是终态,绝不等于“未发生”——现已写入由我们共同起草的 MCP 重试安全提案第 4.3 节,其测试套件就是我们的合规测试集。
底层机制:恰好一次准入
两个不同的 Agent,在两台不同的机器上,同时决定对订单 123 收费。进程内幂等性无济于事——防护机制必须位于两个 Agent 都能访问的存储中,并且必须在其中原子性地决定谁胜出。
Seal 就是这一层。一个 Postgres,每个意图对应一行,只允许一个胜出者:
INSERT ... ON CONFLICT DO NOTHING -- one row, one winner, no check-then-act window
每个获准执行的操作最终都会生成一份证书:一个内容寻址哈希,基于意图、参数摘要、结果摘要以及上一份证书的哈希计算得出。编辑、删除或重新排列任意证书,都会破坏之后的所有哈希——任何拥有 DSN 的人都能检查,无需联网,也无需信任我们:
SEAL_DSN="..." python3 -m seal verify
# chain VERIFIED — 41 cert(s), every link intact (exit 0; broken chain → exit 1)
验证
我们以对抗性方式测试这一声明:1,000 个真实线程通过同一道屏障,同时向一个共享 Postgres 发起请求。“收费”操作会递增一个计量计数器——如果两个调用方都执行,计数器就会显示 2,测试会明确报错。
连续四次运行的结果:ACTUAL_EXECUTIONS = 1。 每个未胜出的请求要么重放已封存的证书,要么在操作进行中主动退出,要么在存储不可达时安全失败。封存后再发起 50 个调用:全部重放,没有一个重新执行。完整数据及坦诚说明的限制见:STORM-PROOF.md。
自行运行:
pip install seal-kernel
export SEAL_DSN="host=... dbname=seal"
python3 -m seal verify # chain check, no network, no trust in us
如需自行运行 1,000 线程风暴证明,请克隆仓库(测试工具随源代码提供,不包含在 wheel 中):
# Needs Python 3.10+. macOS ships 3.9 with pip 21, which fails an editable
# install with a misleading "setup.py not found" error — use a venv rather
# than debugging that.
git clone https://github.com/aurumflux20/seal && cd seal
python3 -m venv .venv && source .venv/bin/activate
python3 -m pip install -U pip && python3 -m pip install -e .
export SEAL_DSN="host=... dbname=seal"
python3 storm.py --n 1000
测试你自己的服务,而不只是我们的服务
将上面的精确测试工具泛化为一个独立文件,与本仓库零依赖——复制它,将其指向你自己的、可写入数据的工具,然后亲自验证:
python3 range_safety_test.py --n 1000
在你真正运行测试之前,它会先针对已知不安全和已知安全的目标自行演示,因此通过测试才有意义。完整说明见 docs/RANGE-SAFETY-TEST.md,其中包括早期版本的这项测试曾经误导我们的三种情况,以及我们如何修复它们。
用法
from seal import Seal
seal = Seal(dsn); seal.setup()
adm = seal.admit("charge", {"order_id": "123", "amount": 4900})
if adm.fresh: # you won — run the effect, then seal it
result = stripe_charge(...)
cert = seal.seal(adm.intent, adm.fence, result)
elif adm.cert is not None: # already done — here is the receipt
return adm.cert
else: # someone else is mid-flight — stand down
raise InFlight()
如果效果在尚未发生任何不可逆操作之前失败,请释放声明,以便可以安全重试:seal.fail(adm.intent, adm.fence, reason)。
当持有者在效果执行期间死亡时(其租约过期,而意图仍处于打开状态),下一次 admit() 不会发放新的声明。过期本身无法说明持有者是在提供方响应前崩溃,还是仍在等待一个缓慢的提供方调用,因此重新执行就意味着在结果未知的情况下执行——而 Seal 承诺绝不会这样做。你会得到 fresh=False, cert=None, reason="lease expired with no witness…";请通过见证进行处理(Gateway.register_witness 或 seal.settle(intent, witness)):如果效果已生效,则修复记录;如果没有生效,则释放声明。Seal(dsn, blind_reclaim=True) 会恢复旧的接管行为,适用于从设计上就具备幂等性的提供方。网关会在整个提供方调用期间为租约发送心跳,因此缓慢的 Stripe 调用会保留其声明,而不会丢失。
世界确认——基于真实 Stripe 测量,而非模拟
一张声称“只准入一次”的证书,说的是我们自己的情况。接下来要问的是 Stripe(或 Resend,或你的银行 Webhook)实际记录了什么——答案可以与我们不一致。
export SEAL_DSN="host=... dbname=..."
export STRIPE_TEST_KEY="sk_test_..." # your own test-mode key, Dashboard -> API keys
python3 stripe_demo.py
它在你的真实 Stripe 测试账户上执行以下操作,不使用模拟:
- 两个 Agent 在同一时刻发起相同的扣款。 Seal 只准入其中一个。
实际创建的
PaymentIntent恰好只有一个。 - 见证查询 Stripe: “有多少笔扣款带有此意图?” Stripe 回答一笔 → 证书升级为
WORLD_FINAL。 - 在网关之外创建一笔违规扣款——这是本地围栏无法独自阻止的情况。见证再次查询;Stripe 此时回答两笔 → 证书变为
WORLD_DIVERGED,该域被冻结,系统会自动拒绝在该域上继续支出。
这次真实运行让我们确认了两件实事,两者都已修复并经过测试:Stripe 的搜索索引最终一致(新扣款可能要过好几秒才会出现——见证会持续轮询,直到得到确定答案,绝不会把“尚未编入索引”的空查询结果当作权威的“不存在”记录);而一旦真实状态与账本矛盾,之后不稳定的重新计数绝不能悄悄将证书降回 WORLD_FINAL——按设计,状态分歧一经确认便会持续保留。
提交前冻结世界状态——不要依据已经变化的事实采取行动
admit() 一直接受 read_set——即决策所依赖的世界事实(例如购物车总额、库存数量)——并将其存储在证书中。直到现在,这些事实从未得到检查:调用方以为自己有过期保护,实际上却没有。其缺陷与当天早些时候修复的另一个缺陷如出一辙,只是高了一层——约束已写入架构,却从未真正执行。
from seal.freshness import CallableChecker
fresh = CallableChecker(lambda rs: current_cart_total(rs["order_id"]) == rs["total"])
adm = seal.admit("charge", {"amount": 5000}, key="order-777",
read_set={"order_id": "777", "total": 5000}, checker=fresh)
# StaleWorldRead is raised BEFORE a fence is granted if the checker says no —
# nothing runs on facts that already changed. Gateway.propose() takes the
# same read_set/checker kwargs and passes them straight through.
选择在围栏之前而非效果执行之后进行检查,是经过审慎考虑的:事后检查只能拒绝确认成功,却无法阻止基于过时信息转移资金,而这正是此功能要防止的实际故障。此功能采用可选启用且向后兼容的方式,遵循本库其他功能一贯的规则:只有调用方同时提供 read_set 和 checker 时才会启用。我们会如实说明其限制,并在适用之处直接指出,而不是等人发现:检查器调用本身无法与准入 INSERT 保持原子性,因此在这个狭窄间隙内发生的变化仍会留下一个窗口——这与见证所依赖的提供方索引最终一致属于同一类注意事项。
Clearance — 必须通过赢得信任获得,而非自行宣称
围栏证明某项操作曾经运行过一次。Clearance 是更上一层的机制,也是公司真正愿意为之付费的东西:Agent 可以在无人值守的情况下调用哪些工具路径,以及需要什么证据。
from seal.clearance import Clearance, CLEARED
cl = Clearance(seal)
cl.set_policy("charge", CLEARED) # an operator's intent
cl.record_proof("charge", green=True, storm_n=1000, executions=1) # from CI
cl.status("charge")["effective"] # CLEARED — but only because both are true
让这不只是一个开关的规则是:CLEARED 必须通过赢得信任获得,而非自行宣称。 只有操作员设置了某条路径,并且最近记录了绿色风暴证明,该路径才会报告为有效的 CLEARED。如果最近一次证明变为红色,或证明已过期,status() 就会自行报告 HOLD——没人需要记得将其降级。REVOKED 始终优先,永远不会自动恢复;revoke_all() 则是一个能在关口处停止所有已知路径的开关。range_report() 会导出计数后的事件和引用提供商信息的认证——这正是安全问卷或 CFO 真正会查看的材料。
独占权限 — Agent 获得的是票据,而非凭证
Clearance 是策略。如果 Agent 仍持有 sk_live,它就能绕过策略;这不是防护栏,而只是建议。独占权限会彻底移除 Agent 持有的凭证。
from seal.authority import Gateway
gw = Gateway(seal)
gw.register_executor("charge", lambda args: stripe_charge(args)) # secret lives HERE only
prop = gw.propose("charge", {"amount": 4900}, key="order-777")
if prop["status"] == "cleared":
result = gw.execute(prop["ticket"], {"amount": 4900}) # gateway calls Stripe, not the agent
Agent 调用 propose() 后会获得一个票据——证明某项意图已获准、通过 Clearance 并纳入预算——绝不会获得密钥。只有 execute() 会实际调用提供商;票据会绑定到已获准的确切参数:如果传给 execute() 的内容与提议的内容不符,票据就会被拒绝;票据只能使用一次,并且会过期。(最初版本没有将参数绑定到签名,这意味着为 1 美元获准的票据本可以用于任意金额——这个问题是在发布前通过攻击我们自己的构建发现的,而不是发布后才发现。)
直白说明保管模式: 网关运行在你自己的基础设施内。AurumFlux 从不持有、查看或传输你的提供商密钥——我们提供的软件会将密钥从 Agent 手中移走;我们自己不会充当保险库。坦诚地说:同一主机上能读取网关自身环境的进程仍然可以窃取密钥。这提高了窃取密钥的门槛,让它变成“从保险库里偷”,但并非让窃取在物理上不可能。
分级 Clearance — 对重要金额实行经办与审批分离
对于 5 美元的 API 调用,二元式 CLEARED 已足够。但对于 50,000 美元的付款,财务部门不会就此签字——他们签字认可的是职责分离:提出支出的人绝不能是审批该支出的人,并且要留下记录。分级 Clearance 在 Clearance 之上增加了阈值:
from seal.graduated import GraduatedClearance, APPROVE
gc = GraduatedClearance(seal)
gc.set_thresholds("payout", auto_ceiling=100, dual_ceiling=10_000, required_approvers=2)
# amount 50 -> AUTO, ordinary Clearance applies
# amount 5000 -> DUAL, needs 2 distinct human approvals before it can execute
r = gc.request("payout", 5000, maker="alice", intent=intent)
gc.add_vote(r["id"], "bob", APPROVE)
gc.add_vote(r["id"], "carol", APPROVE) # now APPROVED — a THIRD person, not alice
该机制已接入网关:对于配置了阈值的路径,调用 Gateway.propose(..., amount=X) 会返回 {"status": "needs_approval", "tier": "DUAL"},而不是票据,直到提供符合要求的 approval_id。经办人不能审批自己的请求——这是由代码强制执行,而非依赖策略;即使发生真实的并发竞争,同一审批人也不能被重复计入,因为这是由 Postgres 的 (approval, approver) 上的 UNIQUE 约束保证的,而非应用层检查。一次拒绝即可终止审批。一次审批仅授权一次执行,并绑定到请求审批的确切意图。每个已作出决定的审批——无论批准还是拒绝,包括每一票——都会追加到与执行认证相同的哈希链中,因此 seal verify 会像验证实际运行的内容一样验证治理决策。
此设计向后兼容:从未对其运行过 set_thresholds() 的路径不会触发分级 Clearance,即使调用 propose() 时提供了金额也是如此——现有的仅预算集成不受影响。
端到端运行完整流程——无需支付提供商,也不会产生任何扣款:
python3 approval_demo.py
200 美元的采购会自动获准;12,000 美元的支出在两位不同的人类审批前会被拒绝;请求者尝试审批自己的请求时会被拒绝;同一审批人的重复投票会被拒绝;一次拒绝即可终止审批;250,000 美元的支出永远不会自动获准;而一次 revoke 会停止包括 200 美元路径在内的所有操作。流程最终会生成 Range Report,其中以金额说明审批情况——批准和拒绝的总额,而不是按事件类型统计数量。
可移植回执——可带出机构的证据
真正的争议涉及三方——授权 Agent 的用户、运行它的运营方,以及收款的商户——每一方都持有另外两方无法读取的数据库。seal verify 回答“这次运行是否恰好发生了一次,世界是否确认了它?”,但只有持有 DSN 的人才能获得答案,也就是说,只有被要求证明自己清白的一方才能获得答案。
可移植回执就是以文件形式呈现这个答案。证书在写入时会基于 RFC 8785 规范化 JSON 计算哈希,并在配置了密钥时通过 Ed25519 签名,因此对手方无需 数据库、网络,也无需我们的任何代码 就能验证它们——docs/verify-receipt.mjs 用大约 30 行 Node 代码就能完成:
pip install 'seal-kernel[signing]'
python -m seal keygen # SEAL_SIGNING_KEY= secret · public key= publish it
python -m seal export --intent <id> > receipt.json
python -m seal verify-receipt receipt.json --pubkey <hex> # needs NO DSN
node docs/verify-receipt.mjs receipt.json <hex> # or no Python at all
关于判定本身,请注意这些诚实的限制:使用固定密钥进行验证通过,证明 这些证书由密钥持有者生成且未被篡改——但无法证明完整性(是否存在其他证书,需要对照存储进行链检查);未固定密钥的验证只能证明内部一致性,绝不证明作者身份。签名是可选的;未签名的存储仍会像以前一样正常工作,v1 证书也会永远与 v2 证书一同通过验证。
settle()——去重不等于结算
幂等键可以让同一请求的重试安全进行,但无法回答超时后发生了什么,因为服务提供方可能已经采取了行动。这类意图会保持 open 状态;在 settle() 出现之前,唯一的解决方式是隐式的——未来某个调用方可能永远不会执行 admit(heal_with=…)。现在,解决它只需一个动词:
gateway.settle(intent) # uses the path's registered witness
# CONFIRMED_ONE → healed to WORLD_FINAL, budget reservation settled
# ABSENT → claim released for a clean retry, budget returned
# MULTIPLE → WORLD_DIVERGED on the chain, domain frozen
# UNKNOWN → unresolved, loudly — the claim stands, nothing is guessed
义务——警示 Agent 未能做到的事
上面提到的每种防护措施——以及我们所知的每种 Agent 安全工具——监控的都是作为:重复扣费、超支、矛盾。没有工具监控未作为。崩溃、丢失密钥或悄然停止运行的 Agent,看起来与无事可做的 Agent 完全一样——直到工资未能发放,或依法应在 14 天内退还的款项悄无声息地未能退还。
本仓库已经在测试中杜绝了这种失败模式(conftest.py:所有测试都被跳过的运行不算通过)。义务将同一原则应用于生产环境中的资金。这是对账扫描的对偶:
reconcile: provider effects − admitted intents = out-of-band (did too much)
obligations: declared duties − sealed intents = BREACH (did too little)
from seal.obligation import Obligations
obs = Obligations(seal); obs.setup()
# at decision time, the agent binds its future self:
obs.expect(action="refund", key="return-123", due_in_sec=14*86400,
description="statutory refund window for return #123")
# the business heartbeat:
obs.expect_recurring(action="renewal", every_sec=86400, min_count=1)
obs.sweep() # or: python -m seal obligations (exit 1 on any open breach)
让遗漏不只是仪表板上一行记录的关键在于:违约事件本身会追加到防篡改链中(删除它会破坏其后的每个哈希),而且 obligation_breached 是一个会暂停许可的事件——对已声明工作保持沉默的路径,会像重复扣费的路径一样失去已获得的自主权。Agent 可以声明职责(通过 MCP 使用 seal_expect);取消职责则是运营方的操作,没有面向 Agent 的工具,因为 Agent 可以取消的义务就不算义务。违约不会故意冻结路径——被冻结的退款路径无法补救未退还的退款;可采取的手段是证据、警报和许可。
Seal 证书声明了什么,又没有声明什么
证书证明该操作已在此网关获准执行且仅执行一次,并且记录的结果自此未被篡改。它并不证明外部世界已完成结算——每张 v1 证书都永久且有意地带有 world: "unconfirmed"。“我们只批准了这次操作一次”和“Stripe 已收款”是不同的声明;混淆两者正是此工具旨在阻止的错误类型。世界确认(通过服务提供方适配器,对照 Stripe 或你自己的服务提供方记录更新该字段)是下一层功能,而证书架构已经包含此字段,因此格式不会因此改变。
与 once-kernel、effectfence 和 coherence 的关系
once-kernel 证明了单个
进程没有重复执行某项操作。 effectfence
为单个 MCP 服务提供防护。Seal 是位于两者之上的跨进程层,适用于你的 Agent 超出单台机器的能力范围时。免费的基础组件将永远保持免费
(Apache-2.0 / MIT)。
关于 Agent PR 和 CI 中的声明与证据(说了 ≠ 证明了),请参阅独立项目
coherence——
它不属于本仓库;包不同,Git 历史也不同。
许可证
Business Source License 1.1:可以阅读、运行,并在内部用于生产环境 (包括商业用途)——但不能将其作为托管服务转售。 将于 2030-08-12 转为 Apache-2.0。
mcp-name: io.github.aurumflux20/seal
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。