GitHub - jferrl/go-githubauth: Go package that provides utilities for GitHub authentication (original) (raw)

go-githubauth

GoDoc Test Status codecov Go Report Card Mentioned in Awesome Go

go-githubauth is a Go package that provides utilities for GitHub authentication, including generating and using GitHub App tokens, installation tokens, and personal access tokens.

v1.5.0 removes the go-github dependency, implementing a lightweight internal GitHub API client. This reduces external dependencies while maintaining full compatibility with the OAuth2 token source interface.


Found this package useful? Give it a star on GitHub! Your support helps others discover this project and motivates continued development.

Star this repo

Share this project: Share on X Share on Reddit


Features

go-githubauth package provides implementations of the TokenSource interface from the golang.org/x/oauth2 package. This interface has a single method, Token, which returns an *oauth2.Token.

v1.5.0 Features

Core Capabilities

Requirements

Installation

To use go-githubauth in your project, you need to have Go installed. You can get the package via:

go get -u github.com/jferrl/go-githubauth

Usage

Usage with oauth2

You can use this package standalone with any HTTP client, or integrate it with the go-github SDK if you need additional GitHub API functionality.

package main

import ( "context" "fmt" "os" "strconv"

"github.com/google/go-github/v76/github" "github.com/jferrl/go-githubauth" "golang.org/x/oauth2" )

func main() { privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY")) clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef" installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)

// Go automatically infers the type as string for Client ID appTokenSource, err := githubauth.NewApplicationTokenSource(clientID, privateKey) if err != nil { fmt.Println("Error creating application token source:", err) return }

installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)

// oauth2.NewClient creates a new http.Client that adds an Authorization header with the token httpClient := oauth2.NewClient(context.Background(), installationTokenSource) githubClient := github.NewClient(httpClient)

_, _, err = githubClient.PullRequests.CreateComment(context.Background(), "owner", "repo", 1, &github.PullRequestComment{ Body: github.String("Awesome comment!"), }) if err != nil { fmt.Println("Error creating comment:", err) return } }

App ID (Legacy)

package main

import ( "context" "fmt" "os" "strconv"

"github.com/google/go-github/v76/github" "github.com/jferrl/go-githubauth" "golang.org/x/oauth2" )

func main() { privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY")) appID, _ := strconv.ParseInt(os.Getenv("GITHUB_APP_ID"), 10, 64) installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)

// Explicitly cast to int64 for App ID - Go automatically infers the type appTokenSource, err := githubauth.NewApplicationTokenSource(int64(appID), privateKey) if err != nil { fmt.Println("Error creating application token source:", err) return }

installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)

httpClient := oauth2.NewClient(context.Background(), installationTokenSource) githubClient := github.NewClient(httpClient)

_, _, err = githubClient.PullRequests.CreateComment(context.Background(), "owner", "repo", 1, &github.PullRequestComment{ Body: github.String("Awesome comment!"), }) if err != nil { fmt.Println("Error creating comment:", err) return } }

Generate GitHub Application Token

First, create a GitHub App and generate a private key. To authenticate as a GitHub App, you need to generate a JWT. Generating a JWT for a GitHub App

package main

import ( "fmt" "os" "time"

"github.com/jferrl/go-githubauth" )

func main() { privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY")) clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef"

// Type automatically inferred as string tokenSource, err := githubauth.NewApplicationTokenSource( clientID, privateKey, githubauth.WithApplicationTokenExpiration(5*time.Minute), ) if err != nil { fmt.Println("Error creating token source:", err) return }

token, err := tokenSource.Token() if err != nil { fmt.Println("Error generating token:", err) return }

fmt.Println("Generated JWT token:", token.AccessToken) }

With App ID

package main

import ( "fmt" "os" "strconv" "time"

"github.com/jferrl/go-githubauth" )

