This article will discuss several key features if you are programming for Google Cloud Platform.

Key features of this article:

  1. Using a service account that has no permissions to read a non-public Cloud Storage object.
  2. How to use the downloaded data, which is a different service account to create credentials that have new permissions.
  3. How to load a service account from local disk and create a Cloud Storage client.
  4. How to read an object stored in Cloud Storage.
  5. How to process the data read from Cloud Storage and how to load this data to create new credentials.

If you consider the points above, we are implementing multiple layers of security. We start off with credentials that have zero permissions. The security for the Cloud Storage object is the identity of the service account and not from an Access Token created from the service account. This limits the exposure if the service account is stolen or made public. The next person must know that the service account can access only one file on Cloud Storage. Without this information about the Cloud Storage object, nothing else can be accomplished with the service account.

For services such as Google Cloud Functions, Cloud Run, etc. the first service account is actually the Application Default Credential for the service. You specify this restricted service account using the --service-account command-line option. In my article on Cloud Run Identity, I cover these topics including how to encrypt the Cloud Storage Object.

Download Git Repository

I have published the files for this article on GitHub.

License: MIT License

Clone my repository to your system:

For the following commands, I include a batch script which will run all the commands below. This script (setup.bat) is in my repository and at the end of this article.

Getting Started

Verify that the correct project is the default project:

If the correct project is not displayed, use this command to change the default project:

You can list the projects in your account. Some security configurations will not allow you to list projects. In that case, you will need to specify the default project manually as shown above.

Step 1 – Create the first service account:

Step 2 – Down the service account key:

Replace [PROJECT_ID] with your Project ID.

This command downloads the service account key to the file first-service-account.json.

Notice we do not assign permissions to this service account.

Step 3 – Create the second service account:

Step 4 – Down the service account key:

Step 5 – Add IAM permissions to the second service account:

In this example, we will add the role storage.objectViewer. This role will allow the program to list objects in the bucket.

Step 6 – Copy the second service account to a Cloud Storage Bucket:

For this example, I recommend creating a new bucket with a unique name. Example command line:

Copy the second service account to the bucket:

Step 7 – Set the permissions for the Cloud Storage Object:

The following command is the magic for this article. The first service account has no permissions. The following command will add the first service account to the Cloud Storage object with permissions to read the object. This is Identity Based Access Control instead of Role Based Access Control (RBAC). RBAC requires an Access Token. The Cloud Storage Bucket is not checking the permissions that the service account has, only the identity of the service account. Here we assign the role legacyObjectReader. After the following command completes, credentials created from first-service-account will be able to read the object second-service-account.json.

Step 8 – Save the following code to main.go and execute:

This is main.go

Update the line bucketName := "replace-with-your-bucket-name" in the source code with the correct bucket name.

Below is a Windows Command Prompt Script to set everything up. This script will get the Project ID from the CLI gcloud command. This script is in my repository.

Save as setup.bat

Additional Information


I write free articles about technology. Recently, I learned about which provides free images. The image in this article is courtesy of Tetyana Kovyrina at Pexels.