- 后端
- 应用安全
- 云原生
【免费下载链接】keto
The most scalable and customizable permission server on the market. Fix your slow or broken permission system with Google's proven "Zanzibar" approach. Supports ACL, RBAC, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
导读
本文基于仓库根目录下的 UPGRADE.md 编写,梳理 ORY Keto 从早期 0.x 沙盒版本(0.0.1 → 0.4.0-sandbox)演进过程中的全部破坏性变更,涵盖 SDK 管道重构、配置管理方式升级、REST API 端点重命名与语义调整、引擎级架构重构(ORY Ladon → Open Policy Agent/Rego)以及 SQL 存储层迁移等关键主题。读完本文,你将掌握 ORY Keto 历史上每次大版本升级的影响范围、端点到新位置的对应关系、Warden 概念的废弃替代方案,以及升级前必须执行的检查与备份流程,并能在当前仓库的源码与配置文件中找到这些变更落地后的实现证据。
升级文档的定位:先看 CHANGELOG,再动手迁移
UPGRADE.md开篇即明确了自身定位:它的目标是让破坏性变更(breaking changes)的迁移尽可能简单,但同时也坦承"并非所有破坏性变更都会被收录"。因此在最终确定升级流程之前,官方要求先核对 CHANGELOG.md 获取完整的变更清单。
这形成了 ORY Keto 的标准升级三步:
- 阅读
UPGRADE.md,了解已知的破坏性变更与对应迁移方案; - 通读
CHANGELOG.md中目标版本区间内的所有条目,补充UPGRADE.md未覆盖的变更; - 备份数据库后执行迁移命令(当前版本为
keto migrate up,见下文"SQL 迁移机制"一节)。
当前仓库根目录下UPGRADE.md与CHANGELOG.md并列存放,CHANGELOG.md已记录至 0.14.0 及更后续的版本,说明UPGRADE.md收录的历史版本段只是整个演进过程的一部分——这正印证了文档开头"not all breaking changes might be included here"(并非所有破坏性变更都收录于此)的提醒。
0.4.0-sandbox:SDK 管道重构与客户端迁移
0.4.0-sandbox 版本的核心工作是对SDK 生成管道(SDK pipeline)进行重构。升级者最需要关注的点有两类:SDK 来源变更与 SDK 自身的破坏性变更。
SDK 来源:仓库内 SDK 被彻底移除
该版本为所有主流编程语言发布了官方 SDK,并同步发布到各自语言的包仓库:
- Python:
ory-keto-client - PHP:
ory/keto-client - Go:
ory-keto-client-go - Node.js(含 TypeScript):
@oryd/keto-client - Java:
sh.ory.keto:keto-client - Ruby:
ory-keto-client
与之对应,托管在本仓库./sdk/...目录下的 SDK 被完全移除。文档明确要求:从该版本起只能使用上述官方来源的 SDK,这同时也消除了旧 SDK 管道引发的若干问题。
从当前仓库的实际结构看,SDK 相关代码已分散为两处,与文档所述的历史形态完全不同:
- Go 客户端:集中在 internal/httpclient/(含
api_metadata.go、api_permission.go、api_relationship.go、client.go、configuration.go及各model_*.go数据模型),对应 internal/httpclient/api/openapi.yaml 描述的全部 REST API; - 生成的类型代码:gen/go/ory/keto/ 与 gen/es/ory/keto/ 分别存放 Go 与 TypeScript 生成物,后者即文档所述 Node.js/TypeScript SDK 能力的落地形态。
SDK 自身的破坏性变更
新 SDK 管道引入了一些不可避免的破坏性变更:
- Go SDK:若干结构体(struct)与字段被重命名。文档估算迁移成本为:重度使用 SDK 的集成约半小时,仅使用一两个方法的集成只需几分钟——因为除重命名外没有其他变化。
- 其他语言 SDK:统一切换为
openapi-generator生成器,该生成器维护更活跃、产出的代码质量更高,最直观的体现是 Node.js SDK 获得了 TypeScript 类型定义。文档坦承这部分没有现成的自动迁移路径,需要人工适配。
升级建议:先对照官方 SDK 文档找出被重命名的类型与字段,用编译错误定位全部受影响调用点,再逐一替换;对于非 Go 语言,由于生成器更换导致代码形态差异较大,建议按新 SDK 的 API 签名重新编写客户端接入层。
0.3.0-sandbox:配置管理与端点语义变更
配置管理:配置文件成为一等公民
0.3.0-sandbox 更新了配置管理体系,首次允许通过配置文件进行配置,同时环境变量仍然可用但经历了一轮更新。旧的环境变量名继续生效,但会产生警告("old env vars still work but will yield a warning")。
这一历史方向在当前仓库中被完整继承并大幅深化:配置系统基于ory/x/configx构建,支持配置文件与环境变量两种来源。以仓库自带的示例 config/keto.yml 为例,可以看到当前版本配置的完整形态:
version: v0.8.0-alpha.2 log: level: debug namespaces: - id: 0 name: videos serve: read: host: 0.0.0.0 port: 4466 write: host: 0.0.0.0 port: 4467 dsn: memory其中的关键配置项包括:namespaces(命名空间定义)、serve.read/serve.write(读写 API 监听地址与端口,对应文档所述 read/write 两类接口)、dsn(数据源,memory表示内存模式)。完整的配置结构约束定义在 embedx/config.schema.json,它同时被 cmd/namespace/validate.go 以 JSON Schema 方式加载,用于校验命名空间与配置文件。CLI 侧,根命令 cmd/root.go 通过configx.RegisterConfigFlag注册--config标志,默认读取用户主目录下的keto.yml。
从源码结构看,配置读取的核心实现位于 internal/driver/config/provider.go,例如CORS(iface string)方法即从配置键serve.<iface>读取 CORS 选项(详见 0.0.1 一节)。
allowed 端点:拒绝语义从 200 改为 403
/engines/acp/ory/{flavor}/allowed端点在 0.3.0-sandbox 中调整了返回语义:当请求被拒绝时返回 HTTP 403 错误。这是鉴权类 API 常见的一次语义修正——将"请求被拒绝"显式表达为错误状态,而不是让客户端仅凭业务字段自行判断。升级时若已有客户端依赖旧的状态码判断逻辑,需要同步调整错误处理分支。
Go SDK 生成器:swagger-codegen → go-swagger
Go SDK 的生成工具从swagger-codegen迁移到go-swagger。文档对已有集成给出务实建议:如有迁移需求请开 issue 寻求官方协助。结合后续 0.4.0-sandbox 的 SDK 整体重构来看,这次生成器更换只是中间态,最终形态以当前仓库 internal/httpclient/ 与 gen/go/ory/keto/ 的代码为准。
0.2.0-sandbox:架构级重构——最大的一次破坏性变更
0.2.0-sandbox 对 ORY Keto 做了完全重写,文档列出了三大设计目标:
- 允许轻松扩展现有访问控制机制;
- 提升稳定性与响应性;
- 支持不止一种访问控制机制,规划中的机制包括 RBAC、ACL、AWS IAM Policies 等。
从当前仓库的描述("Supports ACL, RBAC, and more",基于 Google Zanzibar 模型)看,这一重构方向最终演化为现代 Zanzibar 风格的权限服务。下文按文档的"概念变更 → API 变更 → 迁移"结构展开。
概念变更
已弃用(Deprecated)
- Authorizers(授权器):整体弃用;
- 之前的存储机制:整体弃用。
已变更(Changes)
- 鉴权引擎切换:不再使用 ORY Ladon 作为引擎,改为依赖Open Policy Agent(OPA)。ORY Ladon Access Policy 的概念仍然完全照旧工作,但内部逻辑用Rego重写。
- Warden 概念:被弃用并替换(详情见下文"Reworked Endpoints")。
- CLI 命令:除
serve、version、migrate sql外全部变更。 - API:整体变更(见下一小节)。
- 环境变量:变更或被移除。
已新增(Additions)
- ORY (Ladon) Access Control Policies 新增
exact字符串匹配策略; - ORY (Ladon) Access Control Policies 新增
glob字符串匹配策略。
保持不变(Untouched)
- ORY (Ladon) Access Control Policies 的
regex字符串匹配策略保持原样——这正是 ORY Ladon 与旧版 ORY Keto 一直实现的逻辑。
exact/glob/regex三种匹配策略正是上文/engines/acp/ory/<matching-strategy>/...路径中<matching-strategy>占位符的可选值,0.3.0-sandbox 的 403 语义修正也作用在这条端点族上。
CLI 命令演化的当前形态
文档记载 0.2.0-sandbox 后 CLI 仅保留serve、version、migrate sql三大命令。对照当前仓库 cmd/root.go 的注册逻辑,CLI 树已经演化为:
keto relation-tuple:读写关系元组(cmd/relationtuple/root.go 注册了create、delete、delete-all、get、parse);keto namespace:读取与操作命名空间(cmd/namespace/root.go);keto migrate:数据库迁移(cmd/migrate/root.go 注册up、down、status);keto serve:启动服务(cmd/server/serve.go);keto check/keto expand:权限检查与关系展开;keto status:获取上游实例状态(cmd/status/root.go);keto version:由cmdx.Version提供。
serve与version的延续性、migrate sql演进为migrate子命令族,都印证了文档"命令变更"的记载方向。
API 变更
重命名的端点(Renamed Endpoints)
策略端点整体从根路径移入带匹配策略的路径前缀/engines/acp/ory/<matching-strategy>/:
| 旧端点 | 新端点 |
|---|---|
GET,PUT,POST,DELETE /policies[/<id>] | GET,PUT,POST,DELETE /engines/acp/ory/<matching-strategy>/policies[/<id>] |
GET,PUT,POST,DELETE /roles[/<id>] | GET,PUT,POST,DELETE /engines/acp/ory/<matching-strategy>/roles[/<id>] |
POST,GET /roles/<id>/members | POST,GET /engines/acp/ory/<matching-strategy>/roles/<id>/members |
三条重命名伴随三个方法级合并(upsert 语义):
POST /policies被弃用,与PUT /policies/<id>合并为PUT /engines/acp/ory/<matching-strategy>/policies:以 JSON payload 中的id字段标识策略,执行插入或更新(upsert);POST /roles被弃用,与PUT /roles/<id>合并为PUT /engines/acp/ory/<matching-strategy>/roles,同样按idupsert;POST /roles在成员场景下被迁移为PUT /engines/acp/ory/<matching-strategy>/policies/<id>/members,按 URL 路径中的id字段 upsert 角色成员。
文档特别强调:上述重命名的请求与响应 payload 均未改变,概念也未改变——升级时只需改 URL,无需改数据结构。
重构的端点(Reworked Endpoints):Warden 废弃
Warden 概念被弃用,根本原因是:旧设计允许在请求中随附凭据进行"先认证后授权",这与 ORY Keto 专注的**权限判定(permissioning)**边界相冲突。被废弃的 Warden API 包括:
POST /warden/oauth2/access-tokens/authorize:对token字段做 OAuth 2.0 Token Introspection,取回sub值作为 ORY (Ladon) Access Control Policies 的输入;POST /warden/oauth2/clients/authorize:用 OAuth 2.0 Client Credentials 授权校验 HTTP Basic Authorization 头,取username值作为策略输入。
这两个端点废弃且无替代。另一端点/warden/subjects/authorize使用如下 JSON 语法:
{ "subject": "peter", "action": "delete", "resource": "something:valuable" }该端点以完全相同的格式迁移至/engines/acp/ory/<matching-strategy>/allowed。也就是说:认证职责被剥离出去后,剩余的核心能力"给定 subject、action、resource 判断是否允许"由 allowed 端点完整承接。
新增的端点(New Endpoints)
GET /version:返回运行中的软件版本;GET /health/ready:服务可接受连接并处理数据时返回{"status": "ok"}与 HTTP 200;GET /health/alive:服务可接受连接时返回{"status": "ok"}与 HTTP 200。
这三个端点在新架构中至今仍是核心运维接口,当前仓库有完整实现证据:
- 路径常量定义在 oryx/healthx/handler.go:
AliveCheckPath = "/health/alive"、ReadyCheckPath = "/health/ready"、VersionPath = "/version"; - API 契约定义在 internal/httpclient/api/openapi.yaml:其中
/health/alive仅检查进程是否接受 HTTP 请求(不检查数据库连接),/health/ready额外要求环境依赖(如数据库)响应正常;两者都注明"多节点部署时健康状态只反映单实例,不反映集群状态"; - 生成后的 Go 客户端实现位于 internal/httpclient/api_metadata.go(
IsAlive请求路径为/health/alive,IsReady请求路径为/health/ready)。
迁移:SQL schema 完全变更
0.2.0-sandbox 的 SQL schema彻底改变,文档明确警告:仅靠keto migrate sql无法从旧版本迁移到新版本。受影响的用户需要联系官方(社区论坛或 GitHub issue)寻求迁移协助。
对照当前仓库,SQL 迁移机制已高度工程化,迁移文件按数据库方言拆分存放于 internal/persistence/sql/migrations/sql/(含*.up.sql/*.down.sql,按postgres、mysql、cockroach、sqlite3方言分别维护),并由ory/x/popx迁移框驱动。当前 CLI 迁移命令族定义在 cmd/migrate/:
keto migrate up(up.go):对全新 SQL 安装以及从 v0.7.x 及以后版本升级时执行;建议在靠近 SQL 实例的位置(如同子网)运行以降低失败风险与耗时;执行前会打印当前迁移状态并要求确认(可用-y/--yes跳过交互),且反复警告:在已有数据库上执行前必须创建备份;keto migrate down <steps>(down.go):按步数回滚,传0表示完全回滚;执行前同样要求确认,因为"这会删除数据";keto migrate status(status.go):查看当前迁移状态,支持--block阻塞等待全部迁移完成。
从迁移命令的确认交互与备份警告可以看出,UPGRADE.md中"升级前先查 CHANGELOG、注意破坏性变更"的建议已经内化到 CLI 本身——up.go在应用迁移前会提示用户核对CHANGELOG.md。
0.0.1:CORS 默认禁用
0.0.1 版本引入了新的环境变量CORS_ENABLED,用于控制是否启用 CORS:设为"true"启用,"false"禁用,默认禁用。这是浏览器端跨域调用的重要行为变化——升级后若发现浏览器客户端请求被拦截,优先检查该开关。
在当前仓库中,这一历史决策演化为结构化的配置项。配置模式 embedx/config.schema.json 中定义了cors配置块(含enabled、可暴露的响应头、调试开关等字段),读取实现位于 internal/driver/config/provider.go 的CORS(iface string)方法:该方法按接口(read、write、metrics)从serve.<iface>配置键读取 CORS 选项,默认允许GET, POST, PUT, PATCH, DELETE方法、放行Authorization与Content-Type请求头、暴露Content-Type响应头,并允许携带凭据。服务端在 internal/driver/daemon.go 中依据该配置决定是否为 read/write/metrics 接口挂载 CORS 中间件。
从"单个环境变量"到"每接口结构化配置",CORS 控制的演进脉络清晰可循,且"默认不启用"的原则从 0.0.1 一直保持到今天。
升级前检查清单:把历史教训落到实践
综合UPGRADE.md各版本的迁移建议与当前仓库的机制,一份务实的 ORY Keto 升级检查清单如下:
- 核对变更清单:通读 CHANGELOG.md 目标版本区间全部条目,不能只依赖
UPGRADE.md(文档明示其未收录所有破坏性变更); - 评估端点依赖:若仍在使用旧版
/policies、/roles、/warden/...路径,按上文对照表迁移到/engines/acp/ory/<matching-strategy>/...新路径;注意 allowed 端点 403 语义、Warden 两个 OAuth 端点无替代; - 升级 SDK:放弃仓库内 SDK,改用官方包仓库发布的各语言客户端;Go 用户重点处理结构体/字段重命名;
- 核对配置与环境变量:旧环境变量名若触发警告,迁移到新名称或配置文件(参考 config/keto.yml 与 embedx/config.schema.json);
- 备份数据库:在
keto migrate up之前务必创建备份(up.go 的提示原文即"Before running this command on an existing database, create a back up!"); - 就近执行迁移:在靠近 SQL 实例的网络位置运行迁移,降低失败风险;
- 验证服务健康:迁移与重启后,用
GET /health/alive与GET /health/ready(或keto status命令)确认实例就绪,再放行流量。
结语:从升级文档看 ORY Keto 的设计方向
纵观UPGRADE.md记录的四次关键变更,可以清晰看到 ORY Keto 的设计主线:把认证(authentication)与授权(authorization)彻底分离——Warden 的废弃、allowed 端点语义的收敛、引擎从 Ladon 切换到 OPA/Rego,以及最终走向支持 ACL、RBAC 的 Zanzibar 模型,都在反复强化"只做权限判定"的边界。对升级者而言,理解这条主线比死记端点对照表更重要:每次大版本重构虽然破坏性很大,但方向一致——简化、聚焦、可扩展。本文所引用的当前仓库源码与配置(config/keto.yml、cmd/migrate/、oryx/healthx/handler.go、internal/persistence/sql/migrations/sql/)正是这条主线演进到今天的落地证据,可作为继续深入研究的起点。
- 后端
- 应用安全
- 云原生
【免费下载链接】keto
The most scalable and customizable permission server on the market. Fix your slow or broken permission system with Google's proven "Zanzibar" approach. Supports ACL, RBAC, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
相关推荐
hls.js 迁移指南:从 0.x 到 1.7 的完整升级路径与破坏性变更详解
hls.js 迁移指南:从 0.x 到 1.7 的完整升级路径与破坏性变更详解 本指南以 hls.js 官方迁移文档 MIGRATING.md https://
音视频前端Mbed TLS 3.0 迁移指南:从 2.x 升级的破坏性变更清单与实战迁移路径
Mbed TLS 3.0 迁移指南:从 2.x 升级的破坏性变更清单与实战迁移路径 本篇指南以 Mbed TLS 官方 2.x→3.0 迁移文档为主体,结合当前
人工智能AI Agent多模态语音AI 应用如何在5分钟内上手OmniVoice?小白友好的语音合成入门教程
如何在5分钟内上手OmniVoice?小白友好的语音合成入门教程 想要快速掌握OmniVoice这个强大的语音合成工具吗?本文为你提供完整的5分钟快速入门指南,
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考