Orchestrating Google Application Credentials within GitHub Actions

The integration of Google Cloud Platform (GCP) and GitHub Actions necessitates a robust, secure, and scalable method for handling authentication. At the heart of this interaction lies the GOOGLE_APPLICATION_CREDENTIALS environment variable, a critical configuration point that allows Google Cloud SDKs and client libraries to locate the necessary credentials to authenticate requests. When operating within the ephemeral environment of a GitHub Actions runner, managing these credentials requires a precise understanding of how the google-github-actions/auth action interacts with the underlying filesystem and environment variables. The primary objective of this mechanism is to establish Application Default Credentials (ADC), which are the standard way for Google Cloud client libraries to automatically discover credentials without requiring manual paths to be hardcoded into the application logic. By leveraging the google-github-actions/auth action, developers can transition from risky, long-lived Service Account JSON keys to more secure, short-lived tokens, specifically through the implementation of Workload Identity Federation (WIF).

Architectural Mechanisms of the Authentication Action

The google-github-actions/auth action serves as the primary gateway for establishing identity between a GitHub runner and Google Cloud. Its primary function is to generate a credentials file containing short-lived credentials and subsequently export the path to this file via the GOOGLE_APPLICATION_CREDENTIALS environment variable.

The action operates by creating a JSON file in the $GITHUB_WORKSPACE directory. This specific location is chosen because it is accessible to all subsequent steps in the workflow. Because these credentials are short-lived, the security risk is significantly reduced compared to traditional service account keys; the file is automatically deleted by a post-action once the job finishes, ensuring that no sensitive material persists on the runner's disk beyond the lifecycle of the execution.

For this process to function correctly, the actions/checkout@v4 step must be executed before the auth action. This requirement exists because of how GitHub Actions initializes the $GITHUB_WORKSPACE directory. If the checkout step is omitted or placed after the authentication step, future steps in the pipeline will be unable to authenticate because the workspace context required to store and locate the credentials file was not properly established.

Deep Dive into Authentication Strategies

There are three primary methods available for authenticating to Google Cloud within a GitHub Actions environment, each with different security implications and operational overhead.

Workload Identity Federation (Preferred)

Workload Identity Federation (WIF) is the gold standard for modern CI/CD security. It eliminates the need to store long-lived Service Account JSON keys as GitHub Secrets, which are prone to leakage and require manual rotation. Instead, WIF establishes a trust relationship between the GitHub OIDC (OpenID Connect) provider and the Google Cloud Workload Identity Pool.

When a workflow runs, GitHub provides a signed OIDC token. The google-github-actions/auth action exchanges this token for a short-lived Google Cloud access token. This process is known as trust delegation, where the identity of the GitHub workflow invocation is mapped directly to permissions on Google Cloud.

Workload Identity Federation through a Service Account

In certain scenarios, users may need to impersonate a specific service account to gain precise IAM permissions while still utilizing the security benefits of WIF. In this flow, WIF is used to authenticate the initial request, which then grants the permission to act as a specific service account. This is particularly useful for maintaining the principle of least privilege, as the WIF pool can be configured to only allow the assumption of a very specific service account designated for a particular task, such as writing to a registry.

Service Account Key JSON

This is the legacy method involving the upload of a .json key file to GitHub Secrets. While functional, it is discouraged because the keys are long-lived and represent a significant security liability if the secret is ever exposed.

Detailed Analysis of Action Configuration and Environment Variables

The google-github-actions/auth action provides several optional parameters that dictate how credentials and environment variables are handled.

The createcredentialsfile Parameter

If the create_credentials_file parameter is set to true (which is the default), the action generates a physical JSON file in the $GITHUB_WORKSPACE. This file is essential for tools that require a physical file path to authenticate via the Google Cloud SDK or gcloud CLI.

The impact of this setting is that it enables the use of these credentials in Docker-based GitHub Actions. Since Docker containers run in a separate filesystem from the runner, the credentials file must be explicitly mounted into the container to be usable.

The exportenvironmentvariables Parameter

When export_environment_variables is set to true, the action populates a wide array of environment variables used by various downstream libraries.

The variables exported include:

  • CLOUDSDK_PROJECT
  • CLOUDSDK_CORE_PROJECT
  • GCP_PROJECT
  • GCLOUD_PROJECT
  • GOOGLE_CLOUD_PROJECT

Additionally, if create_credentials_file is also enabled, the following specific variables are exported:

  • GOOGLE_APPLICATION_CREDENTIALS: The path to the generated JSON key.
  • GOOGLE_GHA_CREDS_PATH: The internal path used by the action.
  • CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE: Used to force the Cloud SDK to use the specific generated file.

If export_environment_variables is set to false, no environment variables are exported, which effectively means that any subsequent steps will fail to authenticate unless the user manually provides credentials.

Integration with Docker Containers

A common technical challenge arises when attempting to use Google Cloud resources inside a Docker container during a CI run (e.g., for integration testing with Redis or Postgres). Because the google-github-actions/auth action creates the credentials file on the host runner, the container does not have inherent access to these credentials.

To resolve this, the credentials file must be mounted as a volume. The following implementation demonstrates how to mount the file generated by the auth action into a container:

bash docker run --rm --volume "${{ steps.gcp-auth.outputs.credentials_file_path { } }}":/gcp/creds.json:ro \ --env GOOGLE_APPLICATION_CREDENTIALS=/gcp/creds.json ${{ env.DOCKER_IMAGE }}:${{ env.TEST_TAG }} pytest

