Skip to main content

将 OIDC 与 GitHub Copilot 扩展配合使用

了解如何将 OpenID Connect (OIDC) 与 Copilot Extension结合使用来增强安全性。

关于适用于 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 令牌交换为访问令牌,以便对向扩展发出的请求进行身份验证。

初始请求

  1. 用户向 Copilot Extension发送一条消息。
  2. GitHub 生成包含用户标识信息的 OIDC 令牌。
  3. GitHub 使用 OIDC 令牌调用令牌交换终结点。
  4. 服务验证令牌并返回访问令牌。
  5. GitHub 在对扩展的请求中包含访问令牌。
# HTTP header
Authorization: Bearer <your-service-token>
X-GitHub-Token: <github-token>

后续请求

  1. GitHub 缓存访问令牌,时间最长可达 10 分钟。
  2. 缓存的令牌供后续请求重复使用。
  3. 如果令牌过期或失效,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 有三个步骤。

  1. 配置令牌交换终结点
  2. 在 Copilot 扩展设置中启用 OIDC
  3. 验证 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:

  1. 在 GitHub 上任意页的右上角,单击你的个人资料照片。
  2. 导航到你的帐户设置。
    • 对于由个人帐户拥有的应用,请单击“设置”****。
    • 对于组织拥有的应用:
      1. 单击“你的组织”。
      2. 在组织的右侧,单击设置
  3. 在左侧边栏中,单击“ 开发人员设置”。
  4. 在左侧边栏中,单击“GitHub Apps”。
  5. 在要为 Copilot Extension 配置的 GitHub App 的右侧,单击“编辑****”。
  6. 在左侧边栏中,单击“Copilot”。****
  7. 在“OpenID Connect Token Exchange”下,选中“Enabled”********。
  8. 在“Token exchange endpoint”字段中,输入令牌交换 URL****。
  9. 在“Request header key”字段中,输入服务令牌的标头密钥****。 默认为 Authorization
  10. 在“Request header value”字段中,输入标头值格式****。 默认为 Bearer ${token}

验证 OIDC 令牌

令牌交换终结点应遵照以下步骤验证 GitHub OIDC 令牌:

  1. https://github.com/login/oauth/.well-known/openid-configuration 提取 JSON Web 密钥集 (JWKS)。
  2. 验证令牌签名。
  3. 验证所需声明。
    • aud:受众。 Copilot Extension的客户端 ID。
    • sub- 主体。 发出请求的 GitHub 用户 ID。 响应仅限于用户有权访问的数据。 如果用户没有权限,则会显示 400 Bad Request
    • iat:发布时间。 颁发令牌的时间戳。 这通常是过去时间戳,但表示创建令牌的确切时刻。
    • nbf:生效时间。 在此时间戳之前,令牌无效。 这应是过去的某一时间戳。
    • exp:过期时间。 令牌过期时的时间戳。 这应是将来的某一时间戳。
    • act:参与者。 委托访问中的参与实体。 这应是一个常量字符串。

故障排除

以下部分概述了为 Copilot Extension实现 OIDC 的常见问题和最佳做法。

令牌验证错误

  • 请确保使用的是正确的 JWKS 终结点。
  • 验证所有必需声明是否存在且有效。
  • 检查时间戳(iatnbfexp)是否在有效范围内。

令牌交换失败

  • 对于无效令牌,返回 HTTP 400
  • 如果用户缺少必要权限,则返回 HTTP 403
  • 如果 GitHub 收到 403 响应,它将使用新令牌重试请求。

性能问题

  • 实现高效令牌验证,以最大程度减少延迟。
  • 使用适当的令牌过期时间(建议:10 分钟或更短)。
  • 考虑高流量扩展的缓存影响。

最佳做法

  • 将令牌范围限定为所需的最低权限。
  • 实现正确的错误处理和记录。
  • 监视令牌交换模式是否存在安全异常。
  • 使令牌保持在短期内有效,以最大程度降低安全风险。
  • 在颁发访问令牌前验证所有声明。
  • 考虑在令牌交换终结点上实现速率限制。
  • 对所有令牌交换通信使用 HTTPS。