There are numerous ways to authenticate with the GitHub API, and it can be a bit confusing at the start to know which way you should use. This article breaks down the various authentication methods for GitHub.com and GitHub Enterprise (Server or Cloud).
If you wish GitHub could do something not offered in the core product, or you wanted to build an integration to help the greater GitHub Ecosystem connect with your product, this article is for you.
As we are dealing with API Authentication Methods, there is a minimal assumed level of knowledge of REST APIs (though the information applies to GraphQL as well), and a basic understanding. of authentication processes.
I know I just hyped up a discussion about authentication methods, but did you know you can actually connect to the GitHub API without any authentication at all?
Various GET requests on the GitHub API can be performed without any form of authentication whatsoever. These requests will only return public information, and as a general rule of thumb you can think of the endpoints available for this method to be ones that provide public information only.
As an example, if I did a GET request to my user data, I would see my public profile information to include my company, name, any public emails, etc. However, private information such as private emails are not going to come through this endpoint, as GitHub cannot verify. that you have permission to access the content.
Because of the lack of authentication, you are limited to 60 requests per hour using this method.
While I don't recommend you use this form of API access for anything regularly, it can be useful to test what information is public that you may not want public. For instance, on GitHub Enterprise Server (GHES), you may have Private Mode enabled which should deny all unauthenticated API calls. You may want to verify this setting hasn't changed so you test it occasionally.
That said, there are far better ways to interact with the GitHub API as discussed below.
Basic Authentication with GitHub's API means to provide your username and password to the API call. This is not a recommended approach, as you are prompted to enter your password every time you do a call, and passing your password over an API call is likely a cause for concern security-wise.
Because you are authenticating, you receive 5000 requests per hour to the GitHub API, however there are more secure ways to interact with the API as discussed further below.
Finally, if you're attempting to access information on an organization with SAML enabled, this method will not work as there is no SAML handling in a username/password API call.
I'm actually going to recommend against using this method. It offers no benefit over Personal Access Tokens (PATs, discussed below). If you just want to make a one time call, I can understand testing with basic authentication, but it is much more beneficial and secure to use something like a Personal Access Token (PAT).
Personal Access Tokens (PATs)
Personal Access Tokens, or PATs, are encrypted keys that work only for your user, and are the first form of authentication that I'd actually recommend using regularly. You create them within your developer settings on GitHub, and delete them and regenerate the tokens easily.
With PATs, you're able to have a more secure form of authentication. The token can have specific scopes granted for it, limiting the attack surface area if the token was leaked to a malicious actor. Additionally, the tokens can be revoked and rolled easily, so if there is a leak it can be handled quickly.
Because this is an authentication method, it again is granted 5000 requests per hour before being rate limited. Finally, you can approve the token to be used for organizations on an organization by organization level, enabling Single Sign On (SSO)/SAML support. This means you can make API calls against an organization with SAML enforced using a PAT, and not run into any multi-factor-authentication (MFA) issues.
I like using PATs for one-off scripts using bash or command-line, PowerShell, or in tools like Postman and Insomnia.rest. This allows me to test endpoints, or run things ad-hoc, without the need for a full-blown integrations.
That said, these are NOT recommended for full integrations that are running regularly. You should consider an OAuth App, or even better a GitHub App.
OAuth2 Apps provide similarities to Personal Access Tokens (PATs). In fact, PATs are actually a special kind of OAuth2 Apps on GitHub's backend. With an OAuth2 App, you get the security of a PAT without the need for every user to create their own, they just need to "sign in with GitHub" to approve the application.
OAuth2 Apps do authenticate as the user, and therefore have the same 5000 rate limit as other authentication methods. This limit is shared with the user's limit, since the app is authenticating and acting as that user.
OAuth2 Apps have the same granularity in scopes that PATs have, and any changes to these scopes require the user to re-approve the application for their account.
To create an OAuth2 App, a user or organization can go to their settings and register a new OAuth Application. This will provide you with a ClientID and Client Secret that are used to go through the OAuth flow and authenticate over the API.
Finally, there is a downside to OAuth2 Apps in that if you want them to take action based on webhooks, you need to add those webhooks to the various organizations and repositories for the app to listen to. This is automatic with GitHub Apps, which we'll discuss next.
The GraphQL API Explorer from GitHub is an example of an OAuth2 App.
Anytime you want to take action as a user and not have to ask all of those users to create their own PAT, OAuth2 can shine. For example, if I am building an integration that requires user authentication, I can create an OAuth App that abstracts all the scope management from the user. That user can decide to approve my application and then the integration can use the API as that user.
That said, GitHub Apps can do everything OAuth2 Apps can, and therefore should be used instead. Let's talk about those now.
GitHub Apps are the new hot thing when it comes to API authentication methods with GitHub. If you've ever used GitHub Actions or GitHub Pages, they are actually GitHub Apps built using the same framework available to everyone else.
GitHub Apps are first class actors with dedicated rate limits. This means they can replace service/bot accounts that take up license seats, and have their own rate limit of 5000 requests outside of the user limit of 5000 requests for that user.
GitHub Apps can actually use the OAuth flow if needed to take actions as a user, but more often than not you use a method with installation access tokens as discussed in the example below.
GitHub Apps are the most secure of the authentication methods listed in this article, and provide the easiest setup for the end-user. They automatically subscribe to the needed webhook events, use short-lived installation access tokens (ephemeral tokens expire after one hour), have a super fine-grained permission model, and have loads of libraries and frameworks like Octokit and Probot to assist in development.
Before showing an example of API calls, I wanted to touch on just how granular the permission model is for GitHub Apps. Not only can you give access to read/write/admin for a repository, user data, etc, but you can also get as narrow as read access to a single file in a repository. This is very powerful as you can practice least privilege security recommendations and ensure you only have what you need to interact with the GitHub ecosystem.
First get a list of installations your app is installed on using a JSON Web Token (JWT) signed with your App ID and Private Key.
The call above returns an array of installation objects, i.e. where your app has been installed (on users, organizations, repos, etc).
Using this installation_id and your JSON Web Token, request an Installation Access Token.
Now you can use this Installation Access Token to make calls to the API as you would normally.
GitHub Apps are what you should be building when you need a standing integration to orchestrate between your systems and the GitHub API. They can be used for compliance control, enforcing branch protection and certain settings. They can be used to run audits, merge pull requests, and interact with external tools such as Slack or Microsoft Teams.
The official GitHub Slack app and GitHub Jira app are both GitHub Apps and are open sourced. I actually wrote a blog post about some of the contributions I made to the GitHub Slack app on the official GitHub blog.
The GitHub API is very robust and offers many ways to authenticate. The main ones to be concerned about, are Personal Access Tokens (PATs) and GitHub Apps.
Personal Access Tokens should be used for shell scripts, one-off ad-hoc calls, and in API endpoint testing.
GitHub Apps shoudl be used for all other integration types whenever possible. They are the most secure, and easiest for the end-user to implement.