gogoogle-cloud-platformgoogle-cloud-storage

GCP Cloud Run: “missing required GoogleAccessID” when generating V4 Signed URL for Cloud Storage


I have a Go application deployed on Google Cloud Run that needs to generate V4 signed URLs for objects in Google Cloud Storage. Locally, I’m using the Go Storage client and calling:

signedURL, err := storage.SignedURL(bucketName, objectPath, &storage.SignedURLOptions{
    Scheme:  storage.SigningSchemeV4,
    Method:  "GET",
    Expires: time.Now().Add(15 * time.Minute),
})

Everything compiles, but on Cloud Run, I see an error in the logs:

failed to generate signed URL: storage: missing required GoogleAccessID

I also get the same thing running locally with a local service account credentials JSON file, which currently works for uploading images to Cloud Storage. The service account is assigned to my Cloud Run service (I can see it in gcloud run services describe and the console), and I have granted roles/iam.serviceAccountTokenCreator to the same service account at the project level. Additionally, the IAM Credentials API is enabled.

Am I missing something here? enter image description here


Solution

  • Using the storage package's SignedURL function requires you to provide the Service Account's email (GoogleAccessID).

    If, as you should, you're relying on Application Default Credentials, this function requires additional work.

    Generally, it's preferable to create a storage client and then use the SignedURL method on the Bucket.

    package main
    
    import (
        "context"
        "time"
    
        "cloud.google.com/go/storage"
    )
    
    func main() {
        ctx := context.Background()
        client, err := storage.NewClient(ctx)
        if err != nil {
            panic(err)
        }
    
        name := "..."
        object := "..."
    
        opts := &storage.SignedURLOptions{
            Scheme:  storage.SigningSchemeV4,
            Method:  "GET",
            Expires: time.Now().Add(15 * time.Minute),
        }
        signedURL, err := client.Bucket(name).SignedURL(object, opts)
        if err != nil {
            panic(err)
        }
    
        println(signedURL)
    }