Skip to content

Commit c20f9a1

Browse files
authored
Merge pull request #8 from sagikazarmark/githubapp
Add support for installation tokens issued using GitHub Apps
2 parents 850e19a + 3e3d236 commit c20f9a1

6 files changed

Lines changed: 861 additions & 129 deletions

File tree

README.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

749799
All credential providers in this library follow a consistent pattern for credential delivery:

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ require (
1515
github.com/aws/aws-sdk-go-v2/service/sts v1.34.0
1616
github.com/go-logr/logr v1.4.3
1717
github.com/golang-jwt/jwt/v5 v5.2.2
18+
github.com/google/go-github/v66 v66.0.0
1819
github.com/openbao/openbao/api/auth/jwt/v2 v2.5.0
1920
github.com/openbao/openbao/api/v2 v2.5.0
2021
github.com/werbenhu/eventbus v1.0.8
@@ -57,6 +58,7 @@ require (
5758
github.com/gogo/protobuf v1.3.2 // indirect
5859
github.com/google/gnostic-models v0.6.9 // indirect
5960
github.com/google/go-cmp v0.7.0 // indirect
61+
github.com/google/go-querystring v1.1.0 // indirect
6062
github.com/google/s2a-go v0.1.9 // indirect
6163
github.com/google/uuid v1.6.0 // indirect
6264
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect

0 commit comments

Comments
 (0)