GitHub OAuth2令牌: 如何限制读取单个私有回购的访问

用例:

  1. 控制台应用(部署到第三方机器上)需要能够通过 GitHub API (v3)下载属于某个组织的私有回购协议的 tarball 副本

  2. 应用程序应该只能访问这一个私人回购,没有其他回购只读权限。

在我的 github 帐户上注册了 client _ id/secret 之后,我可以通过为应用程序创建授权来完成(1)。然而,授权返回的令牌似乎并不允许对回购协议进行只读访问,也不限于一个回购协议(例如,人们可能使用令牌修改该回购协议以及属于该组织的其他回购协议)。

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

46812 次浏览

我不认为可以用这种方式限制 github OAuth 令牌

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

因此,虽然可以根据活动的 类别限制令牌的范围,但不能将其限制在回购协议的子集中。

部署密钥 可以限制为单个回购,但允许写访问。

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

Github 甚至明确提到/支持这种策略,称之为 机器使用者

部署密钥是解决问题的方法。

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

例如,运行 bash 脚本:

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

现在你的线人有权在构建期间访问私人回购。

您可以通过访问 Github 上的存储库,然后单击 设定 > 配备钥匙 > 添加部署键来添加 Deploy 密钥

我希望在我的 Github 行动中有更好的访问控制,但同时也可以访问多个存储库。毫无疑问,“部署密钥”还有很长的路要走。您可以选择读/写权限,但不幸的是,每个新存储库都需要一个新的权限对。下面我来告诉你我是怎么做到的。

假设您需要从第三个运行的 GithubActions 访问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文件的内容作为相应存储库的 Deploy 键(如果需要,选择写权限)
  • 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
    
  • 利润

免责声明

正如你可能猜想的那样,上面的解决方案并没有扩展,在某个时候你可能会考虑设置一个 机器使用者(在 starned 的回答中建议) ,它与组织帐户(甚至是免费的)工作得最好,并且提供了访问个人访问令牌和 OAuth 的权限。

正如最好的答案所暗示的那样,目前 GitHub 不可能做到这一点。

这不是对你问题的直接回答,但是我之所以要做同样的事情,是为了遵守只允许 TCP 443从限制区域出站的政策。

GitHub 接受 TCP 443上的 SSH 作为文档 给你。

TLDR: 如果您将 ssh 从 ssh://git@github.com修改为 ssh://git@ssh.github.com:443,那么它应该是成功的。

要将 github 设置为在 SSH 配置文件中使用 TCP443,请编辑位于 ~/. SSH/config 的文件,并添加以下部分:

Host github.com
Hostname ssh.github.com
Port 443
User git

您可以测试这种方法是否适用于:

$ ssh -T git@github.com
> Hi username! You've successfully authenticated, but GitHub does not
> provide shell access.

现在(2022年10月)应该可以做到这一点:

引入细粒度个人访问令牌 (2022年10月)

今天,我们正在为 GitHub.com 上的所有用户帐户启用公共测试版中的细粒度个人访问令牌(PATs)。
这种新类型的令牌使开发人员和资源所有者对令牌访问拥有更多的控制权和可见性。
今天的博客文章中了解有关这种新标记类型的更多信息。

这些新令牌提供了更多的权限可供选择,必须作用域为特定的组织或帐户,并且必须过期。
组织所有者还将找到新的工具来管理可以访问其组织的令牌,并且可以在使用这些令牌之前要求这些令牌得到批准。

https://i0.wp.com/user-images.githubusercontent.com/1666363/196268191-dd27554f-746e-45cf-9b92-a62f1846cd9e.gif?ssl=1 -- PATsv2-light2

您可以尝试使用 新的令牌创建流程,并在我们的 社区讨论中提供反馈。

有关详细信息,请参阅“ 创建细粒度的个人访问令牌”。

如果您愿意,这允许选择特定的存储库。