
Openship权限模型详解组织、项目与Token的细粒度访问控制完整指南【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openshipOpenshipOpenship权限模型是一个自托管部署平台通过组织Organization—项目Project—Token三层结构实现细粒度访问控制每个资源归属唯一组织用户以 owner / admin / member / restricted 四种角色加入受限成员和 API Token 还可被精确授权到单个项目只读这类最小粒度。本文带你完整理解 Openship 的权限体系。 第一层组织——所有资源的家在 Openship 中组织是唯一的多租户边界。项目、部署、服务器、邮箱服务器、备份目标等资源全部挂在组织下而不是挂在用户下。数据库结构一目了然组织与成员表organization.ts 定义了organization、member、invitation三张表权限唯一依据是member表用户是否属于该资源所在的组织 扮演什么角色这是整个模型的地基组织还直接携带计费信息套餐档位planTierId、订阅状态使这个组织能否使用某功能的检查无需额外联表见 organization.ts。 新手提示一个组织 ≈ 一个团队工作区。邀请成员通过invitation表完成邀请可指定对方加入后的角色并设置过期时间。 第二层四种角色与默认权限角色定位默认权限范围owner创建者/最高权限组织内一切含计费与审计admin管理员除计费billing外的全部member普通成员除计费与审计日志audit外restricted受限成员默认零权限仅靠显式授权获得访问角色策略集中在一个纯函数里供每次调用校验和工具列表过滤共用保证两处永不漂移permission.ts。restricted 角色最小权限的核心这是 Openship 权限模型最有特色的设计——默认拒绝default-deny角色为restricted的成员除非有一行显式授权否则对组织资源零访问授权记录存储在 resource-grant.ts一行授权 谁user 对什么资源类型ID 哪些动作read/write/adminresourceId可以是具体 ID只授这一个项目也可以是*该类型下组织内全部资源典型场景给外包工程师授予项目 A read他可以查看 A 的部署与日志但完全看不到其他项目、服务器和计费信息。权限继承授权一个项目覆盖它的一切授权项目时其子资源自动受保护deployment部署、domain域名、service服务、env_var环境变量、build_session构建→ 继承项目的授权backup_policy/backup_run/backup_restore→ 继承备份目标backup_destination的授权解析逻辑在 permission.ts 的resolveResourceOrg中从叶子资源一路向上找到可授权根再校验该根上的授权。 第三层Token——给机器和脚本发缩小版通行证API TokenPAT是 Openship 供 CLI、脚本、MCP 客户端使用的 Bearer 凭据格式为opsh_pat_secret。关键安全设计只存哈希数据库中仅保存 SHA-256 哈希personal-access-token.ts明文只在创建时展示一次生成逻辑见 pat.ts可读标记readOnly的 Token 直接拒绝所有修改类请求范围锁定scoped设为scoped后Token 携带自己的授权表personal-access-token-grant.ts以restricted身份运行——即使属主是 ownerToken 也不能超越自身授权独立存储Token 授权与成员授权分表存放互不串读避免任何查询路径意外放大权限 一次请求是如何被校验的每个 API 路由都声明一个权限标签如project:read、project:service:edit中间件按四步裁决解析标签→ 得到资源类型 动作read/write/admin/list从 URL 提取资源 ID嵌套标签还会校验子资源确实属于 URL 声明的父资源防跨父混淆定位组织→ 详情接口从资源自身读出 org_id列表/创建接口按优先级取X-Organization-Id请求头 → 会话默认组织执行裁决→member查角色restricted 查授权assert统一出口完整流程见 route-permission.ts 与 permission.ts。两个值得称赞的安全细节IDOR 安全越权时统一返回404而非 403——攻击者无法通过错误码探测资源是否存在启动即审计路由注册表在启动时被扫描任何缺少权限声明的路由都会直接拒绝服务启动杜绝忘记加权限检查 授权面统一一个文件定义能授什么历史上可授权资源类型散落在 7 处导致漂移。现在统一收敛到 access-grants.tsGRANTABLE_RESOURCE_TYPES用户实际能授予的类型清单项目、服务器、邮箱服务器、备份目标、GitHub 仓库、平台功能等SENSITIVE_GRANT_TYPESbilling、audit被标记为高影响授权UI 中会明确提示爆炸半径grantableTypesForMode()按部署形态过滤——自托管不显示仅云端存在的billing云端不显示仅自托管的server/mail_server/job授权类型还分为两组呈现具体资源可从目录中挑选单个项目/仓库与平台功能整功能级授权resourceId 固定为*见 access-grants.ts。✅ 实践建议团队日常成员用member角色即可无需任何显式授权外部协作者设为restricted 项目级read/write授权边界清晰CI/脚本/Agent一律使用scopedPAT只授其任务所需的最小资源集并设置过期时间敏感操作计费与审计日志只给 owner给 member 审计权限时清楚这等于交出全员操作历史排查越权优先看 404 是否由permission.assert抛出——那是设计行为不是资源真的不存在小结Openship 的权限模型可以浓缩为三条原则资源认组织不认用户、角色给默认值、授权给例外、Token 的权限只由自己定义。这套机制让两个团队共用一台自托管实例、却互不可见成为开箱即用的默认状态而不需要额外的隔离改造。延伸阅读权限裁决核心permission.ts路由标签系统route-permission.ts成员授权表resource-grant.tsToken 授权表personal-access-token-grant.ts授权面单一来源access-grants.ts审计事件audit.ts【免费下载链接】openshipSelf-hosted deployment platform项目地址: https://gitcode.com/GitHub_Trending/ope/openship创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考