google-cloud-platformgroovygoogle-cloud-functionssap-cpi

Authenticate calls to Google Cloud Functions programmatically


I am trying to authenticate to Google Cloud Functions from SAP CPI to fetch some data from a database. To push data, we use pub/sub, with a service account access token, and it works perfectly. But for the functions, it needs an identity token instead of an access token. We get the previous token with a groovy script (No Jenkins).

Is it possible to authenticate to the functions also with an access token? Or to get the identity token without building a whole IAP layer?


Solution

  • You have to call your Cloud Functions (or Cloud Run, it's the same) with a signed identity token.

    So you can use a groovy script for generating a signed identity token. Here an example

    
    import com.google.api.client.http.GenericUrl
    import com.google.api.client.http.HttpRequest
    import com.google.api.client.http.HttpRequestFactory
    import com.google.api.client.http.HttpResponse
    import com.google.api.client.http.javanet.NetHttpTransport
    import com.google.auth.Credentials
    import com.google.auth.http.HttpCredentialsAdapter
    import com.google.auth.oauth2.IdTokenCredentials
    import com.google.auth.oauth2.IdTokenProvider
    import com.google.auth.oauth2.ServiceAccountCredentials
    import com.google.common.base.Charsets
    import com.google.common.io.CharStreams
    
    String myUri = "YOUR_URL";
    
    Credentials credentials = ServiceAccountCredentials
            .fromStream(new FileInputStream(new File("YOUR_SERVICE_ACCOUNT_KEY_FILE"))).createScoped("https://www.googleapis.com/auth/cloud-platform");
    
    String token = ((IdTokenProvider) credentials).idTokenWithAudience(myUri, Collections.EMPTY_LIST).getTokenValue();
    System.out.println(token);
    
    IdTokenCredentials idTokenCredentials = IdTokenCredentials.newBuilder()
            .setIdTokenProvider((ServiceAccountCredentials) credentials)
            .setTargetAudience(myUri).build();
    
    HttpRequestFactory factory = new NetHttpTransport().createRequestFactory(new HttpCredentialsAdapter(idTokenCredentials));
    HttpRequest request = factory.buildGetRequest(new GenericUrl(myUri));
    HttpResponse httpResponse = request.execute();
    
    System.out.println(CharStreams.toString(new InputStreamReader(httpResponse.getContent(), Charsets.UTF_8)));
    
    

    Service account key file is required only if you are outside GCP. Else, the default service account is enough, but must be a service account. Your personal user account won't work

    Add this dependency (here in Maven)

            <dependency>
                <groupId>com.google.auth</groupId>
                <artifactId>google-auth-library-oauth2-http</artifactId>
                <version>0.20.0</version>
            </dependency>
    

    Or you can use a tool that I wrote and open sourced. I also wrote a Medium article for explaining the use cases