When automating Google Cloud operations on servers, we often need gcloud
CLI to authenticate using service accounts without interactive login. While client libraries respect GOOGLE_APPLICATION_CREDENTIALS
, the gcloud CLI requires different handling.
The standard method gcloud auth activate-service-account
creates credential files in ~/.config/gcloud
, which isn't ideal for:
- Containerized environments
- CI/CD pipelines
- Temporary automation tasks
Use this one-liner to authenticate per-command without leaving credential traces:
export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=$GOOGLE_APPLICATION_CREDENTIALS \
&& gcloud [COMMAND] \
&& unset CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
For a server health check script verifying Pub/Sub access:
#!/bin/bash
# Validate credentials before application starts
export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=$GOOGLE_APPLICATION_CREDENTIALS
if ! gcloud pubsub topics list --format="value(name)" | grep -q "projects/my-project/topics/test"; then
echo "Pub/Sub access validation failed" >&2
exit 1
fi
unset CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE
For scripts requiring multiple gcloud calls, temporarily modify the active account:
TEMP_ACCOUNT="temp-$(date +%s)"
gcloud auth activate-service-account --key-file=$GOOGLE_APPLICATION_CREDENTIALS --project=my-project --quiet
gcloud config set account $(jq -r .client_email $GOOGLE_APPLICATION_CREDENTIALS)
# Your commands here...
# Cleanup
gcloud config unset account
gcloud auth revoke $TEMP_ACCOUNT --quiet
- Always unset environment variables after use
- Prefer short-lived credentials in automation
- Audit service account permissions regularly
When automating Google Cloud Platform (GCP) operations on servers, we often need to execute gcloud
commands non-interactively using service accounts. While client libraries automatically respect the GOOGLE_APPLICATION_CREDENTIALS
environment variable, the gcloud CLI doesn't, creating a frustrating disconnect in automation workflows.
The gcloud CLI maintains its own credential store in ~/.config/gcloud
, separate from the standard GCP authentication flow. This design decision means:
- Environment variables won't affect gcloud authentication
- Credentials get written to disk when using
gcloud auth activate-service-account
- No built-in way to authenticate purely through environment variables
Here are three approaches to solve this elegantly:
1. Temporary Credential Activation
For one-off commands, activate the service account temporarily in a subshell:
(export CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=$GOOGLE_APPLICATION_CREDENTIALS \
&& gcloud pubsub topics publish testtopic --message="hello")
2. Configuration Directory Redirection
For scripts needing multiple commands, redirect the config directory to a temp location:
#!/bin/bash
TMP_GCLOUD_CONFIG=$(mktemp -d)
cleanup() {
rm -rf "$TMP_GCLOUD_CONFIG"
}
trap cleanup EXIT
export CLOUDSDK_CONFIG="$TMP_GCLOUD_CONFIG"
gcloud auth activate-service-account --key-file="$GOOGLE_APPLICATION_CREDENTIALS"
# Your gcloud commands here
gcloud pubsub topics list
gcloud compute instances list
3. Using Docker for Isolation
For maximum isolation, use the official gcloud container with your credentials mounted:
docker run --rm \
-v "$GOOGLE_APPLICATION_CREDENTIALS:/tmp/key.json" \
-e CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE=/tmp/key.json \
gcr.io/google.com/cloudsdktool/cloud-sdk \
gcloud pubsub topics list
Always verify your authentication setup works before relying on it in production:
# Test service account permissions
gcloud auth list
gcloud projects get-iam-policy $(gcloud config get-value project) \
--flatten="bindings[].members" \
--format="table(bindings.role)" \
--filter="bindings.members:$(gcloud config get-value account)"
Key security considerations:
- Set strict permissions (600) on credential files
- Prefer short-lived credentials when possible
- Rotate service account keys regularly