n8n-nodes-gcloud-sa-impersonate
Version:
n8n community node for Google Cloud Service Account Token Impersonation
65 lines (64 loc) • 2.43 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getGceMetadataToken = getGceMetadataToken;
exports.impersonateServiceAccount = impersonateServiceAccount;
exports.parseScopesString = parseScopesString;
exports.parseDelegatesString = parseDelegatesString;
const axios_1 = __importDefault(require("axios"));
const SERVICE_ACCOUNT_IMPERSONATION_URL = 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts';
async function getGceMetadataToken(metadataServerUrl = 'https://metadata.google.internal/') {
const tokenUrl = `${metadataServerUrl.replace(/\/$/, '')}/computeMetadata/v1/instance/service-accounts/default/token`;
try {
const response = await axios_1.default.get(tokenUrl, {
headers: {
'Metadata-Flavor': 'Google',
},
timeout: 10000,
});
return response.data.access_token;
}
catch (error) {
throw new Error(`Failed to get GCE metadata token: ${error}`);
}
}
async function impersonateServiceAccount(sourceToken, targetServiceAccount, scopes, delegates, lifetime = '3600s') {
const impersonationUrl = `${SERVICE_ACCOUNT_IMPERSONATION_URL}/${targetServiceAccount}:generateAccessToken`;
const requestBody = {
scope: scopes,
lifetime,
};
if (delegates && delegates.length > 0) {
requestBody.delegates = delegates;
}
try {
const response = await axios_1.default.post(impersonationUrl, requestBody, {
headers: {
'Authorization': `Bearer ${sourceToken}`,
'Content-Type': 'application/json',
},
timeout: 30000,
});
return response.data;
}
catch (error) {
throw new Error(`Failed to impersonate service account: ${error}`);
}
}
function parseScopesString(scopesString) {
return scopesString
.split(',')
.map(scope => scope.trim())
.filter(scope => scope.length > 0);
}
function parseDelegatesString(delegatesString) {
if (!delegatesString || delegatesString.trim() === '') {
return undefined;
}
return delegatesString
.split(',')
.map(delegate => delegate.trim())
.filter(delegate => delegate.length > 0);
}