• 
      

    Support GitHub fine-grained PATs.

    Review Request #15032 — Created May 8, 2026 and submitted

    Information

    Review Board
    release-8.x

    Reviewers

    Until now, we've only supported classic Personal Access Tokens for
    authenticating with GitHub. While these aren't going away (yet), we
    really ought to support the newer fine-grained tokens.

    This change adds support for those. This is mostly handled through
    documentation and validation--our existing validator needed to be
    updated because access with a fine-grained PAT does not return the
    x-oauth-scopes header. We therefore attempt to access an endpoint inside
    check_repository which requires the necessary permissions in order to
    detect this prior to actual usage.

    While in here, I realized that the scopes we ask for on classic PATs are
    excessive. We were asking for "user", "repo", and "admin:repo_hook".
    While we do access the /user/ API endpoint, this doesn't actually
    require the user scope for read. We also don't automatically create
    webhooks, we only show some instructions, so the repo_hook scope was
    never necessary either.

    • Added a fine-grained PAT with the necessary permissions and verified
      that GitHub functionality worked as expected.
    • Verified that a classic PAT still worked as expected.
    • Ran unit tests.
    • Built the manual and checked the changed pages.
    • Tested the remote-repositories API endpoint with both classic PATs
      (with only the "repo" scope) and fine-grained PATs (with the
      "Metadata" and "Contents" permissions)
    Summary ID
    Support GitHub fine-grained PATs.
    Until now, we've only supported classic Personal Access Tokens for authenticating with GitHub. While these aren't going away (yet), we really ought to support the newer fine-grained tokens. This change adds support for those. This is mostly handled through documentation and validation--our existing validator needed to be updated because access with a fine-grained PAT does not return the x-oauth-scopes header. We therefore attempt to access an endpoint inside `check_repository` which requires the necessary permissions in order to detect this prior to actual usage. While in here, I realized that the scopes we ask for on classic PATs are excessive. We were asking for "user", "repo", and "admin:repo_hook". While we do access the `/user/` API endpoint, this doesn't actually require the user scope for read. We also don't automatically create webhooks, we only show some instructions, so the repo_hook scope was never necessary either. Testing Done: - Added a fine-grained PAT with the necessary permissions and verified that GitHub functionality worked as expected. - Verified that a classic PAT still worked as expected. - Ran unit tests. - Built the manual and checked the changed pages. - Tested the remote-repositories API endpoint with both classic PATs (with only the "repo" scope) and fine-grained PATs (with the "Metadata" and "Contents" permissions)
    svowmurswprrnynnytupyvrqnmunlyxr
    Description From Last Updated

    The review request is linked to bug "x" (typo I assume).

    maubin maubin

    I want to keep admin:repo_hook so I can build out hook management. Better to not have people have to re-create …

    chipx86 chipx86

    Same here, let's keep admin:repo_hook.

    chipx86 chipx86

    This gets very long very fast. Maybe we should just point to the docs, and then include a link for …

    chipx86 chipx86

    This drops all classic access token information. Fine-grained access tokens have real limits. One token cannot be used for both …

    chipx86 chipx86

    We need the prior roles for existing APIs.

    chipx86 chipx86

    We should put the gettext on the previous line and )) on its own line so the string has more …

    chipx86 chipx86

    Doesn't this require the user scope?

    chipx86 chipx86

    Same here.

    chipx86 chipx86

    Minor nit: Can we alphabetize these?

    chipx86 chipx86

    We use "tradeoff" here (from my original copy) but "trade-off" in the new documentation. I think "trade-off" is more common. …

    chipx86 chipx86
    david
    chipx86
    1. 
        
    2. Show all issues

      I want to keep admin:repo_hook so I can build out hook management. Better to not have people have to re-create hooks after installing for the first time with this release.

      Same goes for the other mentions.

      1. I'm going to push back on this.

        I agree that hook management would be great to have, but it's not like we have any progress towards it today. Compared to everything else on our roadmap, it's also pretty low on the priority list. So this is an entirely speculative feature that we have no timeline for.

        Asking for permissions that we don't use is likely to get flagged in security reviews, especially for classic PATs where they grant read/write/edit/delete permissions across all public and private repos the user has access to.

        For fine-grained PATs, which most new users will probably be choosing, we already have the regeneration cost.

        The truly correct solution here is what we were talking about the other night with the GitHub App flow. That will allow us to prompt for additional permissions if and when we need them (including future integration with PRs, etc). And given the extensive list of benefits generally of moving to that model, I think there's a very good argument for prioritizing it sooner rather than later (and I'd be happy to take that on).

      2. I have work toward this and I want to finish that work. I had built this a long while back as part of the new repo form stuff, and never had the time to circle back to get it in. I had hoped to get it into 7.0, and then 8.0, but was far too busy with dark mode and then the licensing stuff to make it happen. I'm determined to get it into 9.0.

        What I don't want is to have to muddle up the support story when this feature lands, forcing only people who linked on Review Board 8 to recreate their tokens a release later, while a decade's worth of releases preceding that will have the permission. That's going to be super annoying.

        Fine-grained PATs and the GitHub app flow are great, and we should prioritize work on an app flow, but realistically people who already have things linked up are probably not going to change what's working for them, and I'd like to build upon what's been working without the complications of deleting this in 8.0 and re-adding in 9.0 and trying to explain that to people.

    3. reviewboard/hostingsvcs/github.py (Diff revision 2)
       
       
      Show all issues

      Same here, let's keep admin:repo_hook.

    4. reviewboard/hostingsvcs/github.py (Diff revision 2)
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      This gets very long very fast. Maybe we should just point to the docs, and then include a link for the template for creating the fine-grained tokens. I feel like we would want a big <strong>Warning:</strong> about expiration though.

    5. reviewboard/hostingsvcs/github.py (Diff revision 2)
       
       
      Show all issues

      We need the prior roles for existing APIs.

    6. reviewboard/hostingsvcs/github.py (Diff revision 2)
       
       
       
       
       
       
       
      Show all issues

      We should put the gettext on the previous line and )) on its own line so the string has more breathing room and is self-contained.

    7. reviewboard/hostingsvcs/github.py (Diff revision 2)
       
       
       
      Show all issues

      Doesn't this require the user scope?

      1. Given that we're only fetching this to determine if the token is correct, no. The user scope is only if we want the payload to include private details.

    8. 
        
    david
    chipx86
    1. 
        
    2. reviewboard/hostingsvcs/github.py (Diff revisions 2 - 3)
       
       
       
       
      Show all issues

      This drops all classic access token information.

      Fine-grained access tokens have real limits. One token cannot be used for both public repositories and for an organization's repository. It also cannot be used across multiple organizations. These are documented as limitations on GitHub's pages that haven't yet been addressed. That means a lot more juggling and debugging and expiration management for admins.

      I am happy to support fine-grained access tokens. I don't believe that them being the primary method we recommend is going to be a good user experience. Even if they're technically more secure, it's very situational, and the second there's an issue it turns into the same awful debugging session we've seen in the past where people have a linked account with a token someone removed.

      I think we should continue to support classic tokens as the primary, and document them, and support fine-grained tokens as the secondary. This mirrors how GitHub's had it for years. Even today, they advertise classic tokens for general API use, and fine-grained tokens for personal API and git-over-HTTPS use.

    3. 
        
    david
    chipx86
    1. I'm happy with this. Couple of tiny doc-related things, but otherwise I think this is good to go.

    2. Show all issues

      Same here.

    3. Show all issues

      Minor nit: Can we alphabetize these?

    4. reviewboard/hostingsvcs/github.py (Diff revision 4)
       
       
      Show all issues

      We use "tradeoff" here (from my original copy) but "trade-off" in the new documentation. I think "trade-off" is more common. Should we standardize on that?

    5. 
        
    david
    david
    maubin
    1. 
        
    2. Show all issues

      The review request is linked to bug "x" (typo I assume).

    3. 
        
    david
    chipx86
    1. Ship It!
    2. 
        
    david
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-8.x (915df9c)