Where to securely store Google_Application_Credentials in Django project?
Question:
I have a Django project that uses the Google API. I created a docker-compose.yml which has my Django container and Nginx container. It builds successfully but when I run docker-compose up, I get following error:
google.auth.exceptions.DefaultCredentialsError: File /file/path/credentials.json was not found.
I have installed the Google SDK and ran ‘gcloud auth application-default login’ which creates the json file in my root directory. I then created an environment variable for it and configured my Django app.
settings.py:
GOOGLE_APPLICATION_CREDENTIALS = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
I can open the credentials json file in my finder so I know it’s there.
The Google API is being used for secret manager to retrive secret keys:
from google.cloud import secretmanager
import environ
env = environ.Env()
environ.Env.read_env()
def get_secret(secret_id, version_id="latest"):
project_id = env("GOOGLE_PROJECT_ID")
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(name=name)
return response.payload.data.decode("UTF-8")
Without running docker-compose up it works fine and I can retrieve keys but I want to test it out running my docker containers.
My docker-compose.yml:
version: '3'
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
env_file:
- ./backend/.env
container_name: backend
ports:
- 8000:8000
nginx:
build:
context: ./nginx
dockerfile: ./Dockerfile
container_name: nginx
ports:
- 80:80
depends_on:
- backend
I even tried downloading the service account key which places it in my downloads folder
When I move the file into the django project, it can ready it but from my understanding, you should’t have the credentials file in the source code. So where should I store the credentials for this to work securely?
Answers:
There are two steps here you’re missing to use a local service account in the container without actually storing it there or adding it to your git repo:
I’ll speak in generalities and then you can add these to your docker-compose.yml
:
Where Should The Google Services Look
The environment variable GOOGLE_APPLICATION_CREDENTIALS
tells the Google services where it should look for a service account in the container. So in your service, set an environment variable with an absolute path in the container where these Google services should look:
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/application_default_credentials.json
env_file:
- ./backend/.env
Mapping From Your Local Machine
Because you don’t want to store the service account in your repo, you need to set up a volume
in your docker-compose.yml
that maps the above GOOGLE_APPLICATION_CREDENTIALS
to the service account on your local machine. If you have your service account at /jdez/Downloads/service-account.json
, you’ll set up your volume like this:
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/application_default_credentials.json
env_file:
- ./backend/.env
volumes:
- /jdez/Downloads/service-account.json:/tmp/keys/application_default_credentials.json
Now when the Google services look for the file at GOOGLE_APPLICATION_CREDENTIALS
, they’ll read the one in your Downloads
directory.
Because you’re using a service account, you don’t even need to run gcloud
unless you need it for other things.
I have a Django project that uses the Google API. I created a docker-compose.yml which has my Django container and Nginx container. It builds successfully but when I run docker-compose up, I get following error:
google.auth.exceptions.DefaultCredentialsError: File /file/path/credentials.json was not found.
I have installed the Google SDK and ran ‘gcloud auth application-default login’ which creates the json file in my root directory. I then created an environment variable for it and configured my Django app.
settings.py:
GOOGLE_APPLICATION_CREDENTIALS = os.environ["GOOGLE_APPLICATION_CREDENTIALS"]
I can open the credentials json file in my finder so I know it’s there.
The Google API is being used for secret manager to retrive secret keys:
from google.cloud import secretmanager
import environ
env = environ.Env()
environ.Env.read_env()
def get_secret(secret_id, version_id="latest"):
project_id = env("GOOGLE_PROJECT_ID")
client = secretmanager.SecretManagerServiceClient()
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
response = client.access_secret_version(name=name)
return response.payload.data.decode("UTF-8")
Without running docker-compose up it works fine and I can retrieve keys but I want to test it out running my docker containers.
My docker-compose.yml:
version: '3'
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
env_file:
- ./backend/.env
container_name: backend
ports:
- 8000:8000
nginx:
build:
context: ./nginx
dockerfile: ./Dockerfile
container_name: nginx
ports:
- 80:80
depends_on:
- backend
I even tried downloading the service account key which places it in my downloads folder
When I move the file into the django project, it can ready it but from my understanding, you should’t have the credentials file in the source code. So where should I store the credentials for this to work securely?
There are two steps here you’re missing to use a local service account in the container without actually storing it there or adding it to your git repo:
I’ll speak in generalities and then you can add these to your docker-compose.yml
:
Where Should The Google Services Look
The environment variable GOOGLE_APPLICATION_CREDENTIALS
tells the Google services where it should look for a service account in the container. So in your service, set an environment variable with an absolute path in the container where these Google services should look:
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/application_default_credentials.json
env_file:
- ./backend/.env
Mapping From Your Local Machine
Because you don’t want to store the service account in your repo, you need to set up a volume
in your docker-compose.yml
that maps the above GOOGLE_APPLICATION_CREDENTIALS
to the service account on your local machine. If you have your service account at /jdez/Downloads/service-account.json
, you’ll set up your volume like this:
services:
backend:
build:
context: ./
dockerfile: ./Dockerfile
environment:
GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/application_default_credentials.json
env_file:
- ./backend/.env
volumes:
- /jdez/Downloads/service-account.json:/tmp/keys/application_default_credentials.json
Now when the Google services look for the file at GOOGLE_APPLICATION_CREDENTIALS
, they’ll read the one in your Downloads
directory.
Because you’re using a service account, you don’t even need to run gcloud
unless you need it for other things.