0

Since this is an integration app calling a service, I decided to use Service Account because its used for server-to-server interactions. I'm using the Lambda integration to call the Google Service Account to get the Google Campaign Manager 360 API campaign data and download the data into S3 bucket for SA's BI Reports. However, after configuring the service and redacting my lambda code , I get this 403 error and not quite sure why. Here are the steps.

  1. I Set up Service Account giving my self owner privileges and the account has user privileges.
  2. Copied the service account Json file to be used by Python and Google API. I'm not sure what to do at this point and what could be wrong. Thanks much for your help.

Here is my code for the lambda python integration where execution fails at line 20 (I would expect an issue with OAuth2.0 credentials but not with Service Account. I'm new to all of this) :

import json
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
import googleapiclient.discovery

SCOPES = ['https://www.googleapis.com/auth/dfareporting', 'https://www.googleapis.com/auth/ddmconversions']
delegate = os.environ['DELEGATE_EMAIL']
profile_id = os.environ['PROFILEID']
def lambda_handler(event, context):
   
    SERVICE_ACCOUNT_FILE = 'service.json'
    print(SERVICE_ACCOUNT_FILE)
    # Implement Credentials objects from the service account and scopes
    credentials = service_account.Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
    print('<< CREDENTIAL >> ', credentials)
    #delegated_credentials = credentials.with_subject(delegate)
    gcm360_client = build('dfareporting', 'v4', credentials=credentials)
    request =gcm360_client.campaigns().list(profileId=profile_id)
    print('<< REQUEST >> ',request)
    response = request.execute()
    #print('<< RESPONSE >> ',response)
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

Here is the error message in Lambda: enter image description here

  • Did you complete the steps [here](https://support.google.com/campaignmanager/answer/6098287#email&zippy=%2Cemail) – John Hanley Jun 15 '23 at 01:07
  • @JohnHanley, thanks I'll look into that. I think I will need to speak with me account admin because I cant create a user profile using Admin->User Profile->New. – Anthony Williams Jun 15 '23 at 01:45
  • @JohnHanley, Also, before switching to Service Account, I was using Postman and OAuth2.0 and I was able to call the scopes and I did get response data so I may not need delegation(?). – Anthony Williams Jun 15 '23 at 02:01
  • Delegation requires even more permissions. Delegation can only be setup by a Super Admin. – John Hanley Jun 15 '23 at 02:04
  • @JohnHanley OK thanks . my company will be meeting with our client to possibly discuss giving me delegate authority to access the scopes. However, I have 2 more questions: 1) Will I have to use the following instruction delegated_credentials = credentials.with_subject('user@example.org') ? 2) Does my current code handle token refreshing as it looks now? Thanks – Anthony Williams Jun 15 '23 at 12:43
  • You do not need Domain Wide Delegation and I would not ask the customer for them. Delegation allows the service account to impersonate users and has security implications. I would not grant those permissions to you without justification. Needing those scopes are not justification. Instead, you should correctly configure the service account as an authorized principal. – John Hanley Jun 15 '23 at 12:48
  • @JohnHanley are you saying that the instruction - "Grant this service account access to project" - is what we need to update? (I found this on the page: https://developers.google.com/identity/protocols/oauth2/service-account#authorizingrequests) I visited the the IAM & Admin page and it shows that my service account is Principal: Project Resource is Parameter 1 and Principal is my service account email id as Parameter 2 . Is this correct? Thanks – Anthony Williams Jun 15 '23 at 13:34
  • I provided a link in my first comment. – John Hanley Jun 15 '23 at 15:30
  • @JohnHanley . Sorry about that. I got sidetracked with Delegation and impersonation and that threw me off. I will have to probably ask the clients super admin to set up my user profile to access the Campaign 360 API programmatically and then set up my work email and attach it to the non-personal google account (because I don;t have User Profile option just Billing and Sites). – Anthony Williams Jun 15 '23 at 17:43
  • @JohnHanley I will give you the vote for this answer. I got the code working but I need to be able to have it generate a token on its own . I had to use Rest approach and incorporated some Google however JWT is giving me an error: "Algorithm 'RS256' could not be found. Do you have cryptography installed?" . So somehow my Jwt library is old or the crytography version is not recognized any longer? I need to have a token generator as you had mentioned: https://stackoverflow.com/questions/53890526/how-do-i-create-an-access-token-from-service-account-credentials-using-rest-api – Anthony Williams Jun 20 '23 at 12:37

1 Answers1

0

After unsuccessfully trying to use the Service Account method, I had to use a mostly non-Google Rest-based alternative that incorporates some Google.

I was able to pull data using a get request and load that data into an S3 bucket using the google API urls for Campaign Manager 360.

Now, I need to generate tokens for my Service Account.

@JohnHanley has a solution for this at:

How do I create an Access Token from Service Account Credentials using REST API?

It seems to use info from the Google Page here:

https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth