@aws/aws-distro-opentelemetry-node-autoinstrumentation
Version:
This package provides Amazon Web Services distribution of the OpenTelemetry Node Instrumentation, which allows for auto-instrumentation of NodeJS applications.
89 lines • 3.79 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwsAuthenticator = exports.X_AMZ_CONTENT_SHA256_HEADER = exports.X_AMZ_SECURITY_TOKEN_HEADER = exports.X_AMZ_DATE_HEADER = exports.AUTHORIZATION_HEADER = void 0;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
const api_1 = require("@opentelemetry/api");
const utils_1 = require("../../../../utils");
let SignatureV4;
let HttpRequest;
let defaultProvider;
let Sha256;
let dependenciesLoaded = false;
if ((0, utils_1.getNodeVersion)() >= 16) {
try {
defaultProvider = require('@aws-sdk/credential-provider-node').defaultProvider;
Sha256 = require('@aws-crypto/sha256-js').Sha256;
SignatureV4 = require('@smithy/signature-v4').SignatureV4;
HttpRequest = require('@smithy/protocol-http').HttpRequest;
dependenciesLoaded = true;
}
catch (error) {
api_1.diag.error(`Failed to load required AWS dependency for SigV4 Signing: ${error}`);
}
}
else {
api_1.diag.error('SigV4 signing requires at least Node major version 16');
}
// See: https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html
exports.AUTHORIZATION_HEADER = 'authorization';
exports.X_AMZ_DATE_HEADER = 'x-amz-date';
exports.X_AMZ_SECURITY_TOKEN_HEADER = 'x-amz-security-token';
exports.X_AMZ_CONTENT_SHA256_HEADER = 'x-amz-content-sha256';
class AwsAuthenticator {
constructor(endpoint, service) {
// The endpoint is pre-validated by the config with isAwsOtlpEndpoint, so then endpoint is guaranteed to be well formatted and
// new URL() will not throw
this.endpoint = new URL(endpoint);
this.region = endpoint.split('.')[1];
this.service = service;
}
async authenticate(headers, serializedData) {
// Only do SigV4 Signing if the required dependencies are installed.
if (dependenciesLoaded && serializedData) {
const cleanedHeaders = this.removeSigV4Headers(headers);
const request = new HttpRequest({
method: 'POST',
protocol: 'https',
hostname: this.endpoint.hostname,
path: this.endpoint.pathname,
body: serializedData,
headers: Object.assign(Object.assign({}, cleanedHeaders), { host: this.endpoint.hostname }),
});
try {
const signer = new SignatureV4({
credentials: defaultProvider(),
region: this.region,
service: this.service,
sha256: Sha256,
});
const signedRequest = await signer.sign(request);
return signedRequest.headers;
}
catch (exception) {
api_1.diag.debug(`Failed to sign/authenticate the given export request with error: ${exception}`);
return undefined;
}
}
api_1.diag.debug('No serialized data provided. Not authenticating.');
return undefined;
}
// Cleans up Sigv4 from headers to avoid accidentally copying them to the new headers
removeSigV4Headers(headers) {
const newHeaders = {};
const sigv4Headers = [
exports.AUTHORIZATION_HEADER,
exports.X_AMZ_CONTENT_SHA256_HEADER,
exports.X_AMZ_DATE_HEADER,
exports.X_AMZ_CONTENT_SHA256_HEADER,
];
for (const key in headers) {
if (!sigv4Headers.includes(key.toLowerCase())) {
newHeaders[key] = headers[key];
}
}
return newHeaders;
}
}
exports.AwsAuthenticator = AwsAuthenticator;
//# sourceMappingURL=aws-authenticator.js.map