This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Mar 31, 2026. It is now read-only.
Impossible to use signed url v4 and the Service Account Credential APIs #355
Copy link
Copy link
Closed
Labels
api: storageIssues related to the googleapis/python-storage API.Issues related to the googleapis/python-storage API.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Description
Months ago, I solved an issue to a Stack overflow user by explaining how to generate a signed URL without a service account JSON fey file. I also release an article on this
Today, a comment of a user told me that is doesn't work. They open a new Stack Overflow question and in their question, there is the v4 mentioned.
I dug into the code and yes, the v2 and the v4 haven't the same behavior: the v4 check if the credential can generate a signed URL by itself, that implies the useless check later that allows to use Service Account Credential API, instead of the service account private key to generate the signature.
Environment details
- Linux (Cloud Function and Cloud Run)
- Python version:
python --version3.7 and 3.8 google-cloud-storageversion: latest (1.35.0)
Steps to reproduce
- Working code on Cloud Run (for example) Replace YOUR_BUCKET by a valid bucket
import os
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def sign_url():
from google.cloud import storage
from datetime import datetime, timedelta
import google.auth
credentials, project_id = google.auth.default()
# Perform a refresh request to get the access token of the current credentials (Else, it's None)
from google.auth.transport import requests
r = requests.Request()
credentials.refresh(r)
client = storage.Client()
bucket = client.get_bucket('YOUR_BUCKET')
blob = bucket.get_blob('name.csv')
service_account_email = credentials.service_account_email
url = blob.generate_signed_url(service_account_email=service_account_email, access_token=credentials.token,version="v2", method="PUT",expiration=timedelta(minutes=120),content_type="application/octet-stream")
return url, 200
if __name__ == "__main__":
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
- Broken code on Cloud Run (for example) Replace YOUR_BUCKET by a valid bucket
import os
from flask import Flask, request
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def sign_url():
from google.cloud import storage
from datetime import datetime, timedelta
import google.auth
credentials, project_id = google.auth.default()
# Perform a refresh request to get the access token of the current credentials (Else, it's None)
from google.auth.transport import requests
r = requests.Request()
credentials.refresh(r)
client = storage.Client()
bucket = client.get_bucket('YOUR_BUCKET')
blob = bucket.get_blob('name.csv')
service_account_email = credentials.service_account_email
url = blob.generate_signed_url(service_account_email=service_account_email, access_token=credentials.token,version="v4", method="PUT",expiration=timedelta(minutes=120),content_type="application/octet-stream")
return url, 200
if __name__ == "__main__":
app.run(host='0.0.0.0', port=int(os.environ.get('PORT', 8080)))
Only the version (v2/v4) has changed
Fix proposal is coming.
Reacted by Igor, Patrik Palmér, nicce, Maikel Ruiz, Rishabh, Lee B. Smith and Nikita Matatov
Reacted by cajoek
Metadata
Metadata
Assignees
Labels
api: storageIssues related to the googleapis/python-storage API.Issues related to the googleapis/python-storage API.priority: p2Moderately-important priority. Fix may not be included in next release.Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Activity
nagro-c commentedon Jan 19, 2021
I'm facing the same issue on cloud function env, and getting the error below:
deepamgupta commentedon Sep 1, 2021
@guillaumeblaquiere
after applying the fix provided by you, I am getting this exception
<class 'google.auth.exceptions.RefreshError'>, RefreshError('invalid_scope: Invalid OAuth scope or ID token audience provided.', '{"error":"invalid_scope","error_description":"Invalid OAuth scope or ID token audience provided."}'), <traceback object at 0x7f4d783cc680>at the line
credentials.refresh(r)Any idea?
guillaumeblaquiere commentedon Sep 1, 2021
@deepamgupta can you describe your runtime context? Is it on your workstation? On Compute Engine? elsewhere?
deepamgupta commentedon Sep 1, 2021
@guillaumeblaquiere Currently I am working on my Laptop. Using Pycharm debugger to run a flask application.
marcusbevans commentedon Mar 7, 2023
I ran into the same problem trying to run a simple FastAPI app on Cloud Run just today. Just an FYI that the problem still exists.
Also, thank you for your article. It allowed me to build the work around.
carlthome commentedon Mar 21, 2023
Same issue here with v4 and FastAPI.