GitHub Authentication: PATs (Personal Access Tokens)

What are the differences between classic and fine-grained PATs? And what are the advantages and compromises?

Manu Magalhães
System Weakness

--

What problem do Personal Access Tokens (PATs) try to solve?

Imagine that LinkedIn asked for your Twitter password to share a tweet. This was very normal in the olden days™: you provided your username and password to access an application via CLI or third-parties. It was no different for GitHub. Unless you were using SSH, you had to provide your username and password every time[1] you interacted with the GitHub API.

The problem with that approach is that anyone who guessed or stole your password could impersonate you, and have all your permissions to everything you could touch. Now throw weak passwords into the mix, and forget two factor authentication (it was not really a thing 10 years ago[2]), and you’ll have an interesting security case.

What solution has GitHub offered?

The solution was to restrict access via token, using SSH or first-generation PATs[3]. There were clear advantages:

  • Tokens are unique. If your password is compromised, an attacker cannot impersonate you by simply using your username and password in the command line, where damage can hit fast and furiously.
  • Tokens are revokable. That is a convenient decoupling from your credentials. You can rotate tokens daily, hourly, however you want, and still keep your password untouched.
  • Tokens are random. It is more challenging to rainbow table them than to guess a not-rarely-weak user password.

And in particular, classic PATs have two extra advantages over SSH keys:

  • PATs can also communicate with the GithHub web service to make REST/GraphQL requests. SSH can only connect to the GitHub server.
  • PATs are limitable. They can provide a restricted set of permissions. Password authentication provided full-blown rights, and SSH can only be scoped as read-only or read-write. Compare them against PATs, and you’ll see the security upgrade that meant:
List of permissions users can assign to PATs

Did the first-generation PATs solve the problem?

Sort of, because they have also created other issues.

  • Even though classic PATs have introduced some restrictions, authorisation can still be too broad, especially for the repo permission.
  • You cannot limit access to a subset of repositories. Classic PATs can interact with the all repositories the user can access.
  • A classic PAT can access all organisations the user can, but organisations can’t tell how many or which classic PATs their members have in place. There’s not a lot orgs can do to control them: it’s only possible to blanket block or allow classic PATs. Other than that, any classic PAT from an org user can access org resources without prior approval. On the bright side, though, organisations can require a classic PAT to be SSO’ed.
  • Users can create PATs that don’t ever expire. Truth be told, that is not an issue most of the time, but it’s something to consider.

Some might argue that “Most users and organisations will be just fine with classic PATs, why bother?” and there’s a point here. However, when much is at stake, you cannot rely on goodwill and luck alone. Controls must be in place, and risk must be contained. That’s why something more was finally delivered in October 2022.

PATs: The New Generation

Surprisingly, the marketing around Fine-Grained PATs (FGP) did not suggest they would phase out classic PATs, but there was a hint to it when they enabled organisations to completely block classic PATs (and that could explain why your classic PAT gets a 403 response when all else is fine).

Here are the advantages of fine-grained PATs:

  • With FGP, authorisation was refined into approximately 50 tightly scoped permissions.
  • FGPs have a “default deny” principle: access to specific repositories and organisations must be explicitly granted.
  • FGPs have an expiration date that range from 1 day to 1 year.
  • Organisations can approve, view and revoke each FGP.

Even though FGPs are the new official recommendation, they are still in beta and organisations must opt-in to use them.

There’s a big but to FGT, though. Because they are still beta, there are operations that are not supported yet, especially non trivial ones. And some very basic operations are not possible too, like querying the GH GraphQL API or access beyond organisations you’re a member of. Check here what you cannot do with a FGT.

Conclusion

This post has covered authorisation in GitHub as intended for humans. On my next post, we’ll cover service accounts, GitHub Apps and OAuth Apps. No history lectures, though.

If you like this story, please acknowledge 👏 and subscribe to the newsletter to see more like this!

[1] That is, unless you cached your password.

[2] In GitHub, 2FA is available since 2013, but will only become generally compulsory at the end of 2023.

[3] Personal Access Tokens have been around in GitHub for as far back as I could track — Nov 2014. However, PATs only became a requirement for all programmatic access to GitHub over HTTPS in August 2021, following a transition of almost two years.

--

--