添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm hosting a Flask web app on Cloud Run. I'm also using Secret Manager to store Service Account keys. (I previously downloaded a JSON file with the keys)

In my code, I'm accessing the payload then using os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = payload to authenticate. When I deploy the app and try to visit the page, I get an Internal Service Error. Reviewing the logs, I see:

File "/usr/local/lib/python3.10/site-packages/google/auth/_default.py", line 121, in load_credentials_from_file
    raise exceptions.DefaultCredentialsError(
google.auth.exceptions.DefaultCredentialsError: File {"

I can access the secret through gcloud just fine with: gcloud secrets versions access 1 --secret="<secret_id>" while acting as the Service Account.

Here is my Python code:

# Grabbing keys from Secret Manager
def access_secret_version():
    # Create the Secret Manager client.
    client = secretmanager.SecretManagerServiceClient()
    # Build the resource name of the secret version.
    name = "projects/{project_id}/secrets/{secret_id}/versions/1"
    # Access the secret version.
    response = client.access_secret_version(request={"name": name})
    payload = response.payload.data.decode("UTF-8")
    return payload
@app.route('/page/page_two')
def some_random_func():
    # New way
    payload = access_secret_version() # <---- calling the payload
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = payload
    # Old way
    os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "service-account-keys.json"

I'm not technically accessing a JSON file like I was before. The payload variable is storing entire key. Is this why it's not working?

Your approach is incorrect.

When you run on a Google compute service like Cloud Run, the code runs under the identity of the compute service.

In this case, by default, Cloud Run uses the Compute Engine default service account but, it's good practice to create a Service Account for your service and specify it when you deploy it to Cloud Run (see Service accounts).

This mechanism is one of the "legs" of Application Default Credentials when your code is running on Google Cloud, you don't specify the environment variable (you also don't need to create a key) and Cloud Run service acquires the credentials from the Metadata service:

import google.auth
credentials, project_id = google.auth.default()

See google.auth package

It is bad practice to define|set an environment variable within code. By their nature, environment variables should be provided by the environment. Doing this with APPLICATION_DEFAULT_CREDENTIALS means that your code always sets this value when it should only do this when the code is running off Google Cloud.

For completeness, if you need to create Credentials from a JSON string rather than from a file contain a JSON string, you can use from_service_account_info (see google.oauth2.service_account)

Thank you for the explanation. I didn't specify in my post but I'm accessing a BigQuery table from my Cloud Run main.py file which is why I needed the credentials in the first place. Sounds like you are saying that I don't need the keys at all and just need to deploy the code as a service account that has the BigQuery Admin role OR I can add that BigQuery Admin role to the default compute engine service account? – scarecrow Jan 15 at 0:42 That's correct. Sorry for the late reply. The service account can be given whatever I AM roles needed to access services. – DazWilkin Jan 15 at 6:16

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.