This post will show you how to generate application default credentials that you can then use as a secret in your local kubernetes cluster during development. You may have a local kubernetes cluster that you are using for development and you want to do some task within your local pods that require GCP credentials such as reading or writing to a private bucket.
This example assumes you have:
- a local linux dev environment with k8s and helm
- gcloud installed and configured
- Sufficient roles for your user’s IAM account
Let’s get started!
Generate Application Default Credentials:
Application Default Credentials (ADC) are short lived service account tokens that allow you to perform GCP tasks based on your IAM permissions. (Short lived seems to be 1-3 hours.) In the past you may have created a service account json key via the GCP portal and stored the key locally. Generating keys that way should be avoided!!! Those keys are not managed and are a security vulnerability if anyone gets your key.
GCP provides a safer option (which is managed) via Application Default Credentials.
#!/bin/bash
# generate application default credentials
gcloud auth application-default login
This will spawn a browser page to enter your GCP credentials. Once complete, you’ll have a service account json token stored at:
/home/$USER/.config/gcloud/application_default_credentials.json
Create a Kubernetes Secret:
Now let’s create a kubernetes secret so we can use the application default credentials json key generated above.
Assuming you have a local kubernetes cluster running,
# create a namespace -- secrets are only available in the namespace they're created in
NS="example"
echo "Creating namespace $NS..."
kubectl create ns $NS
# delete an existing secret with the same name from previous run
SECRET_NAME="gcp-cred-secret"
echo "attempting to delete secret '$SECRET_NAME' if it exists ..."
kubectl delete secret -n $NS $SECRET_NAME
# create the secret
GCP_ADC_CREDS="/home/$USER/.config/gcloud/application_default_credentials.json"
GCP_ADC_KEY="gcp-sa-creds-json"
echo 'creating secret ...'
kubectl create secret -n $NS generic $SECRET_NAME \
--from-file=$(echo $GCP_ADC_KEY)=$GCP_ADC_CREDS
You can now use kubectl to get and describe the secret:
# list the secrets in the example namespace
kubectl get secrets -n example
# describe the secret
kubectl describe secret gcp-cred-secret -n example
# see the secret contents
kubectl get secret -n example gcp-cred-secret -o jsonpath='{.data}'
Here’s the complete code:
#!/bin/bash
# generate application default credentials
gcloud auth application-default login
# create a namespace -- secrets are only available in the namespace they're created in
NS="example"
echo "Creating namespace $NS..."
kubectl create ns $NS
# delete an existing secret with the same name from previous run
SECRET_NAME="gcp-cred-secret"
echo "attempting to delete secret '$SECRET_NAME' if it exists ..."
kubectl delete secret -n $NS $SECRET_NAME
# create the secret
GCP_ADC_CREDS="/home/$USER/.config/gcloud/application_default_credentials.json"
GCP_ADC_KEY="gcp-sa-creds-json"
echo 'creating secret ...'
kubectl create secret -n $NS generic $SECRET_NAME \
--from-file=$(echo $GCP_ADC_KEY)=$GCP_ADC_CREDS
# list the secrets
kubectl get secrets -n $NS
# describe the secret
kubectl describe secret gcp-cred-secret -n $NS
# see the secret contents
kubectl get secret -n $NS gcp-cred-secret -o jsonpath='{.data}'
In the next section we’ll show how to access the secret within a kubernetes pod via helm.