Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ User access tokens will attribute activity to a user and to your app. These are

An installation access token is restricted based on the {% data variables.product.prodname_github_app %}'s permissions and access. A user access token is restricted based on both the {% data variables.product.prodname_github_app %}'s permission and access and the user's permission and access. Therefore, if your {% data variables.product.prodname_github_app %} takes an action on behalf of a user, it should always use a user access token instead of an installation access token. Otherwise, your app might allow a user to see or do things that they shouldn't be able to see or do.

Your app should never use a {% data variables.product.pat_generic %} or {% data variables.product.company_short %} password to authenticate.

## Validate organization access for every new authentication

When you use a user access token, you should track which organizations the token is authorized for. If an organization uses SAML SSO and a user has not performed SAML SSO, the user access token should not have access to that organization. You can use the `GET /user/installations` REST API endpoint to verify which organizations a user access token has access to. If the user is not authorized to access an organization, you should reject their access until they perform SAML SSO. For more information, see "[AUTOTITLE](/rest/apps/installations#list-app-installations-accessible-to-the-user-access-token)."
Expand All @@ -83,13 +85,17 @@ When you use a user access token, you should track which organizations the token

Installation access tokens expire after one hour, expiring user access tokens expire after eight hours, and refresh tokens expire after six months. However, you can also revoke tokens as soon as you no longer need them. For more information, see "[AUTOTITLE](/rest/apps/installations#revoke-an-installation-access-token)" to revoke an installation access token and "[AUTOTITLE](/rest/apps/oauth-applications#delete-an-app-token)" to revoke a user access token.

## Make a plan for rotating credentials
## Make a plan for handling security breaches

You should have a plan in place so that you can handle any security breaches in a timely manner.

In the event that your app's private key or secret is compromised, you will need to generate a new key or secret, update your app to use the new key or secret, and delete your old key or secret.

In the event that installation access tokens, user access tokens, or refresh tokens are compromised, you should immediately revoke these tokens. For more information, see "[AUTOTITLE](/rest/apps/installations#revoke-an-installation-access-token)."
In the event that installation access tokens, user access tokens, or refresh tokens are compromised, you should immediately revoke these tokens. For more information, see "[AUTOTITLE](/rest/apps/installations#revoke-an-installation-access-token)" to revoke an installation access token and "[AUTOTITLE](/rest/apps/oauth-applications#delete-an-app-token)" to revoke a user access token.

## Conduct regular vulnerability scans

{% data reusables.apps.app-scans %}

## Choose an appropriate environment

