Im trying to generate signed urls, so i followed the official guide but im getting this error:
google.auth.exceptions.TransportError: Error calling sign_bytes: {'error': {'code': 403, 'message': "Permission 'iam.serviceAccounts.signBlob' denied on resource (or it may not exist).", 'status': 'PERMISSION_DENIED', 'details': [{'@type': 'type.googleapis.com/google.rpc.ErrorInfo', 'reason': 'IAM_PERMISSION_DENIED', 'domain': 'iam.googleapis.com', 'metadata': {'permission': 'iam.serviceAccounts.signBlob'}}]}}
I have done:
Create a Service Account and grant Storage Object User role and Service Account Token Creator role.
Set up authentication for Cloud Storage and Service account impersonation
gcloud auth application-default login --impersonate-service-account=virtu-backend@hip-apricot-446418-f2.iam.gserviceaccount.com
Run the example code
import datetime
from google.cloud import storage
storage_client = storage.Client()
bucket = storage_client.bucket('virtu_users_uploaded_pictures')
blob = bucket.blob('test1')
url = blob.generate_signed_url(
version="v4",
# This URL is valid for 15 minutes
expiration=datetime.timedelta(minutes=15),
# Allow GET requests using this URL.
method="GET",
)
print("Generated GET signed URL:")
print(url)
print("You can use this URL with any user agent, for example:")
print(f"curl '{url}'")
I also checked the assigned permissions of Service Account Token Creator
UPDATE:
I tried a more minimal case:
from google.cloud import storage
storage_client = storage.Client()
bucket = storage_client.bucket('virtu_users_uploaded_pictures')
print(bucket.exists())
And i get this error:
google.auth.exceptions.RefreshError: ('Unable to acquire impersonated credentials', '{\n "error": {\n "code": 403,\n "message": "Permission \'iam.serviceAccounts.getAccessToken\' denied on resource (or it may not exist).",\n "status": "PERMISSION_DENIED",\n "details": [\n {\n "@type": "type.googleapis.com/google.rpc.ErrorInfo",\n "reason": "IAM_PERMISSION_DENIED",\n "domain": "iam.googleapis.com",\n "metadata": {\n "permission": "iam.serviceAccounts.getAccessToken"\n }\n }\n ]\n }\n}\n')
Per the documentation
Service Account Token Creator (roles/iam.serviceAccountTokenCreator): this role is required for generating short-lived credentials for a service account when a private key file is not provided locally. This role should be granted to the principal that will create the signed URL.
This means you have to assign the role to the user (person/human being) who is invoking the call to impersonate the service account from your CLI e.g. if you're the one doing it, then you have to assign it to yourself and not the service account.