Search code examples
djangogoogle-app-enginegoogle-app-engine-pythongoogle-cloud-buildsecret-key

Secrets in a Django app on Google AppEngine (GAE)


I'm trying to develop a Django app on GAE, and using CloudBuild for CI/CD. I'm wondering what's the best way to pass secrets to my app (DB credentials, etc).

I was able to follow instructions at https://cloud.google.com/cloud-build/docs/securing-builds/use-encrypted-secrets-credentials to read the secret from in my build step, and pass it in to my app as an environment variable. It's a bit hacky, but it works:

  - name: gcr.io/cloud-builders/gcloud
    entrypoint: 'bash'
    args:
    - '-c'
    - |
      TEST_PW=$(gcloud secrets versions access latest --secret=test-key)
      echo "TEST_PASSWORD=$${TEST_PW}" >> env_vars
      unset TEST_PW

However, I'm not sure if this practice is safe. I dumped the env variables in running in my app (using print(dict(os.environ)) and the only sensitive values there are the secrets I passed in (all other GAE app related values are non-sensitive data).

So questions:

1) Is storing secrets in env variables safe in an app in AppEngine, i.e. can they be stolen by "somehow" dumping them through print(dict(os.environ))?

2) Or is the better option to fetch them from Secret Manager in Django (for e.g. in settings.py)? (I'm worried about restarts or version switches here, and if they'll affect this option)

3) Or is there an even better option?

Thanks.


Solution

  • The security issue with what you are doing is not the environment variable itself, but the fact that you are storing the secret's plain decrypted value in it, making it accessible by the os.environ command while your instance is running.

    A simpler solution would be to dump that sensitive information to a file and store it on a Cloud Storage Bucket only your app engine's service account has access to, like this:

    TEST_PW=$(gcloud secrets versions access latest --secret=test-key)
    echo "TEST_PASSWORD=$${TEST_PW}" >> [YOUR_FILE_URL]
    unset TEST_PW
    

    If you want to keep using environment variables, you can do it by using Cloud KMS to keep data encrypted, you can find a how to here, which is a different section of the same documentation you shared on your question.