Skip to content

[DOCS]: Implementation of GitHub App user authentication token with expiring disabled #517

@saddam-azad

Description

@saddam-azad

Describe the need

Attempting to create a GitHub App user authentication token with expiring disabled. (Sidenote, is it the same as a user-to-server token? The language on docs is not clear.)

  1. We have a Github App

  2. We have Opted-Out of the "User-to-server token expiration" in App Settings > Optional features.

  3. Attempting to generate a non-expiring token using @octokit/auth-app

  4. We tried two approaches to generate a token, using JWT and Installation token as Authentication Objects for the createOAuthUserAuth function.

import * as dotenv from 'dotenv';
import { Octokit } from '@octokit/core';
import { createAppAuth, createOAuthUserAuth } from '@octokit/auth-app';

/**
 * Using Github App (JWT)
 */
export const getTokenUsingJwt = async (service: any, SecretKey: any): Promise<string> => {
    try {
        dotenv.config();
        const appId = process.env.APP_ID as string;
        const privateKey = SecretKey?.SecretString as string;
        const clientId = process.env.CLIENT_ID as string;
        const clientSecret = process.env.CLIENT_SECRET as string;
        const installationId = service.metadata.installation as number;

        // Create a new Octokit instance using App Authentication
        const appAuth = createAppAuth({
            appId: Number(appId),
            privateKey,
        });

        // Authenticate as the GitHub App
        const appAuthentication = await appAuth({
            type: 'app',
        });
        const appAuthenticationToken = appAuthentication.token;
        // console.log('App authentication token', appAuthenticationToken);

        // Create an OAuth user authentication for the specified installation
        const authenticated = createOAuthUserAuth({
            clientType: "github-app",
            clientId,
            clientSecret,
            token: appAuthenticationToken,
        });

        // Get the user-to-server authentication token
        const { token, type, tokenType } = await authenticated();

        return token; // type: token, tokenType: oauth
        
    } catch(error) {
        throw error;
    }
}

/**
 * Using Installation
 */
export const getTokenUsingInstallation = async (service: any, SecretKey: any): Promise<string> => {
    try {
        dotenv.config();
        const appId = process.env.APP_ID as string;
        const privateKey = SecretKey?.SecretString as string;
        const clientId = process.env.CLIENT_ID as string;
        const clientSecret = process.env.CLIENT_SECRET as string;
        const installationId = service.metadata.installation as number;

        // Step 1: Authenticate as your GitHub App using a JWT
        const appAuth = createAppAuth({
            appId: Number(appId),
            privateKey: privateKey,
        });

        // Create an installation access token to act on behalf of the GitHub App installation
        const installationAuthentication = await appAuth({ 
            type: 'installation', 
            installationId 
        });
        const installationAccessToken = installationAuthentication.token;
        // console.log('Installation token', installationAccessToken);

        // Step 2: Create OAuth user-to-server access token using the installation access token
        const authenticated = createOAuthUserAuth({
            clientType: "github-app",
            clientId,
            clientSecret,
            token: installationAccessToken,
        });

        // Get the user-to-server access token
        const { token, type, tokenType } = await authenticated({ type: 'get' });

        return token; // type: token, tokenType: oauth
        
    } catch(error) {
        throw error;
    }
}

JWT approach produces a token such as:
eyJhkGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2OTE2NjkzMDMsImV4cCI6MTY5MTY2OTkwMywiaXNzIjoyNzI1NjZ9.gaUOyjWkbm7NrfhNayPYwK1EzMyeUlEuWTTd7OEpBS91pY6wjCJx_giNOJBzNf0gzMwCyycxtjUCiMU1g6J0xgaYH_2iZxNeoakKYztHxccG8lzBUDCaTwgMBeeFxErlsW02WX8-b8nh0kEr07prYr7mwZFs2i5vEjgJznvk7NU7rzknXBzPeac5DZNq-NO6ikb_BTlMq1z7sW9SXU7xrEM8uHyVvk2KIYvkpwqRvoFBAeWuIIP1UotORxnLqAcLa5AIgOB3vg3Fonhv7d65NfbT9S1A6bfNjXJ25fZvzLoSRgCjTmR1St4MqgsK6O71ThjEk_GELnAm2LEwBt_VuQ

The installation token approach produces a token such as this. However, this expires in 1 hour.
ghs_knjVAQQVgpez6y4x6iBtm1BPkCLTlv33Zryn

Both tokens return tokenType as oauth

The documentation for @octokit/auth-app is not clear on how to disable expiry.

SDK Version

3.388.0

API Version

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type: DocumentationImprovements or additions to documentation

    Type

    No type

    Projects

    Status

    🛑 Blocked/Awaiting Response

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions