UNPKG

snowflake-sdk

Version:
110 lines 4.42 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAwsCredentials = getAwsCredentials; exports.getAwsRegion = getAwsRegion; exports.getStsHostname = getStsHostname; exports.getAwsAttestationToken = getAwsAttestationToken; const credential_provider_node_1 = require("@aws-sdk/credential-provider-node"); const client_sts_1 = require("@aws-sdk/client-sts"); const ec2_metadata_service_1 = require("@aws-sdk/ec2-metadata-service"); const protocol_http_1 = require("@smithy/protocol-http"); const signature_v4_1 = require("@smithy/signature-v4"); const sha256_js_1 = require("@aws-crypto/sha256-js"); const logger_1 = __importDefault(require("../../logger")); async function getAwsCredentials(region, impersonationPath = []) { (0, logger_1.default)().debug('Getting AWS credentials from default provider'); let credentials = await (0, credential_provider_node_1.defaultProvider)()(); for (const roleArn of impersonationPath) { (0, logger_1.default)().debug(`Getting AWS credentials from impersonation role: ${roleArn}`); const stsClient = new client_sts_1.STSClient({ credentials, region, }); const command = new client_sts_1.AssumeRoleCommand({ RoleArn: roleArn, RoleSessionName: 'identity-federation-session', }); const { Credentials } = await stsClient.send(command); if (Credentials?.AccessKeyId && Credentials?.SecretAccessKey) { credentials = { accessKeyId: Credentials.AccessKeyId, secretAccessKey: Credentials.SecretAccessKey, sessionToken: Credentials.SessionToken, }; } else { throw new Error(`Failed to get credentials from impersonation role ${roleArn}`); } } return credentials; } async function getAwsRegion() { if (process.env.AWS_REGION) { (0, logger_1.default)().debug('Getting AWS region from AWS_REGION'); return process.env.AWS_REGION; // Lambda } else { (0, logger_1.default)().debug('Getting AWS region from EC2 metadata service'); return new ec2_metadata_service_1.MetadataService().request('/latest/meta-data/placement/region', {}); // EC2 } } function getStsHostname(region) { const domain = region.startsWith('cn-') ? 'amazonaws.com.cn' : 'amazonaws.com'; return `sts.${region}.${domain}`; } async function getAwsAttestationToken(useOutboundToken = false, impersonationPath) { const region = await getAwsRegion(); const credentials = await getAwsCredentials(region, impersonationPath); if (useOutboundToken) { return getOutboundWebIdentityToken(region, credentials); } else { return getCallerIdentityToken(region, credentials); } } async function getCallerIdentityToken(region, credentials) { const stsHostname = getStsHostname(region); const request = new protocol_http_1.HttpRequest({ method: 'POST', protocol: 'https', hostname: stsHostname, path: '/', headers: { host: stsHostname, 'x-snowflake-audience': 'snowflakecomputing.com', }, query: { Action: 'GetCallerIdentity', Version: '2011-06-15', }, }); const signedRequest = await new signature_v4_1.SignatureV4({ credentials, applyChecksum: false, region, service: 'sts', sha256: sha256_js_1.Sha256, }).sign(request); const token = { url: `https://${stsHostname}/?Action=GetCallerIdentity&Version=2011-06-15`, method: 'POST', headers: signedRequest.headers, }; return btoa(JSON.stringify(token)); } async function getOutboundWebIdentityToken(region, credentials) { const stsClient = new client_sts_1.STSClient({ credentials, region }); const response = await stsClient.send(new client_sts_1.GetWebIdentityTokenCommand({ Audience: ['snowflakecomputing.com'], SigningAlgorithm: 'ES384', })); const token = response.WebIdentityToken; if (!token) { throw new Error('Failed to obtain AWS web identity token from STS'); } return token; } //# sourceMappingURL=attestation_aws.js.map