I have a Google Apps Script application that uses a service account with domain-wide delegation to make changes to user accounts on a domain. To improve the security of the application, I moved from storing the private key in code to using Google Secrets Manager with this answer. Strangely, I could see the key being returned correctly from secrets manager but it would fail to get an authorized token, throwing the following error:
{ [Exception: Invalid argument: key] name: 'Exception' }
I solved the issue after seeing this comment in the GitHub repo. I just added the replacement to the retrieval function and everything resumed working correctly. I also cleared the script properties to ensure I was pulling new tokens correctly.
function getSecret() {
let token, endpoint, response;
endpoint = `https://secretmanager.googleapis.com/etc etc etc`;
token = ScriptApp.getOAuthToken();
response = UrlFetchApp.fetch(endpoint, {
headers: {
Authorization: 'Bearer ' + token,
Accept: 'application/json',
}
});
var decodedAPIKey = Utilities.base64Decode(JSON.parse(response.getContentText())['payload']['data']);
var apiKey = Utilities.newBlob(decodedAPIKey).getDataAsString();
return apiKey;
}
function getSerivce(targetEmail,scopes) {
console.log("trying to get oauth2 service with:\n"+scopes);
PRIVATE_KEY = getSecret().replace(/\\n/g, '\n');
return OAuth2.createService('Gmail:' + boxEmail)
// Set the endpoint URL.
.setTokenUrl('https://oauth2.googleapis.com/token')
// Set the private key and issuer.
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
// Set the name of the user to impersonate.
.setSubject(targetEmail)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scope. This must match one of the scopes configured during the
// setup of domain-wide delegation.
.setScope(scopes);
}