diff --git a/go.mod b/go.mod index f847fee1dd8..91956e1b2a2 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/compose-spec/compose-go v1.20.2 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 github.com/ethereum/go-ethereum v1.13.8 + github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/btree v1.1.2 github.com/google/renameio/v2 v2.0.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 5881b9005f4..c5dcbc1ffa0 100644 --- a/go.sum +++ b/go.sum @@ -240,6 +240,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= diff --git a/tests/bootstrap/jwt/main.go b/tests/bootstrap/jwt/main.go new file mode 100644 index 00000000000..d09c46cda45 --- /dev/null +++ b/tests/bootstrap/jwt/main.go @@ -0,0 +1,56 @@ +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "time" + + "github.com/golang-jwt/jwt/v4" +) + +func main() { + // Define command-line flags + appID := flag.String("app-id", "", "GitHub App App ID") + privateKeyPath := flag.String("private-key-path", "", "Path to the GitHub App private key file") + expiryDuration := flag.Duration("expiry", 10*time.Minute, "JWT expiration duration (e.g., 10m, 1h)") + + // Parse command-line flags + flag.Parse() + + // Validate required flags + if *appID == "" || *privateKeyPath == "" { + log.Fatalf("Both app-id and private-key-path are required") + } + + // Read the private key file + privateKeyData, err := ioutil.ReadFile(*privateKeyPath) + if err != nil { + log.Fatalf("Error reading private key file: %v", err) + } + + // Parse the private key + privateKey, err := jwt.ParseRSAPrivateKeyFromPEM(privateKeyData) + if err != nil { + log.Fatalf("Error parsing private key: %v", err) + } + + // Create the JWT claims + claims := jwt.MapClaims{ + "iat": time.Now().Unix(), // Issued at time + "exp": time.Now().Add(*expiryDuration).Unix(), // JWT expiration time + "iss": *appID, // GitHub App App ID + } + + // Create the JWT + token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + jwtToken, err := token.SignedString(privateKey) + if err != nil { + log.Fatalf("Error signing JWT: %v", err) + + } + + // Output the JWT token + fmt.Print(jwtToken) +}