Google Cloud Workload Identity Federation Buildkite Plugin 
A Buildkite plugin to assume a Google Cloud service account using workload identity federation.
The plugin requests an OIDC token from Buildkite and uses it to a populate Google Cloud credentials file assuming you have followed the corresponding setup on Google cloud.
The path to the file is populated in GOOGLE_APPLICATION_CREDENTIALS for SDKs that use Application Default Credentials, and in CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE for the gcloud CLI.
Configuration
audience (Required, string)
- The default audience as shown on the Workload Identity Federation Provider page, without the
https:prefix, or a custom audience that you configure.
claims (list(string))
- A list of claims to add to the requested buildkite oidc token. The agent currently supports requesting claims for
organization_idandpipeline_id. If requested, these will include the respective buildkite organization and/or pipeline UUID claims in the token. (default: [])
hook (string)
-
Which lifecycle hook phase to run the plugin during. This can be either
environment(default) orpre-command. -
This is useful when running this plugin with the artifacts plugin. When using both plugins it may be useful to run this plugin after the artifacts plugin. Running this plugin after allows using the runner’s pre-configured credentials to fetch artifacts before switching to credentials used during the command step. When running the plugin in the
pre-commandhook, you may need to ensure it is ordered after the artifact plugin.
lifetime (number)
- The time (in seconds) the OIDC token will be valid for before expiry. Must be a non-negative integer. If the flag is omitted or set to 0, the API will choose a default finite lifetime. (default: 0)
render-command (string)
- An installed binary that when specified, will run twice to process the values of
audienceandservice-accountvia stdin. This is intended to be used to render environment variables with an application such asenvsubst. (default: ”)
service-account (Required, string)
- The service account for which you want to acquire an access token.
Example
Add the following to your pipeline.yml:
steps:
- command: |
echo "Credentials are located at \$GOOGLE_APPLICATION_CREDENTIALS"
plugins:
- gcp-workload-identity-federation#v1.5.0:
audience: "//iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/buildkite-example-pipeline/providers/buildkite"
service-account: "buildkite-example-pipeline@oidc-project.iam.gserviceaccount.com"
Usage with docker (compose) plugins
For the token to be available in the container(s) run by docker when using those plugins in the same step as this one, you will need to make sure to share the following with the containers:
- the volume
$BUILDKITE_OIDC_TMPDIR - the following environment variables:
BUILDKITE_OIDC_TMPDIRCLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE(if usinggcloud)GOOGLE_APPLICATION_CREDENTIALS(if using any other gcp lib)
For example:
steps:
- command: |
echo "Credentials are located at \$GOOGLE_APPLICATION_CREDENTIALS or \$CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE"
plugins:
- gcp-workload-identity-federation#v1.5.0:
audience: "//iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/buildkite-example-pipeline/providers/buildkite"
service-account: "buildkite-example-pipeline@oidc-project.iam.gserviceaccount.com"
- docker#v5.9.0:
image: <IMAGE>
expand-volume-vars: true
volumes:
- \$BUILDKITE_OIDC_TMPDIR:/\$BUILDKITE_OIDC_TMPDIR
environment:
- BUILDKITE_OIDC_TMPDIR
- CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE # if using 'gcloud'
- GOOGLE_APPLICATION_CREDENTIALS # if using literally any other gcp lib
Google Cloud configuration
You should already have a Google Cloud project and a Service Account to assume. See Google’s documentation for more detailed instructions for these steps.
-
Create a Workload Identity Pool.
We recommend creating a different pool for each security boundary.
In this example we’re using
buildkite-example-pipeline. -
Add a provider to the pool.
Use OpenID Connect, and give it a name like
buildkite.Use
https://agent.buildkite.comas the Issuer.Copy the value of the default audience or provide your own.
-
Configure provider attributes.
Because Google limits the length of attributes to 127 characters, we suggest the following mapping:
Google OIDC google.subject"organization:" + assertion.sub.split(":")[1] + ":pipeline:" + assertion.sub.split(":")[3]attribute.pipeline_slugassertion.pipeline_slugattribute.build_branchassertion.build_branchWith this mapping you can use a CEL expression to restrict which pipelines can assume the service account:
google.subject == "organization:acme:pipeline:buildkite-example-pipeline" -
Grant access to the service account.
-
Configure this plugin using the workload provider audience without the leading
https:, and the service account email address.
Example
Add the following to your pipeline.yml:
steps:
- command: |
echo "Credentials are located at \$GOOGLE_APPLICATION_CREDENTIALS"
plugins:
- gcp-workload-identity-federation#v1.5.0:
audience: "//iam.googleapis.com/projects/123456789/locations/global/workloadIdentityPools/buildkite-example-pipeline/providers/buildkite"
service-account: "buildkite-example-pipeline@oidc-project.iam.gserviceaccount.com"
Developing
To run testing, shellchecks and plugin linting use use bk run with the Buildkite CLI.
bk run
Or if you want to run just the tests, you can use the docker Plugin Tester:
docker run --rm -ti -v "${PWD}":/plugin buildkite/plugin-tester:latest
Contributing
- Fork the repo
- Make the changes
- Run the tests
- Commit and push your changes
- Send a pull request