Skip to main content

创建 GitHub 应用的最佳做法

遵循这些最佳做法来提高 GitHub App 的安全性和性能。

选择所需的最低权限

注册 GitHub App 时,选择 GitHub App 所需的最低权限。 如果应用的任何密钥或令牌遭到入侵,这将限制可能发生的损害量。 有关如何选择权限的详细信息,请参阅“为 GitHub Apps 选择权限”。

当 GitHub App 创建安装访问令牌或用户访问令牌时,可以进一步限制应用可以访问的存储库以及令牌拥有的权限。 有关详细信息,请参阅 为 GitHub 应用生成安装访问令牌为 GitHub 应用生成用户访问令牌

保持在速率限制范围内

订阅 Webhook 事件,而不是轮询 API 以获取数据。 这将帮助你的 GitHub App 保持在 API 速率限制范围内。 有关详细信息,请参阅 将 Webhook 与 GitHub 应用配合使用构建响应 Webhook 事件的 GitHub 应用

请考虑使用条件请求来协助保持在速率限制范围内。 有关条件请求的详细信息,请参阅“使用 REST API 的最佳做法”。

如果可能,请考虑使用合并 GraphQL 查询而不是 REST API 请求来协助保持在速率限制范围内。 有关详细信息,请参阅 比较 GitHub 的 REST API 和 GraphQL APIGitHub GraphQL API 文档

如果达到了速率限制,并且需要重试 API 请求,请使用 x-ratelimit-resetRetry-After 响应头。 如果这些标头不可用,请在两次重试之间等待一段呈指数级增长的时间,并在重试特定次数后引发错误。 有关详细信息,请参阅“使用 REST API 的最佳做法”。

保护应用的凭据

可以为 GitHub App 生成私钥和客户端密码。 使用这些凭据,应用可以生成安装访问令牌、用户访问令牌和刷新令牌。 这些令牌可用于代表应用安装或用户发出 API 请求。

必须安全存储这些凭据。 存储机制取决于集成体系结构及其运行平台。 通常,应使用旨在将敏感数据存储在所使用的平台上的存储机制。

私钥

GitHub App 的私钥授予对安装应用的每个帐户的访问权限。

请考虑将 GitHub App 的私钥存储在密钥保管库(例如 Azure Key Vault)中,并将其设置为“仅登录”。

或者,可以将密钥存储为环境变量。 但是,此方法不如将密钥存储在密钥保管库中强。 如果攻击者获得了对环境的访问权限,他们就可以读取私钥,并作为 GitHub App 获得永久身份验证。

即使代码存储在专用存储库中,也绝不应在应用中对私钥进行硬编码。 如果你的应用是本机客户端、客户端应用,或在用户设备上运行(而不是在服务器上运行),则绝不应随应用一起交付私钥。

生成的私钥数量不得超出所需数量。 需删除不再需要的私钥。 有关详细信息,请参阅“管理 GitHub 应用的私钥”。

客户端机密

客户端密码用于为应用生成用户访问令牌,除非应用使用设备流。 有关详细信息,请参阅“为 GitHub 应用生成用户访问令牌”。

如果应用是网站或 Web 应用,请考虑将客户端密码存储在密钥保管库(例如 Azure Key Vault)中,或者存储为服务器上的加密环境变量或机密。

如果你的应用是本机客户端、客户端应用,或者在用户设备上运行(而不是在服务器上运行),则无法保护客户端密码。 如果计划根据应用生成的令牌限制对自己服务的访问,应谨慎使用,因为任何人都可以访问客户端密码来生成令牌。

安装访问令牌、用户访问令牌和刷新令牌

安装访问令牌用于代表应用安装发出 API 请求。 用户访问令牌用于代表用户发出 API 请求。 刷新令牌用于重新生成用户访问令牌。 应用可以使用其私钥生成安装访问令牌。 应用可以使用其客户端密码生成用户访问令牌和刷新令牌。

如果应用是网站或 Web 应用,则应在后端加密令牌,并确保可以访问令牌的系统的安全性。 请考虑将刷新令牌存储在与活动访问令牌不同的位置。

如果你的应用是本机客户端、客户端应用或在用户设备上运行(而不是在服务器上运行),则可能无法保护令牌以及在服务器上运行的应用。 不应生成安装访问令牌,因为这样做需要私钥。 相反,应生成用户访问令牌。 应通过为应用平台推荐的机制来存储令牌,请记住,存储机制可能并不完全安全。

使用合适的令牌类型

GitHub Apps 可以生成安装访问令牌或用户访问令牌,以便发出经过身份验证的 API 请求。

安装访问令牌会将活动归因于你的应用。 这对于独立于用户运行的自动化非常有用。

用户访问令牌会将活动归因于用户和应用。 这些对于根据用户输入或代表用户执行操作非常有用。

会基于 GitHub App 的权限和访问权限限制安装访问令牌。 会基于 GitHub App 的权限和访问权限以及用户的权限和访问权限限制用户访问令牌。 因此,如果你的 GitHub App 代表用户执行操作,它应始终使用用户访问令牌而不是安装访问令牌。 否则,应用可能会允许用户查看或执行他们不该看到或执行的操作。

在任何情况下,应用都不应使用 personal access token 或 GitHub 密码进行身份验证。

全面持久授权

用户登录后,应用开发人员必须完成额外的步骤,以确保用户有权访问系统中的数据。 每次登录都需要对其成员身份、访问权限以及当前 SSO 状态进行全新检查。

使用持久且唯一的 id 来还原用户

当用户登录并在应用程序中执行操作时,你必须记住是哪个用户执行了该操作,以便在他们下次登录时授予他们访问相同资源的权限。

