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:  Enable the Service Account Credentials API   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')  The bucket exists and there is no typo error 
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.