How to access a Google Secret Manager secret using service account impersonation¶
This guide shows you how to access a Google Secret Manager secret from a CI job running on a GKE-hosted runner. It covers creating a service account and assigning the required IAM bindings using Terraform, as well as how to access the secret using service account impersonation from the CI job itself.
Prerequisites¶
- This how-to assumes that you have already created a Google Secret Manager secret in the relevant
Google Project that you wish to access. In this example the secret ID is referred to as
<existing secret ID>
.
Steps¶
-
Create a dedicated Google IAM service account for this task. For example:
resource "google_service_account" "secret_accessor" { account_id = "secret_accessor" display_name = "Secret Accessor" }
-
Grant the new Google IAM service account the ability to access the required Google Secret Manager secret by assigning it the
secretmanager.secretAccessor
role as follows.resource "google_secret_manager_secret_iam_member" "secret_accessor" { secret_id = "<existing secret ID>" role = "roles/secretmanager.secretAccessor" member = "serviceAccount:${resource.google_service_account.secret_accessor.email}" }
-
Grant the
gke-ci-run
Kubernetes service account the ability to impersonate the new Google IAM service account using the Workload Identity namespace.resource "google_service_account_iam_member" "secret_accessor_impersonation" { service_account_id = google_service_account.secret_accessor.name role = "roles/iam.serviceAccountTokenCreator" member = "serviceAccount:gitlab-runner-prod-22257483.svc.id.goog[<product runner namespace>/gke-ci-run]" }
-
Access the secret in a CI job using the following command in the
script
definition for the job.
```yaml
job1:
image: registry.gitlab.developers.cam.ac.uk/uis/devops/infra/dockerimages/gcloud-docker:latest
script: |
my_secret=$(gcloud --impersonate-service-account=secret_accessor@<project id>.iam.gserviceaccount.com \
--project <project id> secrets versions access latest --secret=<existing secret id>)
tags:
- $GKE_RUNNER_TAG
```
GitLab Project Factory Configuration¶
For gitlab-project-factory projects this is simplified greatly, the project factory provides a service account to access secrets, and a group level gitlab access token that will be stored in the secret manager.
These are then made available as pre-defined CI/CD variables, and can be accessed by jobs running GKE runners.
To access the general purpose gitlab access token:
```yaml
job1:
image: registry.gitlab.developers.cam.ac.uk/uis/devops/infra/dockerimages/gcloud-docker:latest
script: |
my_secret=$(gcloud --impersonate-service-account=${GITLAB_TOKEN_ACCESSOR_SERVICE_ACCOUNT} \
--project <project id> secrets versions access \
${GITLAB_ACCESS_TOKEN_SECRET_ID}/versions/latest)
tags:
- $GKE_RUNNER_TAG
```
Note that the GITLAB_ACCESS_TOKEN_SECRET_ID
is the fully qualified resource
id, so the version must be accessed using the full resource URI as described
above.
Summary¶
In this guide you've learnt how to create a dedicated Google IAM service account with permission to
access an existing secret. You've also learnt how to use Workload Identity to grant a product's
gke-ci-run
Kubernetes service account the ability to impersonate the new Google IAM service
account to retrieve the secret value from a CI job script.