How to generate and use temporary credentials on Google Cloud Platform

Bastien Cadiot
Apr 26 · 5 min read

With the 2.4 version of the GCP Terraform provider, a new feature is shipped allowing to generate short lived credentials. These credentials are based on the Oauth2 token exchange mechanism to implement impersonation between accounts. You can also use this feature with the —-impersonate-service-account flag in the CLI gcloud.

This feature is very similar of the AWS AssumeRole allowing users to obtain temporary new permissions onto specific resources.

Let’s take a look at this feature!

Why using such mechanism?

The two main ways to authenticate with gcloud are using personal access with oauth2 login or using a service account with its own key. The first may not be ideal because you have to grant individual (or group) permissions to the resources, which can be hard to track along time. Furthermore, not all APIs are working with individual credentials. The second way is more suitable to be used in automation but the credentials are long lived, and you have to share them with the members of your team who need to use automation tools.

To mitigate this issue, some people use a central tool like Terraform Enterprise or Atlantis. These tools handle your service account key and create another level of authorization for your users.

With this new mechanism, we can imagine new security models:

  • We can limit write access to a service account and grant read only access to users
  • We can grant impersonate access from users and/or group to a central service account
  • We can create many service accounts in projects and decide to allow different impersonation on each

For example you can see below an example of integration with a central service account.


How does this work?

As a prerequisite, we need to create the service account to be impersonated:

  • Create the service account
  • Give permissions to the service account on desired resources
  • Allow users (or other SA) to issue access tokens on behalf of this service account

Then, you can emit impersonated credentials by following these steps:

  • Authenticate yourself with your own account or with another service account
  • Request a token for the service account
  • Use this token to authenticate on GCP

This new token will be linked to the service account and can use all of its permissions.

Granting permissions to a service account

You can do it either in the gcloud console, or via Terraform. This is a sample using Terraform code:

resource "google_service_account" "admin_sa" {
 account_id = "admin-impersonated"
 display_name = "admin impersonated"
}resource "google_project_iam_member" "editor" {
 role = "roles/editor"
 member = "serviceAccount:${google_service_account.admin_sa.email}"
}

Then, the second step is to grant permissions to your members to create access token:

resource "google_service_account_iam_member" "admin-account-iam" {
 service_account_id = "${google_service_account.admin_sa.name}"
 role = "roles/iam.serviceAccountTokenCreator"
 member = "user:${var.user_email}"
}

Now the user targeted can issue a token on behalf of the service account.

On the other hand, you may want to use gcloud commands to set up this base permissions. Here are the commands to do this task:

PROJECT=my-project-id
USER=my-user@email.comgcloud iam service-accounts create admin-impersonated
gcloud projects add-iam-policy-binding ${PROJECT} --member serviceAccount:admin-impersonated@${PROJECT}.iam.gserviceaccount.com --role roles/editor
gcloud iam service-accounts add-iam-policy-binding admin-impersonated@${PROJECT}.iam.gserviceaccount.com --member user:${USER} --role roles/iam.serviceAccountTokenCreator

Impersonating the service account to create a temporary access token

Here is a sample of code using Terraform. You will notice that we use two providers, one using the default authentication, and the other using the newly impersonated access token.

provider "google" {
 scopes = [
 "https://www.googleapis.com/auth/cloud-platform",
 "https://www.googleapis.com/auth/userinfo.email",
 ]
}data "google_service_account_access_token" "default" {
 target_service_account = "${google_service_account.admin_sa.email}"scopes = [
 "userinfo-email",
 "cloud-platform",
 ]lifetime = "300s"
}

In the code above we are setting the default provider, and calling the API endpoint to request an access token.

provider "google" {
 version = "~> 2.4"
 alias = "impersonated"
 access_token = "${data.google_service_account_access_token.default.access_token}"scopes = [
 "https://www.googleapis.com/auth/cloud-platform",
 "https://www.googleapis.com/auth/userinfo.email",
 ]
}resource "google_compute_network" "vpc_network" {
 provider = "google.impersonated"
 name = "test-net"
}

That’s it, the mechanism is very simple, you can easily implement it in your workflows. Note that the Terraform datasource will generate a new access token at each run, even if the previous is not expired yet.

Then, in this second block, we are defining another provider using the access token, and a dummy resource (a VPC) created with this new provider.

You can also use the gcloud command to do the same thing. Since version 240.0.0 (2019–03–26), the global flag —-impersonate-service-account is added into gcloud.

gcloud --impersonate-service-account=admin-impersonated@my-project-id.iam.gserviceaccount.com compute networks create test-net

Be careful

To finish

If you are looking for other nice contents and you are not afraid of French, feel free to check out our French blog: https://blog.wescale.fr (Come on, google translate is your friend!)

Thanks to my friends from The WeTribu who have patiently reviewed this article.

WeScale

THE WESCALE EXPERTS BLOG — DEVOPS, CLOUD AND PASSION Regularly find articles written by our consultants on the Cloud and DevOps technologies that make up our daily lives.

Bastien Cadiot

Written by

Bastien is Cloud Builder at WeScale in Paris and Google Developer Expert (GDE) Cloud for Google

WeScale

WeScale

THE WESCALE EXPERTS BLOG — DEVOPS, CLOUD AND PASSION Regularly find articles written by our consultants on the Cloud and DevOps technologies that make up our daily lives.