Expand All @@ -111,6 +117,18 @@ When you add repository or organization permissions to your {% data variables.pr

When you update permissions, you should consider making your app backwards compatible to give your users time to accept the new permissions. You can use the [installation webhook with the `new_permissions_accepted` action property](/webhooks-and-events/webhooks/webhook-events-and-payloads?actionType=new_permissions_accepted#installation) to learn when users accept new permissions for your app.

## Use services in a secure manner

{% data reusables.apps.app-services %}

## Add logging and monitoring

{% data reusables.apps.apps-logging %}

## Enable data deletion

If your {% data variables.product.prodname_github_app %} is available to other users or organizations, you should give users and organization owners a way to delete their data. Users should not need to email or call a support person in order to delete their data.

{% ifversion fpt or ghec %}

## Further reading
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The rate limit for {% data variables.product.prodname_github_app %}s using an in
In general, {% data variables.product.prodname_github_app %}s and {% data variables.product.prodname_oauth_app %}s can make the same API requests. However, there are some differences:

- The REST API to manage check runs and check suites is only available to {% data variables.product.prodname_github_app %}s.
- Enterprise resources are only available to {% data variables.product.prodname_oauth_app %}s.
- Enterprise-level resources such as the enterprise object itself are not available to {% data variables.product.prodname_github_app %}s. This means that {% data variables.product.prodname_github_app %}s cannot call endpoints like `GET /enterprise/settings/license`. However, enterprise-owned organization and repository resources are available.
- Some requests may return incomplete data depending on the permissions and repository access that was granted to an {% data variables.product.prodname_github_app %}. For example, if your app makes a request to get all repositories that a user can access, the response will only include the repositories that the app was also granted access to.

For more information about the REST API endpoints that are available to {% data variables.product.prodname_github_app %}s, see "[AUTOTITLE](/rest/overview/endpoints-available-for-github-apps)."
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
title: Best practices for creating an OAuth App
shortTitle: Best practices
intro: 'Follow these best practices to improve the security and performance of your OAuth App.'
versions:
fpt: '*'
ghes: '*'
ghae: '*'
ghec: '*'
topics:
- OAuth Apps
---

## Use a {% data variables.product.prodname_github_app %} instead

If possible, consider using a {% data variables.product.prodname_github_app %} instead of an OAuth App. In general, {% data variables.product.prodname_github_app %}s are preferred over {% data variables.product.prodname_oauth_app %}s. {% data variables.product.prodname_github_app %}s use fine-grained permissions, give the user more control over which repositories the app can access, and use short-lived tokens. These properties can harden the security of your app by limiting the damage that could be done if your app's credentials are leaked.

Similar to {% data variables.product.prodname_oauth_app %}s, {% data variables.product.prodname_github_app %}s can still use OAuth 2.0 and generate a type of OAuth token (called a user access token) and take actions on behalf of a user. However, {% data variables.product.prodname_github_app %}s can also act independently of a user.

For more information about {% data variables.product.prodname_github_app %}s, see "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps)."

For more information about migrating an existing {% data variables.product.prodname_oauth_app %} to a {% data variables.product.prodname_github_app %}, see "[AUTOTITLE](/apps/creating-github-apps/guides/migrating-oauth-apps-to-github-apps)."

## Use minimal scopes

Your OAuth App should only request the scopes that the app needs to perform its intended functionality. If any tokens for your app become compromised, this will limit the amount of damage that can occur. For more information, see "[AUTOTITLE](/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps)."

## Secure your app's credentials

With a client secret, your app can authorize a user and generate user access tokens. These tokens can be used to make API requests on behalf of a user.

You must store your app's client secret and any generated tokens securely. The storage mechanism depends on your integrations architecture and the platform that it runs on. In general, you should use a storage mechanism that is intended to store sensitive data on the platform that you are using.

### Client secrets

If your app is a website or web app, consider storing your client secret in a key vault, such as [Azure Key Vault](https://azure.microsoft.com/products/key-vault), or as an encrypted environment variable or secret on your server.

If your app is a native client, client-side app, or runs on a user device (as opposed to running on your servers), you cannot secure your client secret. You should use caution if you plan to gate access to your own services based on tokens generated by your app, because anyone can access the client secret to generate a token.

### User access tokens

If your app is a website or web app, you should encrypt the tokens on your back end and ensure there is security around the systems that can access the tokens. Consider storing refresh tokens in a separate place from active access tokens.

If your app is a native client, client-side app, or runs on a user device (as opposed to running on your servers), you may not be able to secure tokens as well as an app that runs on your servers. You should store tokens via the mechanism recommended for your app's platform, and keep in mind that the storage mechanism may not be fully secure.

## Use the appropriate token type

OAuth Apps can generate user access tokens in order to make authenticated API requests. Your app should never use a {% data variables.product.pat_generic %} or {% data variables.product.company_short %} password to authenticate.

## Make a plan for handling security breaches

You should have a plan in place so that you can handle any security breaches in a timely manner.

In the event that your app's client secret is compromised, you will need to generate a new secret, update your app to use the new secret, and delete your old secret.

In the event that user access tokens are compromised, you should immediately revoke these tokens. For more information, see "[AUTOTITLE](/rest/apps/oauth-applications#delete-an-app-token)."

## Conduct regular vulnerability scans

{% data reusables.apps.app-scans %}

## Choose an appropriate environment

If your app runs on a server, verify that your server environment is secure and that it can handle the volume of traffic that you expect for your app.

## Use services in a secure manner

{% data reusables.apps.app-services %}

## Add logging and monitoring

{% data reusables.apps.apps-logging %}

## Enable data deletion

If your app is available to other users, you should give users a way to delete their data. Users should not need to email or call a support person in order to delete their data.

{% ifversion fpt or ghec %}

## Further reading

- "[AUTOTITLE](/apps/publishing-apps-to-github-marketplace/creating-apps-for-github-marketplace/security-best-practices-for-apps)"
- "[AUTOTITLE](/apps/publishing-apps-to-github-marketplace/creating-apps-for-github-marketplace/customer-experience-best-practices-for-apps)"

{% endif %}
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@ shortTitle: GitHub Apps & OAuth Apps

In general, {% data variables.product.prodname_github_app %}s are preferred over {% data variables.product.prodname_oauth_app %}s. {% data variables.product.prodname_github_app %}s use fine grained permissions, give the user more control over which repositories the app can access, and use short-lived tokens. These properties can harden the security of your app by limiting the damage that could be done if your app's credentials were leaked.

Similar to {% data variables.product.prodname_oauth_app %}s, {% data variables.product.prodname_github_app %}s can still generate a type of OAuth token (called a user access token) and take actions on behalf of a user. However, {% data variables.product.prodname_github_app %}s can also act independently of a user. This is beneficial for automations that do not require user input. The app will continue to work even if the person who installed the app on an organization leaves the organization.
Similar to {% data variables.product.prodname_oauth_app %}s, {% data variables.product.prodname_github_app %}s can still use OAuth 2.0 and generate a type of OAuth token (called a user access token) and take actions on behalf of a user. However, {% data variables.product.prodname_github_app %}s can also act independently of a user. This is beneficial for automations that do not require user input. The app will continue to work even if the person who installed the app on an organization leaves the organization.

{% data variables.product.prodname_github_app %}s have built-in, centralized webhooks. {% data variables.product.prodname_github_app %}s can receive webhook events for all repositories and organizations the app can access. Conversely, {% data variables.product.prodname_oauth_app %}s must configure webhooks individually for each repository and organization.

The rate limit for {% data variables.product.prodname_github_app %}s using an installation access token scales with the number of repositories and number of organization users. Conversely, {% data variables.product.prodname_oauth_app %}s have lower rate limits and do not scale.

There is one case where an {% data variables.product.prodname_oauth_app %} is preferred over a {% data variables.product.prodname_github_app %}. If your app needs to access enterprise resources, you should use an {% data variables.product.prodname_oauth_app %} because a {% data variables.product.prodname_github_app %} cannot yet be given permissions against an enterprise.
There is one case where an {% data variables.product.prodname_oauth_app %} is preferred over a {% data variables.product.prodname_github_app %}. If your app needs to access enterprise-level resources such as the enterprise object itself, you should use an {% data variables.product.prodname_oauth_app %} because a {% data variables.product.prodname_github_app %} cannot yet be given permissions against an enterprise. {% data variables.product.prodname_github_app %}s can still access enterprise-owned organization and repository resources.

For more information about {% data variables.product.prodname_github_app %}s, see "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/about-creating-github-apps)."

Expand Down
1 change: 1 addition & 0 deletions content/apps/oauth-apps/building-oauth-apps/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ children:
- /authorizing-oauth-apps
- /scopes-for-oauth-apps
- /creating-a-custom-badge-for-your-oauth-app
- /best-practices-for-creating-an-oauth-app
---

Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ If you follow these best practices it will help you to provide a good customer e
- Apps should include links to user-facing documentation that describe how to set up and use the app.
- Customers should be able to see what type of plan they have in the billing, profile, or account settings section of the app.
- Customers should be able to install and use your app on both a personal account and an organization account. They should be able to view and manage the app on those accounts separately.
- Apps should provide customers with a way to delete their account, without having to email or call a support person. Apps should delete all {% data variables.product.company_short %} user data within 30 days of receiving a request from the user, or within 30 days of the end of the user's legal relationship with {% data variables.product.company_short %}.

## Plan management

Expand All @@ -30,4 +31,5 @@ If you follow these best practices it will help you to provide a good customer e
## Further reading

- "[AUTOTITLE](/apps/creating-github-apps/setting-up-a-github-app/best-practices-for-creating-a-github-app)"
- "[AUTOTITLE](/apps/oauth-apps/building-oauth-apps/best-practices-for-creating-an-oauth-app)"
- "[AUTOTITLE](/apps/publishing-apps-to-github-marketplace/creating-apps-for-github-marketplace/security-best-practices-for-apps)"
Loading