在 CloudRun 中创建 V4 签名 URL

Creating V4 Signed URLs in CloudRun

我想从使用 CloudRun 部署的应用程序创建指向 Google 云存储资源的签名 URL。

我按照 this 指南使用具有 GCS 角色的自定义服务帐户设置了 CloudRun。

我的意图是使用 V4 签名从 CloudRun 创建签名 URL。此用例有 a guide,其中文件 service_account.json 用于生成 JWT 配置。当我从 google 的 IAM 下载文件时,这对我在本地主机上有效。我想避免使用我在 CloudRun UI.

中提供的文件在存储库中提交此文件

我希望 CloudRun 将此服务帐户文件注入应用程序容器并使其可在 GOOGLE_APPLICATION_CREDENTIALS 变量中访问,但事实并非如此。

你有关于如何做到这一点的建议吗?谢谢。

Cloud 运行(和其他计算平台)不注入服务帐户密钥文件。相反,他们让 access_tokeninstance metadata service 上可用。然后,您可以使用 JWT 交换此访问令牌。

但是,Google 的客户端库和 gcloud 通常在 GCP 的计算平台上开箱即用,无需明确进行身份验证。因此,如果您使用链接页面上的说明(gcloud 或代码示例),它应该可以正常工作 out-of-the-box.

正如您所说,Golang 存储客户端库需要一个服务帐户 json 文件来签署 url。

目前有一个feature request open in GitHub for this but you should be able to work this around with this sample that I found here:

import (
"context"
  "fmt"
  "time"
  "cloud.google.com/go/storage"
  "cloud.google.com/go/iam/credentials/apiv1"
  credentialspb "google.golang.org/genproto/googleapis/iam/credentials/v1"
)

const (
  bucketName = "bucket-name"
  objectName = "object"
  serviceAccount = "[PROJECTNUMBER]-compute@developer.gserviceaccount.com"
)

func main() {
  ctx := context.Background()

  c, err := credentials.NewIamCredentialsClient(ctx)
  if err != nil {
     panic(err)
  }

  opts := &storage.SignedURLOptions{
     Method: "GET",
     GoogleAccessID: serviceAccount,
     SignBytes: func(b []byte) ([]byte, error) {
        req := &credentialspb.SignBlobRequest{
            Payload: b,
            Name: serviceAccount,
        }
        resp, err := c.SignBlob(ctx, req)
        if err != nil {
           panic(err)
        }
        return resp.SignedBlob, err
     },
     Expires: time.Now().Add(15*time.Minute),
  }

  u, err := storage.SignedURL(bucketName, objectName, opts)
  if err != nil {
     panic(err)
  }

  fmt.Printf("\"%v\"", u)
}