关于适用于 Copilot Extensions的 OpenID Connect (OIDC)
OpenID Connect(OIDC)允许 Copilot Extensions直接从其云提供商交换短期有效的令牌,而不是存储长期有效的 GitHub 凭据。 此功能使 Copilot 代理和技能组能够更安全地对用户进行身份验证和访问云资源。
OIDC 概述
Copilot Extensions通常需要代表用户访问第三方资源或 API。 传统上,这需要将 GitHub 令牌存储为机密,并进行额外的 API 调用,以将这些令牌映射到系统中的用户标识。 凭借 OIDC,扩展可通过交换 GitHub 标识信息直接从身份验证服务请求短期有效的访问令牌。
启用后,GitHub 的 OIDC 提供程序会自动生成一个令牌,其中包含有关用户和请求上下文的声明。 身份验证服务可以验证这些声明,并将其交换为专门针对服务限定范围的访问令牌。
使用 OIDC 对 Copilot 技能组开发尤其有价值,因为它使你能够利用现有 API 终结点,而无需维护单独的特定于 GitHub 的终结点。 不必复制终结点来接受 GitHub 令牌,而是可以使用 OIDC 将 GitHub 标识转换为服务的原生身份验证令牌。
使用 OIDC 的好处
通过在 Copilot Extension中实现 OIDC 令牌交换,你可以:
- 避免存储长期有效的 GitHub 令牌或维护 GitHub 与服务的标识之间的映射。
- 使用短期有效的令牌,这些令牌会自动过期,可专门针对服务需求限定范围。
- 避免对 GitHub 的 API 进行额外调用,以验证令牌并提取用户信息。
- 使用现有 API 为 Copilot 技能启用直接集成,而无需为 GitHub 维护单独的终结点。
- 通过将 GitHub 身份验证转换为服务的原生令牌来重复使用现有 API 终结点。
令牌交换流
下面概述了 Copilot Extensibility Platform 如何将 OIDC 令牌交换为访问令牌,以便对向扩展发出的请求进行身份验证。
初始请求
- 用户向 Copilot Extension发送一条消息。
- GitHub 生成包含用户标识信息的 OIDC 令牌。
- GitHub 使用 OIDC 令牌调用令牌交换终结点。
- 服务验证令牌并返回访问令牌。
- GitHub 在对扩展的请求中包含访问令牌。
# HTTP header
Authorization: Bearer <your-service-token>
X-GitHub-Token: <github-token>
后续请求
- GitHub 缓存访问令牌,时间最长可达 10 分钟。
- 缓存的令牌供后续请求重复使用。
- 如果令牌过期或失效,GitHub 会请求一个新令牌。
了解 OIDC 令牌
GitHub 中的 OIDC 令牌是一个 JWT,其中包含有关用户和请求上下文的声明:
{
"jti": "<unique-token-id>",
"sub": "<github-user-id>",
"aud": "<your-client-id>",
"iss": "https://github.com/login/oauth",
"nbf": 1632492967,
"exp": 1632493867,
"iat": 1632493567,
"act": {
"sub": "api.copilotchat.com"
}
}
为扩展设置 OIDC
为扩展设置 OIDC 有三个步骤。
配置令牌交换终结点
在服务中创建一个符合 RFC 8693 OAuth 2.0 令牌交换的终结点。 此终结点应:
-
接受具有以下表单编码参数的
POST
请求:grant_type=urn:ietf:params:oauth:grant-type:token-exchange &resource=<https://your-service.com/resource> &subject_token=<github-jwt-token> &subject_token_type=urn:ietf:params:oauth:token-type:id_token
-
使用服务的访问令牌返回 JSON 响应:
{ "access_token": <"your-service-token">, "Issued_token_type":"urn:ietf:params:oauth:token-type:access_token", "token_type": "Bearer", "expires_in": 3600 }
-
验证失败时返回错误响应:
{ "error": "invalid_request" }
在 Copilot Extension的设置中启用 OIDC
在 Copilot Extension的配置中,启用 OIDC:
-
在 GitHub 上任意页的右上角,单击你的个人资料照片。
-
导航到你的帐户设置。
- 对于由个人帐户拥有的应用,请单击“设置”****。
- 对于组织拥有的应用:
- 单击“你的组织”。
- 在组织的右侧,单击设置。
- 对于由企业拥有的应用:
- 如果使用的是 Enterprise Managed Users,请单击你的企业,以直接转到企业帐户设置。
- 如果使用的是个人帐户,请单击你的企业,然后单击企业右侧的设置。
-
导航到 GitHub App 设置。
- 对于由个人帐户或组织拥有的应用:
- 在左侧边栏中,单击 开发人员设置,然后单击 GitHub Apps。
- 对于由企业拥有的应用:
- 在左侧边栏中,在“设置”下,单击 GitHub Apps。
- 对于由个人帐户或组织拥有的应用:
-
在要为 Copilot Extension 配置的 GitHub App 的右侧,单击“编辑****”。
-
在左侧边栏中,单击“Copilot”。****
-
在“OpenID Connect Token Exchange”下,选中“Enabled”********。
-
在“Token exchange endpoint”字段中,输入令牌交换 URL****。
-
在“Request header key”字段中,输入服务令牌的标头密钥****。 默认为
Authorization
。 -
在“Request header value”字段中,输入标头值格式****。 默认为
Bearer ${token}
。
验证 OIDC 令牌
令牌交换终结点应遵照以下步骤验证 GitHub OIDC 令牌:
- 从 https://github.com/login/oauth/.well-known/openid-configuration 提取 JSON Web 密钥集 (JWKS)。
- 验证令牌签名。
- 验证所需声明。
aud
:受众。 Copilot Extension的客户端 ID。sub
- 主体。 发出请求的 GitHub 用户 ID。 响应仅限于用户有权访问的数据。 如果用户没有权限,则会显示400 Bad Request
。iat
:发布时间。 颁发令牌的时间戳。 这通常是过去时间戳,但表示创建令牌的确切时刻。nbf
:生效时间。 在此时间戳之前,令牌无效。 这应是过去的某一时间戳。exp
:过期时间。 令牌过期时的时间戳。 这应是将来的某一时间戳。act
:参与者。 委托访问中的参与实体。 这应是一个常量字符串。
故障排除
以下部分概述了为 Copilot Extension实现 OIDC 的常见问题和最佳做法。
令牌验证错误
- 请确保使用的是正确的 JWKS 终结点。
- 验证所有必需声明是否存在且有效。
- 检查时间戳(
iat
、nbf
和exp
)是否在有效范围内。
令牌交换失败
- 对于无效令牌,返回
HTTP 400
。 - 如果用户缺少必要权限,则返回
HTTP 403
。 - 如果 GitHub 收到 403 响应,它将使用新令牌重试请求。
性能问题
- 实现高效令牌验证,以最大程度减少延迟。
- 使用适当的令牌过期时间(建议:10 分钟或更短)。
- 考虑高流量扩展的缓存影响。
最佳做法
- 将令牌范围限定为所需的最低权限。
- 实现正确的错误处理和记录。
- 监视令牌交换模式是否存在安全异常。
- 使令牌保持在短期内有效,以最大程度降低安全风险。
- 在颁发访问令牌前验证所有声明。
- 考虑在令牌交换终结点上实现速率限制。
- 对所有令牌交换通信使用 HTTPS。