In this configuration:
- The output credentials_file_path from the auth action is mapped to /gcp/creds.json inside the container.
- The :ro flag ensures the credentials are read-only.
- The GOOGLE_APPLICATION_CREDENTIALS environment variable is set inside the container to point to the mounted path.

Artifact Registry and Docker Authentication

Authenticating to the Google Artifact Registry requires a specific approach because the registry does not support identity federation directly for the docker login command. An intermediate service account is required to generate an access token.

For example, a service account named github-actions-registry-writer can be created via the following command:

bash gcloud iam service-accounts create github-actions-registry-writer --display-name "GitHub Actions writing to Artifact Registry"

Once the service account is created, the workflow uses the auth action with the token_format: "access_token" input. This allows the docker/login-action to use the generated access token as a password.

The configuration for the authentication step in this context is as follows:

yaml - name: Authenticate to Google Cloud with Service Account id: gcp-auth-with-service-account uses: "google-github-actions/auth@v2" with: token_format: "access_token" project_id: "auth-in-various-contexts" workload_identity_provider: "projects/1067231456173/locations/global/workloadIdentityPools/github-wif-pool/providers/github-wif" service_account: "github-actions-registry-writer@auth-in-various-contexts.iam.gserviceaccount.com"

The subsequent login to the registry is then performed using the oauth2accesstoken username and the access_token output:

yaml - name: Login to Docker Hub uses: docker/login-action@v3 with: registry: europe-west4-docker.pkg.dev username: "oauth2accesstoken" password: "${{ steps.gcp-auth-with-service-account.outputs.access_token }}"

Specialized Connectivity: GKE and Connect Gateway

For Kubernetes deployments, the google-github-actions/get-gke-credentials@v3 action is used to configure kubectl. This action automatically detects Application Default Credentials (ADC) created by the auth action.

A significant challenge occurs when using GitHub-hosted runners to connect to private GKE clusters. Since the runners are in a public environment, they lack direct network connectivity to the private cluster endpoints. To bypass this, the Connect gateway feature of Fleets can be utilized.

The implementation for a private cluster connection is as follows:

yaml - id: 'get-credentials' uses: 'google-github-actions/get-gke-credentials@v3' with: cluster_name: 'my-private-cluster' location: 'us-central1-a' use_connect_gateway: 'true'

By setting use_connect_gateway: 'true', the action routes the connection through the Google Cloud Connect gateway, enabling secure access without requiring a VPN or complex firewall rules.

Troubleshooting and Known Issues

Despite the robustness of the auth action, certain edge cases and tool-specific behaviors can cause authentication failures.

The Nextflow Authentication Bug

A known issue has been reported (e.g., in Nextflow issue #6612) where the google-batch executor fails to recognize the credentials file generated by google-github-actions/auth@v3, resulting in an "Invalid or corrupted Google credentials file" error. This typically happens when the tool does not correctly parse the JSON format generated by the action or fails to locate it in the runner's home directory.

The recommended workaround for this specific failure involves a manual re-authentication step to refresh the Application Default Credentials (ADC) and then unsetting the environment variable to prevent conflicts:

bash gcloud auth login --quiet --cred-file=$GOOGLE_APPLICATION_CREDENTIALS --update-adc echo "GOOGLE_APPLICATION_CREDENTIALS=" >> $GITHUB_ENV

The gsutil Limitation

It is critical to note that the gsutil command does not utilize the credentials exported by the google-github-actions/auth action. Users attempting to interact with Cloud Storage must migrate from gsutil to the gcloud storage command suite to ensure that the exported credentials are correctly applied.

Operational Specifications and Best Practices

The google-github-actions/auth action runs using Node 24. To maintain a secure environment, developers must ensure that generated credentials do not leak into build artifacts.

Preventing Credential Leakage

Because the action generates files matching the pattern gha-creds-*.json in the workspace, these files could accidentally be bundled into a Docker image or a release zip file if the workspace is copied. To prevent this, the following patterns must be added to .gitignore and .dockerignore files:

```text

Ignore generated credentials from google-github-actions/auth gha-creds-*.json

gha-creds-*.json
```

Comparison of Authentication Methods

Feature Service Account Key JSON WIF Direct WIF via Service Account
Credential Lifespan Long-lived (Permanent) Short-lived Short-lived
Secret Management Required (GitHub Secrets) Not Required Not Required
Setup Complexity Low Medium High
Security Level Low (High Risk) Very High Very High
Rotation Required Manual/Automated Automatic Automatic

Summary Analysis of Identity Orchestration

The transition toward Workload Identity Federation within GitHub Actions represents a fundamental shift in the security paradigm of cloud automation. By utilizing the google-github-actions/auth action, the dependency on static secrets is replaced by a dynamic, trust-based exchange. The core of this system is the GOOGLE_APPLICATION_CREDENTIALS variable, which serves as a pointer to a temporary identity file.

The effectiveness of this system relies on the strict sequencing of the workflow: first, the actions/checkout step to prepare the workspace; second, the auth action to generate the identity; and third, the specific tool (like get-gke-credentials or docker login) that consumes the identity. The ability to mount these credentials into Docker containers via volumes and the use of the Connect gateway for private clusters demonstrates the flexibility of this architecture in handling complex network topologies and isolated environments. However, the limitation with gsutil and the specific issues with Nextflow highlight that while the auth action provides the identity, the downstream tool must be compatible with the provided ADC format to function correctly.

Sources

  1. Deploying serverless platforms with GitHub Actions
  2. Securely accessing Google Cloud resources in development, CI, and production
  3. Nextflow Issue #6612: Authentication issues when using google-github-actions/auth@v3
  4. google-github-actions/auth Repository
  5. google-github-actions/get-gke-credentials Repository

Related Posts