应用、服务身份与凭据
Developer App、Environment、Service Account、Credential 和个人默认空间的正式资源模型
应用、服务身份与凭据
Developer App 是 OceanWay API 产品中的业务容器。所有机器调用都必须归属明确的 App、Environment 和 Service Account;API Key 只是 Credential,不是用户、钱包或独立权限主体。登录后管理界面统一位于 console.oceanway.tech/ai,ai.oceanway.tech 公开 Developer Center 不读取或修改这些资源。
正式资源层级
Organization / Personal Space
└── Developer App
└── Environment
└── Service Account
└── Credential| 对象 | 职责 | 不负责 |
|---|---|---|
| Organization / Personal Space | 资源所有权、成员关系和付款上下文 | 保存应用运行密钥 |
| Developer App | 产品接入边界、授权范围和用量聚合 | 充当执行身份或钱包 |
| Environment | 隔离开发、测试、生产配置与风险 | 复制 Organization 成员体系 |
| Service Account | 非交互式 Principal、Scope 和策略主体 | 保存明文 Secret、拥有独立余额 |
| Credential | 证明 Service Account 身份 | 单独决定权限、价格或付款方 |
Workspace 与可选 Project 是 App 或 Service Account 的授权绑定,不插入上述身份父子层级。Billing Account 由 Personal Space 或 Organization 的付款规则解析;App、Environment、Service Account 和 Credential 只能拥有预算与限额,不能拥有子钱包。
唯一 Command Owner
Developer Access Domain 是四层资源的唯一 Command Owner:
DeveloperAccess.create/update/disable/deleteApp
DeveloperAccess.create/update/disableEnvironment
DeveloperAccess.create/update/disableServiceAccount
DeveloperAccess.issue/rotate/revokeCredential这个边界独立于部署方式。首期可以在共享后端中实现为模块化领域服务,但必须满足:
- Console AI BFF 只校验页面请求、调用领域 Command 和组合读模型,不直接写领域表;
- Console 顶层安全/治理页面可以发起停用或撤销 Command,不复制 Credential 状态;
- Public API Edge 只校验 Credential 和读取不可变 Access Snapshot,不创建或修改四层资源;
- Developer Center 只读取公开内容,不接收任何客户资源 Command;
- Text/Media Gateway 不认识 App 层级,不保存 Developer Credential;
- 所有状态变化使用同一事务、并发约束、审计和 Outbox 事件。
Developer 是逻辑产品与领域,不是第二客户后台。Customer Identity、Organization、Membership、Workspace、Project、Billing Account 和 Audit 继续由共享客户控制面拥有。
个人默认空间与默认应用
每个个人用户首次进入 Console AI 专业空间时,Developer Access Domain 以幂等方式确保存在:
Personal Space
└── 默认 Developer App
└── 默认 Environment
└── 默认 Service Account这个默认链路用于降低第一次调用门槛,但底层仍使用完整资源模型:
- 用户可以直接创建第一枚 Credential,而不必手工创建四层资源;
- UI 可以把默认层级折叠为“我的应用”,不能在数据库中继续把 Key 直接绑定 User;
- 默认对象有稳定 ID、审计和生命周期,不通过名称识别;
- 用户创建第二个 App、加入企业或启用高级策略后,再展开完整层级;
- 个人默认资源始终属于 Personal Space,不会因用户加入企业而自动转为企业资产。
企业用户必须在当前 Organization 上下文中创建 App。员工离职只撤销 Membership 和其交互式访问,Organization 拥有的 App、Service Account、Credential、Run 与用量保持有效,除非企业策略明确停用或轮换。
Developer App
Developer App 表示一个客户应用或集成,例如网站后端、内部自动化、移动应用服务端或数据处理任务。
建议核心字段:
developerAppId
ownerType = personal_space | organization
ownerId
workspaceId?
projectId?
name / description
status
allowedOfferingIds[]?
defaultBudgetPolicyId?
createdBy / createdAt / updatedAt规则:
- App 只能属于一个 Personal Space 或 Organization;
- 企业 App 的管理权限来自 Membership 和 Developer 角色,不来自任意持有 Key 的用户;
- App 可以绑定一个 Workspace 和可选 Project,以获得 Asset、Agent、MCP 和 Project Context;
- 绑定只扩大到明确授权的资源,不等于 App 可以读取整个 Organization;
- App 停用后拒绝新请求,但历史 Run、Usage 和 Audit 保持可查询;
- App 删除必须先处理活跃 Credential、Webhook、保留策略和不可变账务记录,不能级联擦除历史事实。
Environment
Environment 将同一 App 的配置、凭据、Webhook、限额和运行历史隔离。典型显示名可以是开发、测试和生产,但系统使用稳定 environmentId,不把名称写成固定权限规则。
environmentId
developerAppId
name / slug
riskClass
status
allowedOfferingIds[]?
rateLimitPolicyId?
budgetPolicyId?
dataPolicyId?
createdAt / updatedAt环境规则:
- Credential、Webhook Endpoint 和 Run 必须固定一个 Environment;
- 不允许把测试环境 Key 静默提升为生产环境 Key;
- Environment 的模型、区域或数据策略只能收窄 App 与 Organization 策略;
- 生产环境的高风险变更可以要求再认证、双人审批或延迟生效;
- 删除环境前必须撤销 Credential,并保留历史 Run 和计费解释所需快照。
Service Account
Service Account 是非交互式权限主体。它唯一归属一个 Environment,并继承 App 与所有者上下文。
serviceAccountId
environmentId
ownerOrganizationId? / personalSpaceId?
name
status
scopes[]
allowedOfferingIds[]?
workspaceBindings[]
projectBindings[]
assetPermissions[]
agentDeploymentPermissions[]
mcpConnectionGrants[]
rateLimitPolicyId?
budgetPolicyId?
createdBy / createdAt / disabledAt?Service Account 不登录 Console,不持有 Customer Session,也不能成为 Organization 成员。Customer User 通过 Console AI 专业空间管理它;Public API 根据 Credential 解析它。
生产自动化必须使用 Service Account Credential,不能依赖某位员工的个人交互式 Session 或个人 Key。Service Account 权限采用最小授权:未声明的 Scope、Offering、Workspace、Project、Asset、Agent 或 MCP Tool 默认拒绝。
Credential 与 API Key
第一阶段客户 Developer Credential 类型为 API Key;未来正式发布的 OAuth Client 或客户侧短期 Token 只有经独立 ADR 批准后,才可以扩展同一开发者凭据抽象。OceanWay 内部 Workload Principal/Credential 属于独立信任边界,不复用 Developer Credential 的类型、Audience、Secret 或轮换记录。
developerCredentialId
serviceAccountId
type = api_key
prefix / lastFour
secretHash
status
expiresAt?
notBefore?
ipAllowlist[]?
rateLimitOverrideId?
createdBy / createdAt
lastUsedAt?
rotatedFromId?
revokedAt?安全规则:
- Secret 使用密码学安全随机源生成,只在创建响应中完整返回一次。
- 服务端只持久化校验所需 Hash、前缀和尾号,不保存可逆密文。
- 列表、详情、审计、日志和支持工具永不回显完整 Secret。
- 轮换创建新 Credential,通过
rotatedFromId建立关系;旧 Key 在明确宽限期后撤销。 - Credential 泄漏只需撤销 Credential,不改变 Service Account、App、钱包或历史 Run 身份。
- Developer Key 只在
api.oceanway.techEdge 鉴权,不转发给 Text/Media Gateway 或 Provider。
身份类型与登录边界
| Principal | 认证或委托方式 | 可以做什么 |
|---|---|---|
| Customer User | OceanWay Customer Identity / Console Host-only Session | 登录 Console AI、提交有权执行的 Developer Access Command |
| Service Account | DeveloperCredential;Playground 由短期 Grant 委托 | 作为唯一 Public API 执行主体,不登录任何客户 UI |
| OceanWay Workload Principal | 短期 Workload Credential 或 mTLS assertion | OceanWay 服务间调用和私有网关访问 |
| OceanWay Workforce | 独立 Workforce Identity | 进入内部 Admin 和运维读模型 |
DeveloperCredential 与 Playground Execution Grant 都是认证或授权证据,不是 Principal。Playground 不创建第五类持久主体:Customer User 是业务发起人,目标 Service Account 是唯一 API 执行主体,Grant 只证明该用户在受限条件下可以委托该 Service Account 执行。
Customer Session、DeveloperCredential、Playground Execution Grant、Workload Credential 和 Workforce Session 必须使用不同 Audience。Developer Center 不需要 Customer Session;Console Session 不能被 Public API、私有网关或 Admin 接受。Workload Identity 是内部信任体系的统称;实现中必须区分稳定 Workload Principal 与它使用的短期 Workload Credential。
Playground Execution Grant
Playground 不创建、读取或复用长期 Developer Credential。浏览器携带 Console Session 调用 Console AI BFF;BFF 从 Developer Access Domain 取得目标 App、Environment 与 Service Account 的 Access Snapshot,再向 Authorization/Policy Token Issuer 申请短期、受限的 Execution Grant,并由服务端调用 Public API Edge。BFF 只能申请和持有 Grant,不能自行签发。
Grant 必须绑定 Customer User Actor、目标 Service Account、App、Environment、允许的 Offering/操作、有效期、使用约束和审计身份。它不是持久 Credential,不能执行四层资源命令,也不得暴露给浏览器 JavaScript、本地存储、URL 或客户端日志。API Edge 接受 Grant Audience,但仍不接受 Customer Session。
授权解析
每个 Public API 请求按固定顺序计算有效权限。正式客户程序集成使用 Developer Credential;Console Playground 使用短期受限 Grant:
Developer Credential 有效或 Playground Grant 有效
∩ 目标 Service Account 启用且 Scope 允许
∩ Environment 启用且策略允许
∩ Developer App 启用且应用授权允许
∩ Organization / Personal Space 有效
∩ Workspace / Project / Asset / Agent / MCP Grant
∩ Model Offering 已发布到 api Surface
∩ Entitlement、预算、限额和区域/数据策略任何一层拒绝即停止执行。前端传入的 Organization、App 或 Project ID 只能作为选择提示,服务端必须从 Developer Credential 或 Playground Grant 重新解析所有权和允许范围。
授权结果进入不可变 Execution Manifest,至少固定:
actorPrincipalId
executionPrincipalId = serviceAccountId
authenticationType = developer_credential | playground_grant
developerCredentialId? / playgroundExecutionGrantId?(严格二选一)
ownerId / organizationId
developerAppId / environmentId
workspaceId / projectId?
billingAccountId
offeringRevision
policyDecisionId合法组合只有两种:
正式 API:actorPrincipalId = serviceAccountId
executionPrincipalId = serviceAccountId
developerCredentialId = required
Playground:actorPrincipalId = customerUserId
executionPrincipalId = serviceAccountId
playgroundExecutionGrantId = required两种认证引用不得同时存在,也不得同时为空。Console BFF 的 Workload Principal 只记录在服务跳转与 Invocation Audit 中,不能覆盖业务 Actor 或执行主体。
Scope 与资源授权
Scope 表示动作权限,例如模型执行、Run 查询、结果读取或 Webhook 管理;它不能代替资源级权限。
建议将权限分为:
- API 动作:
models:read、runs:create、runs:read、outputs:read; - 能力范围:文本、Embedding、Rerank、图像、视频等;
- Offering 白名单:允许的公开模型或 Family;
- 上下文范围:Workspace、Project 与数据区域;
- 生态资源:固定 Asset Revision、Agent Deployment、MCP Connection Grant;
- 商业约束:预算、并发、速率、合同权益和成本中心。
最终 Scope 名称和粒度需要进入 API 版本契约;实现不得用一个泛化 all 永久绕过策略层。
生命周期
App、Environment 和 Service Account 可以停用并恢复;Credential 只允许 active → revoked/expired,撤销后不可恢复。删除是受治理的资源终止,不得删除 Ledger、Usage、Run、Audit 或历史 Offering/价格快照。
状态传播规则:
- 父资源停用立即阻止所有子 Credential 发起新请求;
- 已在执行的 Run 按已冻结 Manifest 和安全策略继续、取消或人工处置,不能由前端猜测;
- 恢复父资源不会恢复已撤销或已过期 Credential;
- Membership 撤销影响用户管理权限,不自动删除企业 Service Account;
- Credential 状态变化发布审计事件并失效鉴权缓存。
预算、计费与用量归属
每次调用同时记录以下维度:
billingAccountId
organizationId / personalSpaceId
developerAppId
environmentId
serviceAccountId
developerCredentialId? / playgroundExecutionGrantId?(严格二选一)
workspaceId / projectId?
runId / executionAttemptId
offeringRevision / pricingSnapshot预算和限额可以设置在 Organization、Workspace、App、Environment 或 Service Account,并按“上层上限与下层上限取更严格者”计算。它们不是余额复制。企业请求余额不足时不得自动改扣员工个人钱包。
Console AI 专业空间展示 API 与 Playground 维度;Console 顶层展示全平台 Billing Account、订阅和账本;Developer Center 只展示公开列表价;Admin 展示脱敏的内部诊断与供应成本。
Webhook 所有权
Webhook Endpoint 归属一个 Environment,事件投递使用 App/Environment 上下文,并在 Console AI 专业空间管理。签名材料使用独立的 WebhookSigningSecretVersion,采用一次显示、版本化轮换和 Vault 托管,不属于 Service Account 的 Developer Credential,也不复用 Public API Key。
Service Account 可以拥有管理 Webhook 的 Scope,但 Webhook Endpoint 不是 Service Account 子对象,以免轮换或停用某个调用身份时错误删除整个应用的事件出口。
审计不变量
以下动作必须记录 Actor、Owner、App、Environment、目标资源、前后状态、原因、Request/Trace ID 和时间:
- App、Environment、Service Account 的创建、停用、恢复和删除;
- Credential 创建、轮换、撤销、过期与高风险使用;
- Scope、模型白名单、Workspace/Project Binding 和预算策略变更;
- Webhook Secret 轮换、Endpoint 停用与事件重放;
- 企业成员对生产资源的访问和权限提升。
审计不得包含完整 Secret、完整 Prompt、媒体二进制或 Provider Credential。
当前实现基线
当前 developer_api_keys 直接保存 user_id,支持名称、到期、IP 列表、速率和并发字段。服务会保存可逆密文,并允许登录用户之后再次回显 Secret。系统中尚无 Developer App、Environment、Service Account、Organization/Membership 或相应资源授权表。
这套实现可以支撑个人 MVP,但不能作为企业生产身份模型继续扩展。
目标状态
目标态中,每个正式客户程序请求都能从 Credential 唯一解析到 Service Account、Environment、Developer App、所有者、Workspace/Project、Billing Account 和策略决策;Playground 请求从受限 Grant 解析到同等业务上下文及 Customer User Actor。员工身份与生产服务身份分离;个人用户仍能通过自动创建的默认层级快速开始。四层资源只有 Developer Access Domain 可以修改,Console AI 只是专业任务入口,公开 Center 没有客户私有状态。
实施阶段
| 阶段 | 交付 | 退出条件 |
|---|---|---|
| ID0 模型冻结 | 数据模型、唯一 Command Owner、角色、Scope、生命周期和审计事件 | 不再新增直接归属 User 或由 BFF 直写的 Key 功能 |
| ID1 默认个人链路 | Personal Space、默认 App/Environment/Service Account | 新个人用户从 Console AI 无需理解层级即可创建一次性 Key |
| ID2 企业链路 | Organization Membership、Developer 角色、Workspace/Project Binding | 成员离职不影响企业生产身份 |
| ID3 Credential 收口 | Hash-only Secret、轮换、撤销、缓存失效和审计 | 任意接口均无法再次回显 Secret |
| ID4 Playground Grant | 短期受限授权、Console BFF 服务端转发与审计 | 浏览器无长期 Key,API Edge 无 Customer Session |
| ID5 策略与商业 | Scope、Offering 白名单、预算、限额和 Billing Account 解析 | 每个请求都有完整且可解释的授权决策 |
验收标准
- 新用户首次进入 Console AI 后自动拥有且只拥有一套幂等创建的默认开发者链路。
- 每枚 API Key 唯一归属一个 Service Account,并可追溯到 Environment、App 和 Owner。
- 完整 Secret 只在创建或轮换响应中出现一次,数据库、日志和查询接口均无法恢复。
- 停用 App、Environment 或 Service Account 后,全部子 Credential 立即拒绝新请求。
- 企业成员离职后不能管理企业 App,但未依赖该成员身份的生产调用不被删除。
- 服务端忽略伪造的 Organization/Workspace/Project 上下文,并按 Credential 重新授权。
- API 用量可按 App、Environment、Service Account 和 Credential 聚合,金额仍归统一 Billing Account。
- 私有网关只接收 OceanWay Workload Principal 使用的短期 Workload Credential,不接收 Customer Session 或 Developer Key。
- Developer Center 无四层资源读写接口;Console BFF 和 API Edge 均不能直接写领域存储。
- Playground 的浏览器网络、页面状态与本地存储中不存在长期 Developer Credential。