Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Creating a GCS Signed URL without a Service Account Key from a GCE instance or a GKE Pod using Workload Identity
package main
import (
"context"
"flag"
"log"
"net/url"
"time"
"cloud.google.com/go/compute/metadata"
credentials "cloud.google.com/go/iam/credentials/apiv1"
"cloud.google.com/go/storage"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
)
func main() {
var bucket string
var object string
var method string
flag.StringVar(&bucket, "bucket", "", "The bucket")
flag.StringVar(&object, "object", "", "The object in the bucket")
flag.StringVar(&method, "method", "GET", "The HTTP method to use")
flag.Parse()
log.Printf("bucket: %v", bucket)
log.Printf("object: %v", object)
log.Printf("method: %v", method)
creds, err := google.FindDefaultCredentials(oauth2.NoContext)
if err != nil {
log.Printf("Error while getting default credentials: %v", err)
return
}
token, err := creds.TokenSource.Token()
if err != nil {
log.Printf("Error while getting token: %v", err)
return
}
accountID, ok := token.Extra("oauth2.google.serviceAccount").(string)
if !ok {
log.Printf("Error while getting account ID: %v", err)
return
}
log.Printf("accountID: %v", accountID)
client, err := google.DefaultClient(oauth2.NoContext)
if err != nil {
log.Printf("Error while getting default client: %v", err)
return
}
computeMetadataClient := metadata.NewClient(client)
email, err := computeMetadataClient.Email(accountID)
if err != nil {
log.Printf("Error while getting email: %v", err)
return
}
log.Printf("email: %v", email)
projectID, err := computeMetadataClient.ProjectID()
if err != nil {
log.Printf("Error while getting project ID: %v", err)
return
}
log.Printf("projectID: %v", projectID)
sc := storage.SignedURLOptions{
GoogleAccessID: email,
Method: method,
Expires: time.Now().Add(60 * time.Second),
ContentType: "",
}
sc.SignBytes = func(payload []byte) ([]byte, error) {
ctx := context.Background()
credsClient, err := credentials.NewIamCredentialsClient(ctx)
if err != nil {
return nil, err
}
req := &credentialspb.SignBlobRequest{
Name: email,
Payload: payload,
}
res, err := credsClient.SignBlob(ctx, req)
if err != nil {
return nil, err
}
return res.SignedBlob, err
}
rawURL, err := storage.SignedURL(bucket, object, &sc)
if err != nil {
log.Printf("Error while generating GCS pre-signed URL: %v", err)
return
}
URL, err := url.Parse(rawURL)
if err != nil {
log.Printf("Error while parsing generated URL: %v", err)
return
}
log.Printf("URL to use with %v method: %v", method, URL)
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment