Search code examples
google-cloud-platformgoogle-app-enginegoogle-cloud-functionsgoogle-oauthgoogle-cloud-iam

How to get the access token of the service account running a google cloud function?


I have a google cloud function that is sending a PATCH request to the GCP app engine admin API to modify a service. I have a assigned a service account to the cloud function that has the required IAM permissions to modify app engine services, but i get a 401 unauthorized error when i test the function. It seems that google cant automatically detect that the request being send to the app engine admin API is authorized by that service account, so how do i get the access token of the service account running the cloud function so i can include it into the api call?

This is my current function:

functions.http('toggleFingerprintServer', async (req, res) => {
    
    //get access token of service account running this function here and attack to request below to gain access to API

    if (!req.query || !req.query.servingStatus || (req.query.servingStatus!== 'SERVING' &&  req.query.servingStatus!== 'STOPPED'))
        res.status(400).json({status: 400, message: "Status must be SERVING or STOPPED"})
    else {
        const externalRes = await fetch('https://content-appengine.googleapis.com/v1/apps/demoApp/services/fingerprint-api/versions/1?updateMask=servingStatus', {
            method: 'PATCH',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({servingStatus: req.query.servingStatus}),
        });
        res.sendStatus(externalRes.ok ? 200 : 500);
    }
});

Solution

  • Indeed, you need an access token. You could get it manually (using the metadata server and calling the correct URL), but you can also leverage the built-in solution of Google Cloud client library like that

        const {GoogleAuth} = require('google-auth-library');
    ...
    ...
    
        const auth = new GoogleAuth({
            scopes: 'https://www.googleapis.com/auth/cloud-platform'
        });
        const token = await auth.getAccessToken();
        console.log(token);