凭据托管服务围绕“凭据 Provider”和“运行时取凭据”两类动作工作。控制面负责创建、查询、更新、删除凭据配置;数据面负责校验调用方身份,并返回 API Key、OAuth2 Access Token、用户凭据或云厂商临时角色凭证。
推荐理解方式:先把 Provider 看成“凭据配置对象”,再把数据面 API 看成“按身份取凭据的入口”。Provider 不直接代表某个用户授权,用户授权 Token 会在 OAuth2 回调或手工导入后按用户维度保存。
租户由请求上下文注入。火山模式下通常来自 X-Top-Account-Id,也可以由 X-Asi-Token 解析得到;ByteCloud 模式下来自 Source-Service。Pool 用于在同一租户下隔离凭据命名空间,未传 PoolName 时默认使用 default。
- 同一租户内按 PoolName 隔离 Provider、用户凭据和 token 数据。
- 创建 API Key、OAuth2、Role Provider 时可传 ProjectName;未传时归属 default 项目。
- 返回结果中的 CredentialProviderTrn 使用 workloadpool/{PoolName}/{ProviderType}/{Name} 结构。
Provider 中的长期敏感值不会以明文保存。API Key 和 OAuth2 Client Secret 支持两种存储方式:默认 Secret Manager,或 KMS 信封加密。OAuth2 Access Token 和 Refresh Token 使用租户级 DEK 做信封加密后存储。
- SecretManager:创建或更新云 Secret,返回 SecretTrn。
- Kms:用指定或默认 KMS key 加密明文,密文存储在数据库;如配置 EncryptionKey,返回中会把它作为 SecretTrn。
- 删除 Provider 时,只有 Secret Manager 存储会同步删除底层 secret;KMS 模式不会删除外部 key。
API Key Credential Provider
API Key Provider 用于托管静态密钥。控制面保存 API Key 和元数据,数据面通过 IdentityToken 验证调用身份后返回明文 API Key 与使用位置元数据。
- 创建、查询、更新、删除 API Key Provider。
- 支持 ApiKeyMetadata 描述密钥应该放在 Header、Query 等位置,以及参数名和可选前缀。
- 支持按页列表、批量查询,以及通过统一 Provider 列表检索。
- 支持 Secret Manager 或 KMS 存储。
OAuth2 Credential Provider
OAuth2 Provider 用于托管 OAuth2 客户端配置和用户授权 token。它同时支持机器到机器的 M2M 流程,以及需要用户身份的 USER_FEDERATION 流程。
- 支持 Vendor:Custom、Google、Github、Coze、Feishu、Weixin、UserPool、ByteCloud、NextCode。
- 支持手工配置授权服务元数据,也支持通过 DiscoveryUrl 读取 OAuth2/OIDC discovery 信息。
- 支持 RFC 7591 Dynamic Client Registration(DCR),由服务向授权服务器注册 OAuth2 client。
- 用户联邦流程会返回已有 token、刷新 token,或返回 AuthorizationUrl 让用户授权。
- 支持 ForceAuthentication 强制重新授权,支持 Scopes、CustomParameters、UsernameFormat 和出向 EIP。
注意:Weixin 当前只支持 M2M 流程。对 USER_FEDERATION 调用 GetResourceOauth2Token 会返回参数错误。
User Credential 与 SSH Credential
User Credential 用于按用户身份保存任意凭据数据。创建、查询、更新、删除时都会校验 IdentityToken,凭据数据在写入数据库前会加密。SSH Credential 是 User Credential 的便捷能力:服务生成 SSH key pair,并把 key pair JSON 存为用户凭据。
- 按 IdentityToken 解析用户,凭据归属到该用户和 Pool。
- CredentialId 可由调用方指定;不传时自动生成 cred- 前缀 ID。
- UpdateUserCredential 使用 upsert 语义,可以创建或覆盖同一 CredentialId。
- CreateSshCredential 默认生成 Ed25519,也支持 RSA 和 ECDSA。
Role Credential Provider
Role Credential Provider 用于把经过验证的身份 token 映射到火山引擎云角色,并调用 STS 返回临时凭据。当前 Vendor 只有 VolcEng。
- 身份来源支持 UserPool 和 AgentPool 两类配置。
- 角色映射支持固定角色、按 claims 规则匹配、由请求选择允许角色、以及 Hybrid 混合模式。
- 支持 PolicyTemplate,可以用 token claims 渲染下游 STS policy。
- 数据面支持普通 AssumeRole 和 AssumeRoleWithOIDC,并透传 DurationSeconds。
Resource Binding 用于把 Provider 和业务资源建立关联。当前实现只允许绑定 api_key 和 oauth2 Provider,不能绑定 Role Credential Provider。
- 绑定前会校验 Provider 类型合法,且目标 Provider 在当前租户和 Pool 下存在。
- 统一列表 ListCredentialProviders 可以返回 API Key 与 OAuth2 Provider,并带出 BindingResourceNumber。
这是最简单的凭据托管路径,适合第三方服务只提供静态 API Key 的场景。
请求需要携带租户、区域、服务等网关 header;未传 PoolName 时默认写入 default Pool。
调用 CreateApiKeyCredentialProvider,提交 Name、ApiKey,按需提交 ApiKeyMetadata 和 SecretStorage。
记录 CredentialProviderTrn,用于资源治理、项目归属和问题排查。
业务服务调用 GetResourceApiKey,提交 ProviderName 与 IdentityToken;服务校验身份后解密并返回 ApiKey。
如果返回 ApiKeyMetadata,按其中的 Location、ParameterName 和 Prefix 放置密钥。
流程二:创建 OAuth2 Provider 并获取用户授权 Token
此路径适用于目标资源需要用户授权的场景,例如访问用户云盘、代码仓库或第三方 SaaS 资源。
调用 CreateOauth2CredentialProvider,配置 Vendor、ClientId、ClientSecret、Flow=USER_FEDERATION、Scopes 和 RedirectUrl。
调用 GetResourceOauth2Token,提交 ProviderName 和当前用户的 IdentityToken。
如果返回 AccessToken,直接使用;如果返回 AuthorizationUrl,引导用户完成授权。
下一次调用会优先返回未过期 access token;过期且 refresh token 有效时,会加锁刷新并更新存储。
如果 RedirectUrl 为空,会进入 session binding 流程。此时请求必须提供 ResourceOauth2ReturnUrl,服务会返回或生成 SessionUri;授权回调后再调用 CompleteResourceTokenAuth 绑定当前用户并完成 token 交换。
流程三:使用 M2M 获取 OAuth2 Token
M2M 适合服务到服务调用,不需要用户授权页。
- 创建 OAuth2 Provider,配置 Flow=M2M、ClientId、ClientSecret、Scopes 和 token endpoint。
- 调用 GetResourceOauth2Token,指定 Flow=M2M。
- 服务使用 client credentials 从授权服务器换取 token,并返回 AccessToken 与 ExpiresIn。
M2M 不会校验用户身份分支;如果业务仍传入 IdentityToken,该字段不会改变 M2M token 的主体语义。
此路径适合用户私有凭据,如 SSH key、浏览器 cookie 或工具侧私钥。
- 调用 CreateUserCredential,提交 IdentityToken、CredentialData 和可选 CredentialId。
- 服务验证 IdentityToken,把凭据写入当前用户和 Pool 下。
- 后续调用 GetUserCredential 或 UpdateUserCredential,仍需提交同一用户身份的 IdentityToken。
- 如需生成 SSH key pair,调用 CreateSshCredential,服务会生成并保存 key pair JSON。
此路径适合需要临时访问云资源的 Agent 或服务。
调用 CreateRoleCredentialProvider,配置身份来源 IdentityPool 和角色映射 RoleMapping。
简单场景使用 FromRole 固定角色;多角色场景使用 FromRule、FromRequest 或 Hybrid。
调用 GetRoleCredentials,提交 ProviderName、IdentityToken,按需传 RequestedRoleTrn、WithOIDC、DurationSeconds。
服务验证 JWT、确定 RolePolicy,再调用火山 STS 返回临时凭据。
已确认调用入口会注入租户上下文,例如 X-Top-Account-Id 或可解析的 X-Asi-Token。
已确认 PoolName 规划清晰;默认 Pool 与业务自定义 Pool 不混用。
已确认 Provider Name 在同一租户和 Pool 下唯一,删除后如需复用名称应使用硬删除后的结果。
已确认 API Key 或 OAuth2 Client Secret 的 SecretStorage 策略符合安全要求。
OAuth2 用户联邦流程已验证 RedirectUrl、ResourceOauth2ReturnUrl、callback 域名和 scope。
如使用 OAuth2 refresh token,已验证过期刷新、强制授权和授权服务器临时错误的处理路径。
如使用 Role Provider,已验证身份池 issuer、JWKS、claims、角色映射和 DurationSeconds。
如使用 EIP,已验证 Haina client 配置、EIP 绑定、解绑和失败回滚。
如使用 Resource Binding,已确认只绑定 api_key 或 oauth2 Provider。
已准备按 RequestId、Provider TRN、PoolName、ProjectName 排查问题。
创建 Provider 时不传 PoolName 会发生什么?
系统会使用默认 Pool:default。后续查询、更新、删除和数据面取凭据也需要落到同一个 Pool,否则会出现找不到 Provider 或找不到用户凭据的问题。
默认使用 Secret Manager。API Key 和 OAuth2 Client Secret 会写入 Secret Manager,Provider 返回中会带 SecretTrn。如果显式设置 StorageType=Kms,服务会把明文做信封加密后保存。
为什么 GetResourceOauth2Token 返回 AuthorizationUrl,而不是 AccessToken?
这表示当前用户在该 Provider、scope 和 custom params 组合下还没有可用 token,或 token 已过期且无法刷新。业务需要引导用户访问 AuthorizationUrl 完成授权,然后由回调保存 token。
ForceAuthentication 会做什么?
ForceAuthentication=true 时,服务会删除当前用户在该 Provider 下已有的 OAuth2 credential,并尽力向授权服务器撤销旧 token,然后重新返回授权 URL。
OAuth2 的 UsernameFormat 有什么影响?
默认格式是 ${sub}/${act.sub},要求身份 token 中有用户主体和委托主体;也支持 ${sub}。修改 UsernameFormat 会影响 OAuth2 credential 的用户维度,更新后会清理该 Provider 下已有 token。
为什么 Weixin 的 USER_FEDERATION 不可用?
当前实现中 Weixin Vendor 只支持 M2M。如果使用用户联邦流程,服务会返回 Flow 参数错误。
RoleMapping 的 FromRequest 如何选择角色?
如果请求里传了 RequestedRoleTrn,系统会检查它是否在 AllowedRoles 中;如果没传,会尝试从 identity token claims 的 preferred_role 读取。两者都没有或不在允许列表中,会返回 RequestedRoleTrn 参数错误。
Resource Binding 会限制运行时取凭据吗?
当前实现中 Resource Binding 用于资源关系管理和列表筛选,不是运行时强制鉴权点。运行时是否能取到凭据,仍主要由租户、Pool、Provider 是否存在以及 IdentityToken 校验决定。
SetResourceOauth2Token 可以直接对外使用吗?
不建议作为普通外部 API 使用。代码中该路由是手工注册,并明确没有放入 IDL service 以避免外部暴露,适合作为受控场景下导入已有 OAuth2 token 的高级能力。
删除 API Key Provider 时,如果底层使用 Secret Manager,会删除对应 secret。删除 OAuth2 Provider 时,会删除关联 OAuth2 credential、删除 Provider、解绑 EIP 并从 Project 中移除资源。KMS 模式不会删除外部 KMS key。
标准 API 同时支持下划线路径和压平路径。推荐在新接入中使用压平 Action 名称,便于和请求中的 Action 保持一致。