func main() { privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY")) appID, _ := strconv.ParseInt(os.Getenv("GITHUB_APP_ID"), 10, 64)

// Type automatically inferred as int64 tokenSource, err := githubauth.NewApplicationTokenSource( int64(appID), privateKey, githubauth.WithApplicationTokenExpiration(5*time.Minute), ) if err != nil { fmt.Println("Error creating token source:", err) return }

token, err := tokenSource.Token() if err != nil { fmt.Println("Error generating token:", err) return }

fmt.Println("Generated JWT token:", token.AccessToken) }

Generate GitHub App Installation Token

To authenticate as a GitHub App installation, you need to obtain an installation token using your GitHub App JWT.

package main

import ( "fmt" "os" "strconv"

"github.com/jferrl/go-githubauth" )

func main() { privateKey := []byte(os.Getenv("GITHUB_APP_PRIVATE_KEY")) clientID := os.Getenv("GITHUB_APP_CLIENT_ID") // e.g., "Iv1.1234567890abcdef" installationID, _ := strconv.ParseInt(os.Getenv("GITHUB_INSTALLATION_ID"), 10, 64)

// Create GitHub App JWT token source with Client ID appTokenSource, err := githubauth.NewApplicationTokenSource(clientID, privateKey) if err != nil { fmt.Println("Error creating application token source:", err) return }

// Create installation token source using the app token source installationTokenSource := githubauth.NewInstallationTokenSource(installationID, appTokenSource)

token, err := installationTokenSource.Token() if err != nil { fmt.Println("Error generating installation token:", err) return }

fmt.Println("Generated installation token:", token.AccessToken) }

Personal Access Token Authentication

GitHub Personal Access Tokens provide direct authentication for users and organizations. This package supports both classic personal access tokens and fine-grained personal access tokens.

Using Personal Access Tokens

With oauth2 Client (Standalone)

package main

import ( "context" "fmt" "io" "net/http" "os"

"github.com/jferrl/go-githubauth" "golang.org/x/oauth2" )

func main() { // Personal access token from environment variable token := os.Getenv("GITHUB_TOKEN") // e.g., "ghp_..." or "github_pat_..."

// Create token source tokenSource := githubauth.NewPersonalAccessTokenSource(token)

// Create HTTP client with OAuth2 transport httpClient := oauth2.NewClient(context.Background(), tokenSource)

// Use the HTTP client for GitHub API calls resp, err := httpClient.Get("https://api.github.com/user") if err != nil { fmt.Println("Error getting user:", err) return } defer resp.Body.Close()

body, _ := io.ReadAll(resp.Body) fmt.Printf("User info: %s\n", body) }

With go-github SDK (Optional)

package main

import ( "context" "fmt" "os"

"github.com/google/go-github/v76/github" "github.com/jferrl/go-githubauth" "golang.org/x/oauth2" )

func main() { // Personal access token from environment variable token := os.Getenv("GITHUB_TOKEN") // e.g., "ghp_..." or "github_pat_..."

// Create token source tokenSource := githubauth.NewPersonalAccessTokenSource(token)

// Create HTTP client with OAuth2 transport httpClient := oauth2.NewClient(context.Background(), tokenSource) githubClient := github.NewClient(httpClient)

// Use the GitHub client for API calls user, _, err := githubClient.Users.Get(context.Background(), "") if err != nil { fmt.Println("Error getting user:", err) return }

fmt.Printf("Authenticated as: %s\n", user.GetLogin()) }

Creating Personal Access Tokens

  1. Classic Personal Access Token: Visit GitHub Settings > Developer settings > Personal access tokens > Tokens (classic)
  2. Fine-grained Personal Access Token: Visit GitHub Settings > Developer settings > Personal access tokens > Fine-grained tokens

🔐 Security Note: Store your personal access tokens securely and never commit them to version control. Use environment variables or secure credential management systems.

Contributing

Contributions are welcome! Please open an issue or submit a pull request on GitHub.

License

This project is licensed under the MIT License. See the LICENSE file for details.