GitHub OAuth2 令牌:如何限制访问以读取单个私有仓库

Posted

技术标签:

【中文标题】GitHub OAuth2 令牌:如何限制访问以读取单个私有仓库【英文标题】:GitHub OAuth2 Token: How to restrict access to read a single private repo 【发布时间】:2014-12-09 22:22:15 【问题描述】:

用例:

    命令行应用程序(部署到第 3 方计算机)需要能够通过 GitHub API (v3) 下载属于组织的私有 repo 的 tarball 副本

    应用程序应该只能访问这个私有仓库,而不能访问其他具有只读权限的仓库。

在我的 github 帐户上注册 client_id/secret 后,我​​已经能够通过为应用程序创建授权来完成 (1)。但是,授权返回的令牌似乎不允许对存储库进行只读访问,也不限于一个存储库(例如,一个人可能会使用该令牌与属于该组织的其他存储库一起修改此存储库)。

是否可以通过适当的范围限制访问?我在 API 文档 (https://developer.github.com/v3/oauth/#scopes) 中看不到任何相关内容。

【问题讨论】:

我也会对类似的东西感兴趣,减去只读约束。唯一相关的是您可以为存储库创建的部署密钥,但我不确定您是否可以通过 API 使用这些密钥。似乎这里唯一的解决方法是添加一些您用来登录 API 的虚拟用户作为该存储库的协作者。 【参考方案1】:

我不相信您可以以这种方式限制 github OAuth 令牌。 github docs for OAuth 这么说

虽然带有 OAuth 的 Git over HTTP 减少了某些类型的应用程序的摩擦,但请记住,与部署密钥不同,OAuth 令牌适用于用户有权访问的任何存储库。

因此,虽然您可以根据活动的类型来限制令牌的范围,但不能将其限制为 repos 的子集。

Deploy keys 可以被限制为单个 repo,但允许写访问。

显而易见的策略(正如 Thomas 所提到的)是创建一个代表应用程序的虚拟帐户。考虑到 OAuth 的目标,无论如何这可能是一个更好的工作流程——它可以让您轻松更改应用所拥有的权限,就好像它实际上是用户一样。

Github 甚至明确提及/支持这一策略,称其为 machine users。

【讨论】:

虽然可行,但对组织来说并不方便,因为您无法撤销特定用户的令牌。 部署密钥默认是只读/拉取的,你也可以给他们写/推送访问权限。 但如果我理解正确,您不能在 github 操作中使用部署密钥,因为您必须将私钥存储在某处。为单个存储库创建访问令牌或部署密钥会很棒,但能够在操作中使用它。 @maksim-nesterenko 有一个ssh-agent action,您可以使用它设置通过 GitHub 机密提供的 ssh 私钥。【参考方案2】:

部署密钥是必经之路

默认情况下,它们不允许写入访问,并且它们的范围仅限于特定存储库(与 GitHub 个人访问令牌不同)。因此,您现在可以生成一个私钥/公钥对,将其中一个设置为只读/仅在 GitHub 中的单个存储库上部署密钥,并在您的 CI 中使用私钥。

例如运行一个 bash 脚本:

eval "$(ssh-agent -s)";
ssh-add <your private deploy key>;

现在您的 CI 有权在构建期间访问私有存储库。

您可以通过转到 Github 上的存储库然后单击 设置 > 部署密钥 > 添加部署密钥来添加部署密钥p>

【讨论】:

但是它们也可以具有写访问权限,这使它们成为密码的完美替代品(如果发生泄漏,损坏仅限于单个 repo!)【参考方案3】:

我希望在我的 Github 操作 中获得更好的访问控制,同时还可以访问多个存储库。果然,部署密钥是可行的。您可以选择读/写权限,但不幸的是,每个新存储库都需要一对新的权限。下面我将向您展示我是如何让它发挥作用的。

假设您需要从第三个运行的 Github Actions 访问 2 个存储库

生成您的密钥
ssh-keygen -N '' -t ed25519 -C "First Key Name" -f ./first_key
ssh-keygen -N '' -t ed25519 -C "Second Key Name" -f ./second_key
只要在将密钥添加到 Github 存储库中的密钥后从文件系统中删除密钥,就不需要密码。*.pub 文件的内容添加为各个存储库的部署密钥(如果需要,选择写入权限) 将first_keysecond_key 文件的内容分别添加到第三个存储库的机密中,分别为DEPLOY_KEY_FIRSTDEPLOY_KEY_SECOND 现在您可以删除生成的密钥文件 - 您不想再保留它们了。您可以随时生成新的。 设置工作流文件
name: Some automatic action

on:
  # on push event
  push:
  # allow manual run
  workflow_dispatch:

env:
  # sockets for multiple ssh agents (1 per key)
  SSH_AUTH_SOCK_FIRST: /tmp/ssh_agent_first.sock
  SSH_AUTH_SOCK_SECOND: /tmp/ssh_agent_second.sock

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      # first step is to setup ssh agents
      - name: Setup SSH Agents
        run: |
          # load deploy keys from the secrets
          echo "$ secrets.DEPLOY_KEY_FIRST " > ./ssh_key_first
          echo "$ secrets.DEPLOY_KEY_SECOND " > ./ssh_key_second

          # set chmods (required to use keys)
          chmod 0600 ./ssh_key_*

          # start agents
          ssh-agent -a $SSH_AUTH_SOCK_FIRST > /dev/null
          ssh-agent -a $SSH_AUTH_SOCK_SECOND > /dev/null

          # add each key to their own ssh agent
          SSH_AUTH_SOCK=$SSH_AUTH_SOCK_FIRST ssh-add ./ssh_key_first
          SSH_AUTH_SOCK=$SSH_AUTH_SOCK_SECOND ssh-add ./ssh_key_second

          # you can now remove keys from the filesystem
          rm -f ./ssh_key_*

      # now you can use these keys in normal git commands
      - name: Clone first
        env:
          # assign relevant agent for this step
          SSH_AUTH_SOCK: $ env.SSH_AUTH_SOCK_FIRST 
        run: |
          git clone git@github.com:user/first.git ./first

      - name: Clone second
        env:
          SSH_AUTH_SOCK: $ env.SSH_AUTH_SOCK_SECOND 
        run: |
          git clone git@github.com:user/second.git ./second
利润

免责声明

正如您可能猜到的那样,上述解决方案并未扩大规模,并且在某些时候您可能会考虑设置Machine user(建议在 starwed 的答案中),它最适合组织帐户(甚至免费)并提供个人访问权限令牌和 OAuth。

【讨论】:

以上是关于GitHub OAuth2 令牌:如何限制访问以读取单个私有仓库的主要内容,如果未能解决你的问题,请参考以下文章

OAUTH2 刷新令牌

如何为 OAuth2 访问令牌指定受众?

Oauth2、范围和用户角色

无法检索 oauth2 的访问令牌

移动应用程序的 OAuth2 访问令牌是不是必须过期?

使用Spring启动进行Oauth2身份验证