// Copyright (c) 2022 Gitpod GmbH. All rights reserved. // Licensed under the GNU Affero General Public License (AGPL). // See License.AGPL.txt in the project root for license information. package cmd import ( "context" "fmt" "time" connect "github.com/bufbuild/connect-go" "github.com/gitpod-io/gitpod/common-go/util" "github.com/gitpod-io/gitpod/components/public-api/go/client" v1 "github.com/gitpod-io/gitpod/components/public-api/go/experimental/v1" "github.com/gitpod-io/gitpod/gitpod-cli/pkg/gitpod" supervisor "github.com/gitpod-io/gitpod/supervisor/api" "github.com/spf13/cobra" "golang.org/x/xerrors" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" ) var idpTokenOpts struct { Audience []string } var idpTokenCmd = &cobra.Command{ Use: "token", Short: "Requests an ID token for this workspace", RunE: func(cmd *cobra.Command, args []string) error { cmd.SilenceUsage = true ctx, cancel := context.WithTimeout(cmd.Context(), 5*time.Second) defer cancel() tkn, err := idpToken(ctx, idpTokenOpts.Audience) if err != nil { return err } fmt.Println(tkn) return nil }, } func idpToken(ctx context.Context, audience []string) (idToken string, err error) { wsInfo, err := gitpod.GetWSInfo(ctx) if err != nil { return "", err } supervisorConn, err := grpc.Dial(util.GetSupervisorAddress(), grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return "", xerrors.Errorf("failed connecting to supervisor: %w", err) } defer supervisorConn.Close() clientToken, err := supervisor.NewTokenServiceClient(supervisorConn).GetToken(ctx, &supervisor.GetTokenRequest{ Host: wsInfo.GitpodApi.Host, Kind: "gitpod", Scope: []string{ "function:getWorkspace", }, }) if err != nil { return "", xerrors.Errorf("failed getting token from supervisor: %w", err) } c, err := client.New(client.WithCredentials(clientToken.Token), client.WithURL("https://api."+wsInfo.GitpodApi.Host)) if err != nil { return "", err } tkn, err := c.IdentityProvider.GetIDToken(ctx, &connect.Request[v1.GetIDTokenRequest]{ Msg: &v1.GetIDTokenRequest{ Audience: audience, WorkspaceId: wsInfo.WorkspaceId, }, }) if err != nil { return "", err } return tkn.Msg.Token, nil } func init() { idpCmd.AddCommand(idpTokenCmd) idpTokenCmd.Flags().StringArrayVar(&idpTokenOpts.Audience, "audience", nil, "audience of the ID token") _ = idpTokenCmd.MarkFlagRequired("audience") }