Reputation: 10349
How can I use the implicit GOOGLE_APPLICATION_CREDENTIALS
environment variable provided to a Cloud Function to sign a Cloud Storage URL?
The following works locally when a GOOGLE_APPLICATION_CREDENTIALS
environment variable exists, but fails with a KeyError
when run inside of a Cloud Function.
google_credentials = service_account.Credentials.from_service_account_file(
os.environ['GOOGLE_APPLICATION_CREDENTIALS']
)
client_email = google_credentials.service_account_email
credential_scope = '{}/auto/storage/goog4_request'.format(datestamp)
credential = '{}/{}'.format(client_email, credential_scope)
# ...
signature = binascii.hexlify(
google_credentials.signer.sign(string_to_sign)
).decode()
The Cloud Function in question will be deployed in multiple environments, so I'd like to avoid having to actually deploy the credentials file -- which does work.
In case it's relevant, I'm using Python 3.7 and basing my solution off of this example.
Upvotes: 1
Views: 1513
Reputation: 114
The GOOGLE_APPLICATION_CREDENTIALS should be no necessary when deploying your function. Please take a look at this [1] in order to see how to handle authenticated requests.
As you may see from [2], the Cloud Storage client libraries may require the IAM (iam.googleapis.com) API and the iam.serviceAccounts.signBlob permission. Even though Cloud Functions have a "default application credential", it (typically) does not include the iam.serviceAccounts.signBlob permission.
As you may see in the documentation, you will also need to make sure your Service Account has the appropriate role. You can also choose which Service Account your function will be using to run.
Please, let me know if this information helps to address your issue.
[1] https://cloud.google.com/functions/docs/writing/http#authentication_and_cors
[2] https://cloud.google.com/functions/docs/writing/http#uploading_files_via_cloud_storage
Upvotes: 2