若要将用户正确存储在数据库中,请始终使用用户的 id。 此值永远不会为用户更改,也不会用于指向其他用户,因此它可以确保你对用户提供所需访问权限。 可以使用 GET /user REST API 终结点查找用户的 id。 请参阅“用户的 REST API 终结点”。

如果存储对存储库、组织和企业的引用,也请使用其 id 来确保指向它们的链接保持准确。

_切勿_使用可能随时间变化的标识符,包括用户句柄、组织数据域或电子邮件地址。

验证每个新身份验证的组织访问权限

使用用户访问令牌时,应跟踪授权该令牌访问的组织。 如果组织使用 SAML SSO,而用户未执行 SAML SSO,则用户访问令牌将无法访问该组织。 可以使用 GET /user/installations REST API 终结点来验证用户访问令牌有权访问哪些组织。 如果用户未被授权访问组织,则应在他们执行 SAML SSO 之前阻止他们访问你自己的应用程序中组织拥有的数据。 有关详细信息,请参阅“GitHub App 安装的 REST API 终结点”。

使用组织和企业上下文存储用户数据

除了通过 id 字段跟踪用户标识之外,还应该保留每个用户所处的组织或企业的数据。 这将有助于确保在用户切换角色时不会泄露敏感信息。

例如:

  1. 用户处于需要 SAML SSO 的 Mona 组织中,并在执行 SSO 后登录到你的应用。 你的应用现在可以访问用户在 Mona 中所做的任何操作。
  2. 用户从 Mona 中的存储库中提取一堆代码,并将其保存在你的应用中进行分析。
  3. 稍后,用户切换作业,并从 Mona 组织中删除。

当用户访问你的应用时,他们能否在其用户帐户中查看来自 Mona 组织的代码和分析?

这就是为什么跟踪应用保存的数据来源至关重要。 否则,你的应用对组织来说是一个数据保护威胁,如果他们不能相信你的应用正确地保护了其数据,他们很可能会禁止你的应用。

令牌过期

GitHub 强烈建议使用会过期的用户访问令牌。 如果之前选择不使用会过期的用户访问令牌,但希望重新启用此功能,请参阅“激活 GitHub 应用的可选功能”。

安装访问令牌在 1 小时后过期,即将过期的用户访问令牌在 8 小时后过期,刷新令牌在 6 个月后过期。 但是,还可以在不再需要令牌时立即撤销令牌。 有关详细信息,请参阅“DELETE /installation/token”来撤销安装访问令牌,参阅“DELETE /applications/{client_id}/token”来撤销用户访问令牌。

缓存令牌

用户访问令牌和安装访问令牌将一直用到过期。 应缓存创建的令牌。 创建新令牌前,检查缓存以查看是否已有有效令牌。 重用令牌将使应用更快,因为这会减少生成令牌的请求。

制定处理安全漏洞的计划

应制定计划,以便及时处理任何安全漏洞。

如果应用的私钥或机密遭到入侵,则需要生成新的密钥或机密,更新应用以使用新密钥或机密,并删除旧密钥或机密。

如果安装访问令牌、用户访问令牌或刷新令牌遭到入侵,应立即撤销这些令牌。 有关详细信息,请参阅“DELETE /installation/token”来撤销安装访问令牌,参阅“DELETE /applications/{client_id}/token”来撤销用户访问令牌。

定期进行漏洞扫描

应定期对应用进行漏洞扫描。 例如,可以为托管应用代码的存储库设置代码扫描和机密扫描。 有关详细信息,请参阅“关于代码扫描”和“关于机密扫描”。

选择适当的环境

如果应用在服务器上运行,请验证服务器环境是否安全,以及它是否能够处理应用预期的流量。

订阅最少 Webhook

仅订阅应用所需的 Webhook 事件。 这将有助于减少延迟,因为应用不会收到不需要的有效负载。

使用 Webhook 机密

应为 GitHub App 设置 Webhook 机密,并验证传入 Webhook 事件的签名是否与机密匹配。 这有助于确保传入的 Webhook 事件是有效的 GitHub 事件。

有关详细信息,请参阅“将 Webhook 与 GitHub 应用配合使用”。 有关示例,请参阅“构建响应 Webhook 事件的 GitHub 应用”。

为用户留出时间接受新权限

当你向 GitHub App 添加存储库或组织权限时,在其个人帐户或组织中安装了该应用的用户将收到一封电子邮件,提示他们查看新权限。 在用户批准新权限之前,其应用安装将仅获得旧权限。

更新权限时,应考虑让应用后向兼容,为用户留出时间来接受新权限。 可以使用安装带有 new_permissions_accepted 操作属性的 Webhook,了解用户接受应用新权限的时间。

以安全的方式使用服务

如果应用使用第三方服务,则应以安全的方式使用它们:

  • 应用使用的任何服务都应具有唯一的登录名和密码。
  • 应用程序不应共享服务帐户(如电子邮件或数据库服务)来管理 SaaS 服务。
  • 只有履行管理职责的员工才应具有托管应用的基础结构的管理员访问权限。

添加日志记录和监视

请考虑为应用添加日志记录和监视功能。 安全日志可以包括:

  • 身份验证和授权事件
  • 服务配置更改
  • 对象读取和写入
  • 用户和组权限更改
  • 角色提升到管理员

日志应为每个事件使用一致的时间戳,并应记录所有记录事件的用户、IP 地址或主机名。

启用数据删除

如果 GitHub App 可供其他用户或组织使用,则应为用户和组织所有者提供删除其数据的方法。 用户应无需发送电子邮件或致电支持人员即可删除其数据。

其他阅读材料