Basics of authentication – GitHub Docs

Authenticating as a github app

Authenticating as a GitHub App lets you do a couple of things:

  • You can retrieve high-level management information about your GitHub App.
  • You can request access tokens for an installation of the app.

To authenticate as a GitHub App, generate a private key in PEM format and download it to your local machine. You’ll use this key to sign a JSON Web Token (JWT) and encode it using the RS256 algorithm. GitHub checks that the request is authenticated by verifying the token with the app’s stored public key.

Here’s a quick Ruby script you can use to generate a JWT. Note you’ll have to run gem install jwt before using it.

require'openssl'require'jwt'
private_pem = File.read("YOUR_PATH_TO_PEM")
private_key = OpenSSL::PKey::RSA.new(private_pem)


payload = {
  iat: Time.now.to_i - 60,
  exp: Time.now.to_i   (10 * 60),
  iss:"YOUR_APP_ID"
}

jwt = JWT.encode(payload, private_key, "RS256")
puts jwt

YOUR_PATH_TO_PEM and YOUR_APP_ID are the values you must replace. Make sure to enclose the values in double quotes.

Authenticating as an installation

Authenticating as an installation lets you perform actions in the API for that installation. Before authenticating as an installation, you must create an installation access token. Ensure that you have already installed your GitHub App to at least one repository; it is impossible to create an installation token without a single installation.

By default, installation access tokens are scoped to all the repositories that an installation can access. You can limit the scope of the installation access token to specific repositories by using the repository_ids parameter. See the Create an installation access token for an app endpoint for more details. Installation access tokens have the permissions configured by the GitHub App and expire after one hour.

Похожее:  RESTful Authentication with Flask -

To list the installations for an authenticated app, include the JWT generated above in the Authorization header in the API request:

Bad credentials

Error: Bad credentials

This error means that there is an issue with your stored account credentials.

To troubleshoot, sign out of your account on GitHub Desktop and then sign back in.

Checksum

Identifiable prefixes are great, but let’s go one step further. A checksum virtually eliminates false positives for secret scanning offline. We can check the token input matches the checksum and eliminate fake tokens without having to hit our database.

A 32 bit checksum in the last 6 digits of each token strikes the optimal balance between keeping the random token portion at a consistent entropy and enough confidence in the checksum. We start the implementation with a CRC32 algorithm, a standard checksum algorithm. We then encode the result with a Base62 implementation, using leading zeros for padding as needed.

Deleting private keys

You can remove a lost or compromised private key by deleting it, but you must have at least one private key. When you only have one key, you will need to generate a new one before deleting the old one.
Deleting last private key

Generating a private key

After you create a GitHub App, you’ll need to generate one or more private keys. You’ll use the private key to sign access token requests.

You can create multiple private keys and rotate them to prevent downtime if a key is compromised or lost. To verify that a private key matches a public key, see Verifying private keys.

To generate a private key:

  1. In the upper-right corner of any page, click your profile photo, then click Settings.

    Settings icon in the user bar

  2. In the left sidebar, click Developer settings.

  3. In the left sidebar, click GitHub Apps.
    GitHub Apps section

  4. To the right of the GitHub App you want to modify, click Edit.
    App selection

  5. In “Private keys”, click Generate a private key.
    Generate private key

  6. You will see a private key in PEM format downloaded to your computer. Make sure to store this file because GitHub only stores the public portion of the key.

Note: If you’re using a library that requires a specific file format, the PEM file you download will be in PKCS#1 RSAPrivateKey format.

Handling errors

If the token is invalid, the server will respond with a 401 status and a “bad credentials” message

If the token does not have the required scopes, the server will respond with a 403 status and an explanatory message

New scopes cannot be added to existing tokens, you will have to create a new token with the required scopes selected to address 403 errors.

Identifiable prefixes

As we see across the industry from companies like Slack and Stripe, token prefixes are a clear way to make tokens identifiable. We are including specific 3 letter prefixes to represent each token, starting with a company signifier, gh, and the first letter of the token type. The results are:

Additionally, we want to make these prefixes clearly distinguishable within the token to improve readability. Thus, we are adding a separator: _. An underscore is not a Base64 character which helps ensure that our tokens cannot be accidentally duplicated by randomly generated strings like SHAs.

One other neat thing about _ is it will reliably select the whole token when you double click on it. Other characters we considered are sometimes included in application word separators and thus will stop highlighting at that character. Try out double clicking this-random-text versus this_random_text!

With this prefix alone, we anticipate the false positive rate for secret scanning will be down to 0.5%.⚡

Providing a callback

In server.rb, add a route to specify what the callback should do:

Registering your app

First, you’ll need to register your application. Every
registered OAuth application is assigned a unique Client ID and Client Secret.
The Client Secret should not be shared! That includes checking the string
into your repository.

В случае кражи access токена, refresh куки и fingerprint’а:

Стащить все авторизационные данные это не из легких задач, но все же допустим этот кейс как крайний и наиболее неудобный с точки зрения UX (без примера в кодовой базе supra-api-nodejs).

Предложу несколько вариантов решения данной проблемы:

  1. Хакер воспользовался access token’ом
  2. Закончилось время жизни access token’на
  3. Хакер отправляет refresh куку и fingerprint
  4. Сервер проверяет IP хакера, хакер идет лесом

Зачем все это ? jwt vs cookie sessions

Зачем этот весь геморой ? Почему не юзать старые добрые cookie sessions ? Чем не угодили куки ?

Имплементация:

Front-end:

Back-end:

Ключевой момент:

В момент рефреша то есть обновления access token’a обновляются ОБА токена. Но как же refresh token может сам себя обновить, он ведь создается только после успешной аутентификации ? refresh token в момент рефреша сравнивает себя с тем refresh token’ом который лежит в БД и вслучае успеха, а также если у него не истек срок, система рефрешит токены.

Accessing api endpoints as a github app

For a list of REST API endpoints you can use to get high-level information about a GitHub App, see “GitHub Apps.”

В итоге:

p.s. Каждой задаче свой подход. Юзайте в небольших/средних монолитах cookie sessions и не парьтесь. Ну или на ваш вкус 🙂

Accessing api endpoints as an installation

For a list of REST API endpoints that are available for use by GitHub Apps using an installation access token, see “Available Endpoints.”

For a list of endpoints related to installations, see “Installations.”

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *