@ cat- factory/ 守门员- 工人
这是什么
云花工机械 背后的猫因子 守门员: 证书持有口 结束 Cloudflare 操作系统 工作空间驱动器 没有代理商见过证书 特工人员具有以下能力: 方法恰恰是给予的政策; 钥匙停留在工人的秘密和持久对象中 存储.
它在同一个房间里有两个门, 哪个呼叫者通过决定它是什么 授权:
| 门 | 谁进来的 | 授权 |
|---|---|---|
这个 GatekeeperVendor 切入点 | Cloudflare OS 工作空间,超过 GATEKEEPER_* 服务绑定 | 保持约束 |
ALL /rpc (Cap'n Web通过HTTP) | 任何其他会说 Cap'n Web 的代理运行时间 | OS_SHARED_TOKEN |
已公布的Cloudflare OS合同将一个守门员交给当地工人RPC
WorkerEntrypoint 导出名称 GatekeeperVendor; Cap'n Web 是工作空间的浏览器到后端
和装配边协议, 它分享语义而不是线。 这么说吧 /rpc 门是
所有不是Cloudflare OS部署, 这里没有什么是Cloudflare -OS只.
这是守门员家庭的一半机器:
| 块 | 这是什么 | 你怎么样 |
|---|---|---|
@cat-factory/gatekeeper-bindings | 生成的操作表 此软件包会针对 | 以依赖身份进入 |
@cat-factory/gatekeeper-worker (本套装) | 容量表面, 密钥经纪人, 网络hook接收器, 批准信箱, 状态 DO | 安装, 只写一个策略 |
deploy/gatekeeper | 部署模板: 策略、 硬盘绑定、 三行接线 | 复制和编辑 src/policy.config.ts |
您安装此软件包并写入一个文件 。 所有部署都不同 政策; 其他一切,从能力向下浮出 至可持久对象 钥匙从这里进来 拆分就是目标 机器升级是一个版本起伏 而不是你编辑过的文件的合并, "你得到安全相关的修正"是 由版本编号回答 .
宗旨和目标
其目的是将猫因子放在一个组织自己的治理面板后面: 证书,所以每次运行 追溯到一个人, 每一级操作授权 这样一个代理可以达到 只有操作员的决定 现场伪装 平台的停放决定 浮出水面 批准信箱而不是一个投票循环.
这是一个 稳定公共表面的消费者曰:能骑也 /api/v1 和外出网点
通过交货合同 @cat-factory/sdk 财务报告和审定财务报表
没有别的了。 一个从未听说过的猫因子部署是字节
不变.
怎样用
起点是模板
deploy/gatekeeper页:1
它,指向您的工作空间,并编辑它 src/policy.config.ts一个部署的全体工人
为:
import { createGatekeeperWorker } from '@cat-factory/gatekeeper-worker'
import { POLICY } from './policy.config'
// wrangler resolves `class_name` against the Worker's OWN exports, so the Durable Object class has
// to be named here even though it is implemented in this package.
export { GatekeeperState } from '@cat-factory/gatekeeper-worker'
export default createGatekeeperWorker({ policy: POLICY })
// policy.config.ts: the `/policy` entry point carries the vocabulary without the Worker runtime,
// so this file and its tests load anywhere.
import { DECISION_BINDINGS, type GatekeeperPolicy } from '@cat-factory/gatekeeper-worker/policy'
export const POLICY: GatekeeperPolicy = {
defaultTier: null, // no implicit access: an ungranted actor gets `unknown_actor`, not a capability
tiers: {
observer: { description: 'Read the board and runs.', keyScope: 'read', allow: '*' },
approver: {
description: 'Answer a run’s parked decisions.',
keyScope: 'decide',
// Derived from the answerer table, never transcribed: a run parks on thirteen different
// things and the surface carries more than forty operations for answering them.
allow: ['tasks_get_run', ...DECISION_BINDINGS],
mask: ['run.pullRequestUrl'],
},
},
grants: { '[email protected]': 'approver' },
}
@cloudflare/workers-types 是一个 所需经费 对应的,不是可选的。 此软件包的每个类型
出版物以 " 工人全球 " 的形式列出(ExportedHandler, (中文(简体) ), DurableObjectNamespace, (中文(简体) ),
Request)和持久对象基类来自 cloudflare:workers,所以消费者没有
这些类型无法编译上述三行,更不用说其他任何行了。 这是同龄人而不是
一个依赖性,因为全局是环境的: 在一个树上复制两本, 互相重复, 所以
版本必须是消费者的.
它会做什么
- 对象能力约束. 代理人持有的物体,其操作政策是方法ODS 答应了 每通电话都没有查询许可名单,因为没有可查询的:a 操作该级不携带不是拒绝的方法,它不存在.
- Cloudflare OS对象模型,作为一个外观覆盖了全部.
GatekeeperVendor→CatFactoryAccount→CatFactoryResource* 届会,与describe(), (中文(简体) ),getSupportedResources()财务报告和审定财务报表getTypeScriptTypes()操作表的所有项目 而不是记录下来 一个资源是配对的猫因子工作空间,由一个 URLPatter 超越部署来源: 一个守门员服务于一个工作空间, 因为 提供它持有的钥匙的范围是一. - 工作空间的批准队列,在每个呼叫前. 每个读取的入口路径是 提交和完成每封信 工作空间应用它。 为抓取的代理文本服务的读取器是标记不可共享的,动作 背负表格所述的后果,不提供未处理的自动核准,同时 表面的注释没有写作安全。 下方的分层政策是留在地上.
- 人均演员证书. 每一个呼叫者都有自己的猫因子钥匙,用薄荷
POST /api/v1/keys在等级范围 并印有你的身份 这个人 (单位:千美元)externalIdentity)),所以运行追溯到人和角色范围合并政策仍然真实. 薄荷在401号机运行和重取薄荷之前就被索赔了 所以首先同时拨打薄荷 一次和旋转提供钥匙 治愈而不是楔形. - 批准作为收件箱,每个公园. 平台的外出网络hook提供
已停放的决定牌; 工人在原始字节上验证 HMAC , 取消
deliveryId, (中文(简体) ), 然后举出一张牌 跑步可以停止在13个不同的事物上 每一个都有按键的答案 sDK的亲善联盟,所以一个公园 平台添加失败 这个包的建设而不是 报告stale永远 回答重读 运行的现场决定和帖子通过 打电话者自己的钥匙. - 运行生命周期没有投票.
run.started编号 :run.completed编号 :run.failed作为土地runs_watched()投影,然后一个终端事件结算运行的开卡. - 钩子,所以工作空间被推而不是被问. 会话通过
工作空间本身
bindHook,工作空间在它准备好时允许它,每张卡或运行 然后推动过渡:每次发送一次新的回调,按观察情况授权. 什么钩子推 就是什么approvals_list()财务报告和审定财务报表runs_watched()回答, 哪个是 真相:一个没有找到的钩子仍然可以读到hooks_bound()报告误差 而不是把它从一个安静的收件箱中推断出来。 粉丝出局了 承认和每次推力都以自己的最后期限为界限,所以挂起的工作空间成本 a 并且永远不要重试平台的预算. - 共享已经核实,没有假设. 共享到约束资源的工作空间用户是 只有在OWN账户的分层达到资源分层达到的方方面面时才被接纳,以及 不再有口罩;一个能够读取捕获的代理文本的分级是永远无法共享的. 观察员 必须持有账户 此部署在解决任何级别之前已计值、 检查 : 未知 id 否则,将解决自动规定的层级,即这里每个账户的层级, 所以从另一个卖家看 完全被测量为与所有者相同。 任何东西 守门人不能回答(一个没有核查人的观察者,它从未铸造过的账户)就是拒绝 说它是什么.
- 对比每个行动申报的内容. 未读的参数 被扔在路上, 所以一个过滤器 没有人应用回来 作为一个答案形状像一个 过滤了一个。 现在,这是拒绝 命名什么操作得到的, 之前的钥匙是 铸造或批准使用.
- 自入并出所出所入. 端点在呼叫者选择的网页上注册
id,hour and idepotly. 时间,时间和能力.
POST /admin/retire?actorId=…取消每张密钥计价符 人,上游先在这里.
有一件事要告诉谁写 代理在另一边: 仅以标题归档的任务
公园立即在任何探员逃跑之前 cat-factory 将任务在之前的作者字段减小
第一次发送, 一个缺失的描述是一个阻断 发现,所以 tasks_create + 键
tasks_start 光着地契,就停止运行 input-gate 决定而不是一项
这是工作。 公园像其他公园一样负责 但更便宜的修补是存档
工作,说它想要什么.
要配置什么
所有操作都来自工人的环境 通过两种机制
可互换: vars 和 持久对象绑定在模板中
wrangler.toml,三个证书是秘密,与 wrangler secret put 输入
平台的秘密商店。 配置文件中的证书是寄存器中的证书,所以
拒绝指定其约束性机制的名称,而不是提供两者.
| 装订 | 仁爱 | 这是什么 |
|---|---|---|
CAT_FACTORY_BASE_URL | var. (中文(简体) ) | 这个守门员是配对的. |
PUBLIC_URL | var. (中文(简体) ) | 这名工人本人的公共出身;分娩到达 <PUBLIC_URL>/webhook。 。 。 . |
WEBHOOK_ID | var. (中文(简体) ) | (原始内容存档于2017-10-21). Out-bound-webhook id to admit understand. 来电选择;保持稳定. |
PROVISIONING_KEY | 隐藏 | 一个 admin cat-factory API 键. Mints / aactor 密钥; 没有其他的 . |
WEBHOOK_SECRET | 隐藏 | 16-200个字符。 注册了终点 并核实了每次交货. |
OS_SHARED_TOKEN | 隐藏 | 搭配的OS部署员在每次RPC呼叫中都会呈现. |
STATE | 持久对象 | 指定名称空间 GatekeeperState:卡,去dupe日志,薄荷键. |
缺失的绑定被解答为 503 命名方式和设置方式, 从未默认: 没有
安全地站立 证明或身份 与它谈判的部署. GET /health
立即询问整个表格,而不是给定请求路径的绑定
用于直播的部署和用于交通的未接通的部署读取其内容.
工人服务五道:
| 路线 | 认证 | 这是什么 |
|---|---|---|
POST /webhook | 交付 HMAC | 平台外出交货. 已验证过原始字节 . |
ALL /rpc | OS_SHARED_TOKEN | Cap'n Web,用于代理运行时间,而不是Cloudflare OS. |
POST /admin/enroll | OS_SHARED_TOKEN | 重新刷新网签. 还有小时运行克龙. |
POST /admin/retire?actorId=… | OS_SHARED_TOKEN | 下机:为一个OS用户取消每个密钥计价. |
GET /health | 无 | 设定每个约束时绿色, 并汇编政策 . |
/rpc 因为有一条路线的工人,凡找到这条路线的,都是可以到达的,
能力表面 唯一防御是模糊的不是一面 Cloudflare OS 路径没有
通过这里,它到达 服务捆绑, 它从来没有穿过互联网和
只有部署的操作员才能写, 所以持有它就是授权和第二
在它面前的秘密不会保护任何东西.
/health 还报告 Cloudflare OS 是否可以安装此功能
有两件事决定了, 也没有自己的请求路径: 输入模块必须导出
对象模型所解决的四个名称( q)GatekeeperVendor, (中文(简体) ), CatFactoryAccount, (中文(简体) ),
CatFactoryResource, (中文(简体) ), CatFactoryVerifier)),政策必须命名为 autoProvisionedTierA级
查找缺失任一工作空间不会产生任何显示器的错误; 它永远不会完成
安装。 绿色的回答就包含在 ok数字 :
{ "ok": true, "os": { "discoverable": true, "blockers": [], "limitations": [] } }
limitations 用于不停止安装的同一报告. CatFactoryHookController 实值
仅当会话绑起钩子时才到达, 所以一个部署缺失它安装、 服务和回答
和以前一样拒绝 approvals_subscribe(); 称阻断器会变成工作
部署为红色,省略后,就会从代理失败的呼叫中发现空隙.
它被报告,从来没有折入状态, 因为守门员服务 /rpc 没有别的了
是一个支持的部署:这个一揽子计划承诺,向不是Cloudflare的消费者敞开大门
OS,然后把他们的活生生的红色 在一个版本的凸起 将是这个路线 回答一个问题
没人问过 需要发现密钥的部署 显示器 os.discoverable; 每个条目
内 blockers 携带一个 reason (单位:千美元)missing_exports, (中文(简体) ), no_auto_provisioned_tier)和a 数据 detail
标出固定线,两条线都用一条通道报到 所以半线部署没有线
一次调出.
如何定制:政策
政策是部署所写的,是争论
(单位:千美元)createGatekeeperWorker({ policy })),这个软件包从不读取文件。 A 类 GatekeeperPolicy 已经
三个字段:
defaultTier:没有获得明确赠款的行为者的级别,或null拒绝未知 行为者(unknown_actor) (中文(简体) ).null是已发运的默认值, 安全值是: 添加一个人是 然后刻意地编辑.tiers: 名称TierPolicy条目,每个条目都包含:description: 传播操作系统显示在平面旁.keyScope: 为这一级设计的每名演员密钥的范围(read编号 :write编号 :decide) (中文(简体) ). 这也是补助金的上限;admin被直接拒绝,因为POST /api/v1/keys不能薄荷 它要求的层次 是门卫的 自己的供养秘密.allow: 授予具有约束力的名称,或'*'内在的一切keyScope。 。 。 .deny: 绑定名称从allow。最后应用,所以一个否认总是获胜 模板用于将调试表面(模型提示、捕获输出)远离一个'*'读取等级.mask: 点行道在到达呼叫者之前从每个结果被修改(见下文).
grants:OS的演员身份(无论OS认证和传递给什么)connect()至分级 名称.
一项政策是根据现场调查操作表汇编的,并且只有来自
bindingsWithinScope(tier.keyScope),所以一个层次不能授予 超过关键支持
退休或拼写错误的业务是拒绝服务(PolicyError而不是一种方法
每通电话403次 两项规则值得你继续改变
- 按姓名开列的赠款
read。 。 。 .'*'对只读的层次是诚实的,对上面有危险的:a * 将作战舰艇加到每艘'*'升级时无人决定. - 保留
keyScope尽可能低的补助金. 这是每个演员的密钥范围, 这是演员证书的爆炸半径.
面具替换,永不删除. 被遮住的叶子变成导出 MASKED 发送器
(单位:千美元)[masked by gatekeeper policy]而不是消失,因为一个去掉的钥匙和一个钥匙
平台没有与消费代理人相同的读取值,它们是不同的事实.
路径是点和向外的数组元素(steps.status 口罩每步状态); a
不匹配的路径不是一个错误,因为结果形状会因操作而合法地变化.
打电话的人会怎么想
connect({ actorId, label? }) 编辑 /rpc 对话框
能力. actorId 这是操作员自己的身份 这是唯一的
要求守门人信任:任何呼叫者都不要选择一层。 除了授权的操作
每个能力都带有十种保留的方法:
tier(): 呼叫者扮演的角色(演员,级别名称,描述,关键范围).bindings(): 所授予的操作,每个操作都有其范围底,后果(谨慎的默认) 被应用)和论证形状,因此OS可以运行自己的批准治理每个呼叫.withheld(): 每一个装订的部署都服务于这种能力不携带 理由,你觉得呢? 四个原因故意分开:not_in_policy财务报告和审定财务报表denied_by_policy为: 政策作者的问题,above_key_scope是一个不同的地方, 或接受上限),以及not_relayable既不是: SSE 流或 二进制 blob 无法 穿过Cap'n的网络呼叫,所以修复是问另一个方式(Poll)tasks_get_run代替 事件流).approvals_list(), (中文(简体) ),approvals_inspect(cardId), (中文(简体) ),approvals_answer(cardId, input)页:1 批准收件箱;关于流量和三个答案结果,请参见模板README.runs_watched(): 运行寿命周期预测run.*网络事件.approvals_subscribe(callback), (中文(简体) ),runs_subscribe(callback):绑住钩子,所以两个预测 以上为被否决。 回调需要一种方法(onApprovalCard(card)编号 :onRunEvent(state), (中文(简体) ), 并且每一次过渡都会有一张卡片 包括一个终端运行事件. 都拒绝/rpc门,它不会带来批准队列 注册钩和 不得授权对货物交付;拒绝时,双方的回答相同 问. 不使用绑定的工作空间( 它的队列没有钩子, 或一个人) 已拒绝)为 ahook_bind_refused因为那两个需要反之 修补和在这种缝隙里 没有任何东西能让他们分辨出来.hooks_bound(): 此账户所启用的, 用每个钩子所驱动的 (单位:千美元)deliveries),它不能被推动的missed),工作空间所拒绝的(failures(中文(简体) ) 以及它是否还在live。当永久对象在 发送,因为工作空间的回调源是一个活字根,不能被存储;读作live: false不断上升missed,而补救办法是再次约束。 从同一处重新装订 配置相同的登记簿,而不是添加第二个: 因为它是历史的源头 重新武装.
门卫的拒绝是 GatekeeperError携带可读机器 reason
(单位:千美元)unknown_actor, (中文(简体) ), card_not_found, (中文(简体) ), ambiguous_park,","平台自己扮演的角色")
details.reason 播放:一个 OS Gadget 映射它来复制和补救. 运算符错误是
PolicyErrors在编译时间, 任何能力存在之前, 所以一个配置错误的门卫
而不是服务于失败的方法.
监护,以及它不承诺的
提供钥匙是工人的秘密,从来不离开平台的秘密商店. 每个演员 它的密钥生活在持久对象的存储中: 在每个代理的能及范围之外, 但休息在 你的账户。 如果无法接受,则每一次调用并随后取消薄荷,成本为按键行 每次行动.
这可强制执行的是,行为者可以从事哪些业务,其信誉如何。 那又怎样 由cat-factory自己的合并政策和批准管理.
升级
升级此软件包 . @cat-factory/gatekeeper-bindings 成为它的依附者
准确的版本,所以撞出这个软件包 就是操作表的移动方式,没有什么
保持一步一步的手。 不添加直接依赖于约束来保留它们“ 在一起” : a
精确的平针加第二个范围 安装表格的第二个副本, 而策略仍在编译
对抗这里解决的那个人 政策名称从
@cat-factory/gatekeeper-worker/policy因此,部署从来不需要依赖.
版本skew被报告而不是被吸收. 一个给操作命名比
安装的表格以 a 失败 PolicyError 叫你升级,梯子帮手就投球
所以在你包之前的部署读作skew 而不是a
键,没有权限.
测试
这套套房是真实的 workerd 下级 @cloudflare/vitest-plugin,反对工人
由这个软件包自己的厂房建造,有真正的持久对象、真正的WebCrypto和真正的Cap'n
网络客户端,与一个被脚本化了的猫因子源进行交谈,绑定为池外服务. 这个
证明 - 保管的故事是"关键是工人的秘密" 所以一个节点嘲笑一个工人会证明
没什么.
pnpm --filter @cat-factory/gatekeeper-worker test:run
test/live/ 和被拿走的剧本来源是同一个人 一个固定同意这一点
通过构造包,所以请求形状绑定和SDK都认为正确只能
对真实的部署错误:真实的 webhook 收藏中包含的活的光谱, 薄荷一个真实的
每名演员按键(并从其被撤销中恢复),转发日常循环,并回答一个运行
真的停了下来,没有卡 平台自己的通知提高。 他们由
@cat-factory/sdk-smoketest,是哪个拥有他们需要的部署,所以这个软件包没有
Postgres- 形状的依赖性 :
DATABASE_URL=... pnpm --filter @cat-factory/sdk-smoketest run smoketest -- --only=gatekeeper
特意不涵盖的是TRAVELLED的快递:平台拒绝注册 一个回转端点,所以接收器用信封驱动 平台本身的通知对象.
test/os-live/ 是第三条腿,它带走了假的另外两股:工作空间.
Cloudflare OS 的自带设备 @gadgets/integration-tests 工具箱靴子真实 workshop-backend 旁边
这个工人在wrangler的测试下, 所以一个真正的工作空间 发现卖家从服务
绑定、 薄荷账户、 绑定配对部署为资源并共享。 夜晚被钉住
对伙伴的承诺 GATEKEEPER_OS_REF,并通过生活在自己的工作流程中而不受阻碍
(单位:千美元).github/workflows/gatekeeper-os.yml) (中文(简体) ). 要自己运行,克隆伙伴仓库 内部
这个 从寄存器根点出套件:
git clone https://github.com/cloudflare/cloudflare-os.git .cloudflare-os
# The commit the nightly pins is GATEKEEPER_OS_REF in .github/workflows/gatekeeper-os.yml.
# Running against a different one is fine; it is then your run that is unpinned, not the lane's.
git -C .cloudflare-os checkout <that commit>
(cd .cloudflare-os && pnpm install --frozen-lockfile --ignore-scripts \
&& pnpm --filter @gadgets/workshop-backend run build:format-blueprints)
GATEKEEPER_OS_DIR="$PWD/.cloudflare-os" pnpm --filter @cat-factory/gatekeeper-worker test:os
克隆人进入了这个仓库 因为wrangler的测试拉带 靴子伙伴的工人和
这个在一根下,而根 套房的手就是这个寄存器: 旁边的检查
它不能被启动, 配置拒绝一个 而不是让绳子报告一个工人它
无法找到 . .cloudflare-os 被赋予了这一点.
它对于三个接合点存在,这里没有其他结构上的套房:入口点 NAMES(即:
工作空间可以解决它们, 并且从不问它们叫什么包, 交接的根
(单位:千美元)createAccount() 返回工作空间所坚持的部分,以及 getGatekeeperClassFor() 类
只有工作空间本身的机器可以即时处理),转录协议在
src/os/protocol.ts无法从落后的形状中分辨出来 内容
第一次运行找到一个真实的:没有 allow_irrevocable_stub_storage 兼容旗帜, a
工作空间无法存储账户根, 因此任何连接的账户都失败 。 它没有做什么
到达是会话: 控制器没有设备代码, 所以 startSession 从未被调用和
批准队列,辩证和回答者都留在隐形套房里. 两条腿 二条
问.
参考资料
deploy/gatekeeper页:1 您复制的模板、其配置走过和操作系统侧用例.- ADR 0052 (英语)数字 : 设计记录,每半页背后的决定, 以及每个套房故意不涵盖的内容.
backend/docs/public-api.md数字 : aPI 此座标( 键, 瞄准镜, 网点, 端点语义) .@cat-factory/gatekeeper-bindings数字 : 根据生成的操作表策略汇编.