FrankAsanteVanLaarhoven/BoundedAuth-AI

GitHub: FrankAsanteVanLaarhoven/BoundedAuth-AI

该项目为 AI agent 参与的资金流转提供了一种与交易绑定、单次使用且经过签名的受限授权凭证,确保非信任组件只能提议支付而无法授权支付。

Stars: 0 | Forks: 0

# BoundedAuth **资金流转的受限授权** —— 一种经过签名、与交易绑定且仅供单次使用的凭证,允许不受信任或非确定性的组件*提议*一笔支付,但无法让其*授权*支付。被入侵或遭遇提示词注入的 agent 所能造成的最坏后果,也仅仅是人类实际签名过的那笔支付。

CI Go 1.22+ Zero dependencies Race detector Cross-language vectors

``` _, err := boundedauth.Authorise(ctx, verifier, store, credential, boundedauth.Binding{ Payer: "wallet:alice", Payee: "wallet:bob", AmountMinor: 50_000, FeeMinor: 250, Currency: "GHS", Reference: transferID, }, func(ctx context.Context, granted boundedauth.Consumption) error { // Runs inside the host's transaction. The credential is spent and this // effect commit together, or neither happens. return ledger.Post(ctx, transferID, granted.ID) }) ``` **目录** · [问题](#the-problem) · [核心优势](#what-it-gives-you) · [架构](#architecture) · [安装](#install) · [一致性测试套件](#why-the-conformance-suite-is-the-point) · [可校验内容](#what-is-checkable) · [安全模型](#security-model) · [未声明的特性](#not-claimed) · [设计文档](#design-and-specification) ## 问题所在 token 只声明了调用者*是谁*。它并没有说明*他们同意了什么*。任何持有有效 token 的实体,都可以在其权限范围内,随心所欲地向任何接收方转移任意金额的资金。 当调用者是一个点击按钮的人类时,这是可以容忍的。但当调用者是一个根据其接收到的文本自动组合支付请求的自动化 agent 时,这就变得无法容忍了——因为问题不再是*该调用者是否已通过身份验证*,而是*人类是否同意了**这笔**支付*。 所有的 Agentic-commerce(智能体商业)努力都在围绕着同一个未解决的问题打转:如何让一个非确定性的执行者提议一笔支付,而不允许其进行授权?常见的答案——受作用域限制的 bearer token——依然会被任何持有签发密钥的人伪造,而且依然没有与特定的交易绑定。BoundedAuth 将签名与交易本身进行了绑定。 ## 核心优势 签名覆盖了确切的交易细节——付款方、收款方、金额、手续费、货币、备注以及可选的上下文信息。因此: | 属性 | 含义 | | --- | --- | | **不可重定向** | 为一笔支付获取的凭证不能用于另一笔支付——任何人都不行,包括请求该凭证的服务。 | | **原子化的单次使用** | 授权在其转移资金的同一笔交易中被精确消耗一次。消耗与生效要么同时提交,要么都不发生。 | | **设备绑定(推荐)** | 当认证者的挑战*即是*绑定摘要时,由设备对交易进行签名,因此即使是 compromised 的签发者,也无法为人类从未见过的支付获取签名。 | | **存证即同一链条** | 回执被绑定到相同的摘要并与其自身字段进行交叉校验,因此如果回执描述的支付与被授权的支付不一致,就会被检测到,而不会静默通过。 | 直白地说,其结果是:**无论 agent 出错、被提示词注入还是怀有敌意,其能造成的最坏后果仅仅是实际被签名过的那笔支付。** ## 架构 ``` flowchart LR subgraph Untrusted["Untrusted — may only propose"] AG["Agent / front-end /
partner integration"] end subgraph Issuer["Issuer — authenticates the human"] WA["WebAuthn / HSM"] MINT["Mint
signs the binding digest"] end subgraph Authority["Authority — where money moves"] VER["Verify
signature, binding,
lifetime, method
"] ST["Store.Consume
spend once + effect,
ONE transaction
"] RC["Receipt
bound to the same digest"] end AG -->|"typed proposal"| MINT WA -->|"challenge = binding digest"| MINT MINT -->|"credential"| AG AG -->|"credential + transaction"| VER VER --> ST ST --> RC VER -.->|"public key only"| Issuer ``` 有两个至关重要的模块边界: - **Verifier 是一个值,而不是全局状态。** 它持有一个基于每个签发者的公钥映射,因此信任第二个签发者永远不会扩大第一个签发者所能授权的范围。它在失败时会闭合:没有密钥,就没有授权。 - **单次使用是宿主的 `Store` 的属性,而不是本库的属性。** “只消耗一次,且与效果原子性地同时执行”是*你的*事务边界的属性——本库无法提供该属性,因此它提供了一个**用于测试你的实现的一致性测试套件**。 完整的组件与序列图:**[ARCHITECTURE.md](ARCHITECTURE.md)**。 规范的网络格式与规则:**[SPEC.md](SPEC.md)**。 ## 安装 ``` go get github.com/FrankAsanteVanLaarhoven/BoundedAuth-AI ``` ``` import boundedauth "github.com/FrankAsanteVanLaarhoven/BoundedAuth-AI" ``` PostgreSQL 参考存储是一个**独立的模块**,因此嵌入 verifier 并不会引入数据库驱动: ``` go get github.com/FrankAsanteVanLaarhoven/BoundedAuth-AI/postgres ``` 除 Go 标准库之外,核心代码**零依赖**。 ## 为什么一致性测试套件才是关键 这里的密码学代码只有几百行,要么正常工作,要么明显失败。而经常在实际交付中出现问题的要求是**原子性**——即消耗凭证与执行操作必须同时提交生效。 一个存在缺陷的实现能通过正常的测试和代码审查,因为代码读起来很正确:查找、校验、标记、执行。它在并发场景和部分失败的情况下会出问题——也就是说,它会在生产环境中的关键资金流转路径上失败。 因此,[`conformance`](conformance/) 会测试**你的** store,而不是本库: ``` func TestConformance(t *testing.T) { conformance.Run(t, conformance.Harness{ NewStore: func(t conformance.TB) boundedauth.Store { return myPostgresStore(t) }, Write: func(ctx context.Context, key string) error { /* inside the tx */ }, Committed: func(t conformance.TB, key string) bool { /* observed outside */ }, Consumed: func(t conformance.TB, id string) bool { /* observed outside */ }, }) } ``` 它会运行那些在安静的测试环境中永远不会触发的失败模式:同时展示同一个凭证、在凭证被名义上消耗后执行失败的操作,以及执行了两次的操作。如果你的 `Write` 无法在 `Consume` 开启的 transaction 内部运行,测试套件就会失败——这是正确的,因为无论你的 store 代码怎么写,它都无法提供这种保证。 **该测试套件本身也针对三个故意写坏的 store 进行了测试**——即“先检查后执行”、“先标记后执行”和“执行两次”——每一种都对应一个经典反模式,因此每一次校验都*被证明*能检测出特定问题。一个从未被证明能检测出任何问题的一致性测试套件,仅仅是一个声明,而不是一次真正的校验。 ## 可校验内容 以下每一项都是可以通过命令执行的,而不是空头支票。`go test ./... -race` 会运行所有测试。 | 声明 | 如何校验 | | --- | --- | | 规范足够完整,可直接据此实现 | `python3 testdata/verify_vectors.py` —— 另一个根据 `SPEC.md` 用其他语言编写的实现,复现了所有 **10** 个测试向量 | | 绑定覆盖了决定资金去向的每个字段 | `go test -run TestEveryBindingFieldChangesTheDigest` | | 凭证无法被重定向到另一笔支付 | `go test -run TestRepointingIsRefused` | | 重定向尝试不会消耗掉凭证 | `go test -run TestARepointedCredentialIsNotSpent` | | 终身上限对其自身的签发者也具有约束力 | `go test -run TestLifetimeCeilingIsEnforcedAtVerifyNotOnlyAtMint` | | `method` 是一个封闭集合;极其相似的错误项也无法通过测试关卡 | `go test -run TestUnknownMethodIsRefused` | | 显示错误支付信息的回执无法通过 `MatchesAuthority` 校验 | `go test -run TestReceiptWithMismatchedFieldsFailsMatchesAuthority` | | 内存存储满足原子性契约 | `go test ./memory/... -race` | | **PostgreSQL** store 在真实数据库中满足该契约 | `cd postgres && BOUNDEDAUTH_TEST_DATABASE_URL=... go test ./... -race` | | 一致性测试套件会使不满足条件的 store 失败 | `go test ./conformance/... -race` | **真实数据工作负载研究。** [`bench/`](bench/) 测试工具针对 PostgreSQL 重放了 IEEE-CIS 欺诈检测数据集(包含 590,540 笔真实交易)的完整流程:在单个主机上达到约 21,000 笔/秒的授权支付速度,中位数耗时约为 3 毫秒,拒绝操作的成本比接受操作低约 3 倍,在批量测试中每一次重放和重定向尝试都被成功拒绝。具体方法论及其有效性威胁分析详见已执行的[笔记本](notebooks/ieee-cis-workload-study.ipynb)。 ## 安全模型 **它能防御什么。** 一个能够组合支付请求的受感染或恶意组件——无论是 agent、前端、合作伙伴还是内部服务——都无法为人类未签名的支付获取授权,无法更改金额或接收方,也无法为第二笔支付重放授权。 **它不能防御什么。** 一个被攻陷的**签发者(issuer)**可以凭空签发任何操作的授权,因为签发者就是用来证明人类已同意的实体——将绑定摘要用作认证者的挑战可以降低这种风险,但无法消除它。一个被攻陷的**宿主**可以在没有凭证的情况下执行操作,这就是为什么校验环节必须设在资金转移的节点上,而不是在 API 边缘。密钥轮换在 v1 版本中不在支持范围内(在超过最长生命周期的重叠期内,verifier 会同时持有两个密钥)。 本库在发布前经过了**红队测试**:凭证部分的防护依然稳固(伪造、重定向和重放均被拒绝;在竞争检测器下验证了 PostgreSQL 的单次使用和原子性),而存证部分的发现以及一些声明属性的缺口已修复,并为每一项添加了回归测试。 ## 未声明的特性 坦白地说,因为一个省略了自身局限性的安全库,其价值要低于一个承认自身局限性的库。 - **没有第三方审计或渗透测试。** 它只经过了内部红队测试;测试用例由代码作者本人编写。 - **版本 1 不支持密钥轮换。** - **本库不负责对任何人进行身份验证。** 它只校验由你信任的 issuer 签发的凭证;将人类身份与密钥绑定是 issuer 的工作。 - **被攻陷的 issuer 可以为任何操作签发授权**(规范的 §3.3 降低了此风险,但并未消除)。 - **`memory` 只是一个参考实现,不是持久化存储。** - **没有生产环境的部署。** 它是从一个从未处理过真实资金的支付平台中提取出来的。 ## 设计与规范 | 文档 | 内容简介 | | --- | --- | | **[ARCHITECTURE.md](ARCHITECTURE.md)** | 组件、授权序列、信任边界、一致性模型、采用拓扑结构 | | **[SPEC.md](SPEC.md)** | 规范的网络格式、摘要构造、校验步骤、回执规则——足够精确,可直接据此重新实现 | | **[ADOPTION.md](ADOPTION.md)** | 如何将其接入已有资金流转系统:包含五项关键决策、集成步骤、迁移、运维,以及可能踩坑的方式 | ## 目录结构 | 路径 | 内容 | | --- | --- | | `authority.go` | 绑定摘要、`Issuer.Mint`、`Verifier.Verify` | | `store.go` | `Store` 契约与 `Authorise` | | `receipt.go` | 绑定到授权其生效的回执 | | `conformance/` | 校验宿主的 store;本身也针对故意写坏的 store 进行了测试 | | `memory/` | 参考 store —— 在 `-race` 下通过测试套件 | | `postgres/` | PostgreSQL 参考 store —— 独立模块,保持核心代码免受外部依赖干扰 | | `bench/` | 真实数据的工作负载基准测试 (IEEE-CIS) | | `testdata/` | 跨语言的测试向量与第二套实现代码 | ## 契约实现方 | 实现方 | 状态 | | --- | --- | | `memory` | 参考实现。在 `-race` 下通过测试套件。 | | `postgres` | 参考实现。在真实的 PostgreSQL 上通过 `-race` 测试。 | | EPHERA ledger | 通过相同的测试套件,验证了入账资金的确切执行语句。 | 最后一行值得仔细阅读。该契约是从那个 ledger 中提取出来的,这使得它成为了最容易被假定正确,也最不可能去针对启发它的测试套件进行测试的实现——因此,现在它必须接受与任何外部采用者相同的一致性测试套件的检验。 ## 许可证 尚未分配——默认保留所有权利。请联系作者了解相关条款。
标签:AI安全, Chat Copilot, Go语言, JSONLines, Streamlit, 代码分析, 凭证管理, 支付授权, 日志审计, 测试用例, 程序破解, 访问控制, 逆向工具, 零信任