我们的应用程序数据存储由Google Cloud storage(以及S3和Azure Blob storage)提供支持。我们需要让随机的外部工具访问这个存储(使用CLI工具从本地磁盘上传,从Redshift、Snowflake等分析数据库卸载)。具体的用例是用户需要上传多个大文件(你可以把它想象成流媒体视频的m3u8播放列表——它是m3u8播放列表和数千个小视频文件)。这些工具和用户可能不以任何方式隶属于谷歌(可能没有谷歌帐户)。我们也绝对需要数据直接传输到存储,在我们的服务器之外。
在S3中,我们使用联邦令牌来访问S3桶的一部分。
所以在AWS S3上建模场景:
- 客户请求通过我们的API上传一些数据
- 我们为客户提供S3凭证,范围为
s3://customer/project/uploadId
,允许上传新文件 - 客户端使用任意工具上传数据
- 客户端上传
s3://customer/project/uploadId/file.manifest
,s3://customer/project/uploadId/file.00001
,s3://customer/project/uploadId/file.00002
,…
- 客户端上传
- bucket中的其他数据(无论是其他uploadId还是项目)是安全的,因为给定的凭据范围
在ABS中我们使用STS令牌来达到同样的目的。
GCS似乎没有类似的东西,除了签名url。有签名的url有一个问题,即它们引用的是单个文件。这要么要求我们提前知道有多少文件将被上传(我们不知道),要么客户端需要单独请求每个文件的签名URL(对我们的API造成压力,而且速度很慢)。
ACL似乎是一个解决方案,但它只与谷歌相关的身份相关联。这些东西不能按需快速地创造出来。服务用户也是一个选项,但它们的创建速度很慢,通常不鼓励它们用于此用例IIUC。
是否有一种方法可以创建一个限于CGS桶子集的短期凭据?
理想的情况是,我们在应用程序中使用的服务帐户将能够生成一个短期令牌,该令牌只能访问bucket的一个子集。但这样的事情似乎并不存在。
遗憾的是,没有。对于检索对象,签名url需要用于精确的对象。您需要为每个对象生成一个。
使用*通配符将指定您的目标子目录,并将识别其下的所有对象。例如,如果您试图访问bucket中的Folder1中的对象,您将使用gs://Bucket/Folder1/*
,但下面的命令gsutil signurl -d 120s key.json gs://bucketname/folderName/**
将为bucket中的每个文件创建一个SignedURL,但不会为整个文件夹/子目录
有一个正在进行的特性请求https://issuetracker.google.com/112042863。请在此提出您的关切,并关注进一步的更新。
目前,实现这一目标的一种方法是编写一个小的应用引擎应用程序,他们尝试从而不是直接从GCS下载,GCS将根据你使用的任何机制检查身份验证,然后,如果他们通过,为该资源生成一个签名的URL并重定向用户。参考:https://stackoverflow.com/a/40428142/15803365