@@ -25,6 +25,7 @@ This library provides a unified interface for obtaining and refreshing credentia
2525 * [ OAuth2 Authorization Code] ( #oauth2-authorization-code-flow-provider )
2626 * [ OAuth2 Client Credentials] ( #oauth2-client-credentials-flow-provider )
2727 * [ Vault Provider] ( #vault-credentials-provider )
28+ * [ GitHub App Provider] ( #github-app-credentials-provider )
2829* [ Channel Behavior] ( #channel-behavior )
2930* [ License] ( #license )
3031* [ Contributing] ( #contributing )
@@ -42,6 +43,7 @@ This library provides a unified interface for obtaining and refreshing credentia
4243- ** OAuth2AC:** Obtains access tokens through OAuth2 authorization code flow and refreshes them before expiration
4344- ** OAuth2CC:** Obtains access tokens through OAuth2 client credentials flow and refreshes them before expiration
4445- ** Vault** Exchanges ID tokens for secrets from Vault using Vault's JWT authentication.
46+ - ** GitHub App:** Mints GitHub App installation access tokens by signing a JWT with the App's private key and refreshes them before expiration.
4547
4648## Installation
4749
@@ -744,6 +746,54 @@ go func() {
744746// wg.Wait()
745747```
746748
749+ ### GitHub App Credentials Provider
750+
751+ ``` go
752+ import (
753+ " os"
754+
755+ " github.com/google/go-github/v66/github"
756+
757+ " go.riptides.io/tokenex/pkg/credential"
758+ " go.riptides.io/tokenex/pkg/githubapp"
759+ )
760+
761+ // Source the App's private key however you like (env var shown; could be a file,
762+ // k8s secret, Vault, etc.) and parse it once.
763+ key , err := githubapp.ParsePrivateKey ([]byte (os.Getenv (" GITHUB_APP_PRIVATE_KEY" )))
764+ if err != nil {
765+ log.Fatalf (" parse private key: %v " , err)
766+ }
767+
768+ provider , err := githubapp.NewCredentialsProvider (ctx, logr.Discard ())
769+ if err != nil {
770+ log.Fatalf (" new provider: %v " , err)
771+ }
772+
773+ credCh , err := provider.GetCredentials (ctx,
774+ githubapp.WithAppID (123456 ),
775+ githubapp.WithInstallationID (7890123 ),
776+ githubapp.WithPrivateKey (key),
777+ // Optional: scope the token to specific repos / permissions.
778+ // githubapp.WithRepositories([]string{"repo-a"}),
779+ // githubapp.WithPermissions(&github.InstallationPermissions{Contents: github.String("read")}),
780+ // Optional: GitHub Enterprise Server.
781+ // githubapp.WithBaseURL("https://github.example.com/api/v3"),
782+ )
783+ if err != nil {
784+ log.Fatalf (" get credentials: %v " , err)
785+ }
786+
787+ for cred := range credCh {
788+ if cred.Err != nil {
789+ log.Printf (" github app token error: %v " , cred.Err )
790+ break
791+ }
792+ tok := cred.Credential .(*credential.Token )
793+ log.Printf (" got installation token, expires %s " , tok.ExpiresAt )
794+ }
795+ ```
796+
747797## Channel Behavior
748798
749799All credential providers in this library follow a consistent pattern for credential delivery:
0 commit comments