Application Default Credentials (ADC) supports fetching tokens from the metadata service (Compute Engine, Cloud Run, Cloud Functions, etc). That means that the private key is not available to sign data. In that case, you have two options, provide a service account JSON key or use Google Cloud IAM to sign the request for you.
To use the IAM sign API, the service account must have the IAM role Service Account Token Creator.
The following method supports creating signed URLs when the available credentials (ADC) do not provide the service account private key. Note: Some services do not provide the service account email address. In that case, you must lookup or hardcode the email address.
Example code:
import datetime as dt
from google import auth
from google.cloud import storage
credentials, project = auth.default()
credentials.refresh(auth.transport.requests.Request())
expiration = dt.timedelta(days=1)
client = storage.Client(credentials=credentials)
bucket = storage_client.get_bucket("bucketName")
blob = bucket.get_blob("blobName")
signed_url = blob.generate_signed_url(
expiration=expiration,
service_account_email=credentials.service_account_email,
access_token=credentials.token
)
You can specify the HTTP method and content type:
signed_url = blob.generate_signed_url(
expiration=expiration,
service_account_email=credentials.service_account_email,
access_token=credentials.token,
method="PUT",
content_type="application/octet-stream"
)
If you get an IAM permissions error, double-check the IAM roles assigned to the service account used for ADC.
Also, see this answer by @guillaume-blaquiere