team-compass icon indicating copy to clipboard operation
team-compass copied to clipboard

Creation of a jupyterhub-bot GitHub account (its PAT isn't limited as secrets.github_token is)

Open consideRatio opened this issue 3 years ago • 7 comments

secrets.github_token can be used in GitHub workflows to open PRs, but opening them won't trigger GitHub Workflows to run because of a GitHub policy.

We create a few PRs and push a few commits automatically though, and would sometimes also like to have those also trigger tests.

Workarounds

  • To manually close and reopen a PR created by a bot account, that will make github workflow's trigger properly while otherwise only pre-commit.ci, readthedocs, and non-github CI services would run

  • To create a jupyterhub-bot GitHub account and an associated Personal Access Token.

    This is what the dask organization has done and works well as you can easily replace references to secrets.github_token with the PAT.

    Note that these kinds of accounts are considered "machine user" accounts, and fully acceptable by GitHub policy. image

Where we need a workaround

(If you know of other locations, please edit and add to this list)


Ping @manics who I know have struggled with this issue for action-major-minor-tag-calculator, and @sgibson91 who I think has run into this trouble as well.

consideRatio avatar May 17 '22 08:05 consideRatio

I am +1'ing this as it would mean that the test-this-pr workflow in mybinder.org-deploy wouldn't need to use my PAT and would reduce my notifications!

sgibson91 avatar May 17 '22 10:05 sgibson91

@jupyterhub/jupyterhubteam I've created a @jupyterhub-bot account without 2FA using the password used for our account of the same name, used for https://pypi.org.

I suggest that the following is done:

  1. We create a jupyterhub-bot team in the jupyterhub organization and invite the bot account there
  2. We grant the jupyterhub-bot team permissions as we go. Like this, the bot account doesn't have to "accept" becoming a maintainer etc if granted more permissions over time. I'm not sure that this "accept" part is needed though, but if we go for strategy A below that wouldn't be a big problem and we could omit creating a team as well.
  3. We make PATs available for repo's using strategy A below. Other strategies are mentioned as well for comparison.
    • Strategy A: We create multiple PATs for individual repos This requires access to the bot account typically as we would want to create new PATs from time to time. Even though a single individual could also do this maybe we can't have multiple individuals use 2FA? Anyhow, this could be accomplished by a few members having access to the password of the account, but we couldn't setup 2FA I think. Not having 2FA for the account relates a bit to #443.
    • Strategy B: We create a single PAT, used for a few separate repos The PAT would be shared like any kind of password between members like we have done for the jupyterhub-bot accounts password in PyPI.
    • Strategy C: We create a single PAT, used for the entire JupyterHub org Easy solution, but exposes the PAT to any project in the org and all maintainers of all projects in the org.

Questions

  1. Do you agree on granting permissions towards a bot account for the JupyterHub org in some way?
  2. Should we create a team for the bot account, or give the account permissions on individual repos directly?
  3. Should we go for a shared password to the bot account?

consideRatio avatar May 17 '22 17:05 consideRatio

Update on insights

  1. Using a GitHub account with a shared password won't work. We will be forced to do device authentication via email when a new device is used anyhow. But, if we have 2FA enabled, I think we don't have to do that.
  2. We can be multiple people using 2FA! I've communicated username/password/2FA-key to @sgibson91 and @minrk to avoid a bus factor of 1.

Proposal and piloting how to work with this account

I've went ahead and got started to pilot this in jupyterhub/zero-to-jupyterhub-k8s, and are ready to revert/adjust/expand to other projects based on feedback.

  • [x] A shared account is created: @jupyterhub-bot (JupterHub Bot Account <[email protected]>)
  • [x] Access to the account with password + 2FA key is shared to a few members (currently: @sgibson91, @minrk, and @consideeratio)
  • [x] We who have access will when needed add @jupyterhub-bot as a member to repositories where we don't want to use a secrets.github_token but instead use a PAT.
    • When having added @jupyterhub-bot as a repository member, you need to login as the bot account and visit the repository. There you will see a banner about the invite which you then accept.
  • [x] When we add @jupyterhub-bot to a project, we create a dedicated PAT for that project in https://github.com/settings/tokens when signed in as the jupyterhub-bot account.
    • When creating a new PAT, you declare a note and scopes. Make the note for example GitHub Actions: jupyterhub/zero-to-jupyterhub-k8s. When declaring the scopes, you often need write access to public repo's content, for that it would be sufficient with the public_repo scope I think.
    • When adding a new PAT to a repo. Make the name of the github actions secret JUPYTERHUB_BOT_PAT and let it be part of a GitHub Environment so that only the jobs that declare they want that access will be able to read it. To do that, visit https://github.com/jupyterhub/zero-to-jupyterhub-k8s/settings/environments for example.
  • [x] As part of adding @jupyterhub-bot, let's also create a branch protection rule that restricts anyone but org/repo admins from pushing to the protected branch.
    • This can be done in a repo specific link like https://github.com/jupyterhub/zero-to-jupyterhub-k8s/settings/branch_protection_rules
    • Check the Restrict who can push to matching branches checkbox for the rule, which should target the main branch.

Inspecting the jupyterhub-bot's permissions

You can see what the bot has access to in the JupyterHub org by visiting https://github.com/orgs/jupyterhub/people/jupyterhub-bot.

consideRatio avatar May 18 '22 12:05 consideRatio

For reference, @sgibson91 mentioned also that one can use a GitHub App to do some magic. For some details about that, see https://github.com/peter-evans/create-pull-request/blob/main/docs/concepts-guidelines.md#authenticating-with-github-app-generated-tokens.

consideRatio avatar May 18 '22 12:05 consideRatio

Explanation

GitHub Apps can be setup to have very fine-grained permissions and only installed to specific repositories. In a GitHub Actions workflow file running in a repository where the App is installed, you can "swap" secrets.GITHUB_TOKEN for a token generated by the App which will have just the right amount of permissions to do the required task in the required repository while also is allowed to trigger other GitHub Actions workflows, unlike secrets.GITHUB_TOKEN. It also means we do not have to maintain a separate "GitHub user" (the bot account) and any team access required.

I think the crucial part of understanding for GitHub Apps is that, while you can provide a webhook URL, it is not a requirement for setting up a GitHub App (it can be turned off) and is not a requirement for this kind of permissions elevation flow.

sgibson91 avatar May 18 '22 13:05 sgibson91

Could we also add "Branch protection rules" so that in the event a token or the account was compromised they wouldn't be able to force push to a repo branch?

manics avatar May 19 '22 17:05 manics

@manics i saw the following:

image

That seems perfect I think, then we list @jupyterhub/jupyterhubteam which doesn't include the @jupyterhub-bot account. But... I just can't manage to add the team to that list for some reason. I tried this for z2jh overe here: https://github.com/jupyterhub/zero-to-jupyterhub-k8s/settings/branch_protection_rules/25850097

UPDATE

Oh, but, we are 5 people with admin rights to the repo and then org admins can also push no matter what still. But, the jupyterhub-bot account isn't one of those. So, we should be good!

@manics I updated https://github.com/jupyterhub/team-compass/issues/516#issuecomment-1129961954 to include checking the Restrict who can push to matching branches checkbox.

consideRatio avatar May 19 '22 17:05 consideRatio

GitHub have introduced beta-access for fine-grained scopes for PATs https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/ This includes limiting a token to a single repo, as well as limiting access within that repo (e.g. permission to modify content in the repo, but not workflows).

manics avatar Oct 30 '22 15:10 manics

We have the bot account, and access to credentials to it is documented in #520. I figure we should minimize adoption of this bot still though, but use it as a fallback if required.

consideRatio avatar Jun 19 '23 05:06 consideRatio