How to use gcp workload identity in java springboot application?

2.6k Views Asked by At

In below I set the variable in application.properties and the tried using default service instance:

    private static void testListGCPBucket() String configPath) throws IOException {
        
         Storage storage = StorageOptions.getDefaultInstance().getService();
        System.out.println("Buckets:");
        Page<Bucket> buckets = storage.list();
        for (Bucket bucket : buckets.iterateAll()) {
            System.out.println(bucket.toString());
        }
        System.out.println("completed...");
    }

application.config file content:

GOOGLE_APPLICATION_CREDENTIALS=classpath:config.json

But this is not working I am getting below error:

Caused by: com.google.api.client.http.HttpResponseException: 403 Forbidden
POST https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/proj-workload-id-svc-acct@idmp-mii-dev-ddb5.iam.gserviceaccount.com:generateAccessToken
{
  "error": {
    "code": 403,
    "message": "The caller does not have permission",
    "errors": [
      {
        "message": "The caller does not have permission",
        "domain": "global",
        "reason": "forbidden"
      }
    ],
    "status": "PERMISSION_DENIED"
  }
}

    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1116)
    at com.google.auth.oauth2.ImpersonatedCredentials.refreshAccessToken(ImpersonatedCredentials.java:441)
    ... 36 more
1

There are 1 best solutions below

1
On

Based on my understanding, if using the DefaultService then it will look at your environment variables. Setting it into your application.properties will not modify your environmental variables.

You will need to point to your file instead. Adding it to your application.properties, it will not be picked up.

Credentials credentials = GoogleCredentials
  .fromStream(new FileInputStream("yourJsonConfig"));
Storage storage = StorageOptions.newBuilder().setCredentials(credentials).build().getService();

Or according to the official documentation, you can use Spring Cloud GCP Starter, and configure it using your application.properties file.

https://docs.spring.io/spring-cloud-gcp/docs/1.1.0.M1/reference/html/spring-cloud-gcp-core.html#_credentials

2 Credentials

CredentialsProvider is a functional interface that returns the credentials to authenticate and authorize calls to Google Cloud Client Libraries.

public interface CredentialsProvider { Credentials getCredentials() throws IOException; }

The Spring Cloud GCP starter auto-configures a CredentialsProvider. It uses the spring.cloud.gcp.credentials.location property to locate the OAuth2 private key of a Google service account. Keep in mind this property is a Spring Resource, so the credentials file can be obtained from a number of different locations such as the file system, classpath, URL, etc. The next example specifies the credentials location property in the file system.

spring.cloud.gcp.credentials.location=file:/usr/local/key.json

Alternatively, you can set the credentials by directly specifying the spring.cloud.gcp.credentials.encoded-key property. The value should be the base64-encoded account private key in JSON format.

If that credentials aren’t specified through properties, the starter tries to discover credentials from a number of places:

Credentials file pointed to by the GOOGLE_APPLICATION_CREDENTIALS environment variable
Credentials provided by the Google Cloud SDK gcloud auth application-default login command
Google App Engine built-in credentials
Google Cloud Shell built-in credentials
Google Compute Engine built-in credentials

If your app is running on Google App Engine or Google Compute Engine, in most cases, you should omit the spring.cloud.gcp.credentials.location property and, instead, let the Spring Cloud GCP Starter get the correct credentials for those environments. On App Engine Standard, the App Identity service account credentials are used, on App Engine Flexible, the Flexible service account credential are used and on Google Compute Engine, the Compute Engine Default Service Account is used.

spring.cloud.gcp.credentials.location=file:/usr/local/key.json