Skip to content

Commit 9e036ee

Browse files
Skip credential extraction if the context is not injectable
1 parent ac0ca9d commit 9e036ee

File tree

2 files changed

+64
-16
lines changed

2 files changed

+64
-16
lines changed

aws-distro-opentelemetry-node-autoinstrumentation/src/patches/instrumentation-patch.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -470,25 +470,28 @@ function patchAwsSdkInstrumentation(instrumentation: Instrumentation): void {
470470
// suppressTracing prevents span generation for internal credential extraction calls
471471
// which are implementation details and not relevant to the application's telemetry
472472
const suppressedContext = suppressTracing(activeContext).setValue(SKIP_CREDENTIAL_CAPTURE_KEY, true);
473-
await otelContext.with(suppressedContext, async () => {
474-
try {
475-
const credsProvider = this.config.credentials;
476-
if (credsProvider instanceof Function) {
477-
const credentials = await credsProvider();
478-
if (credentials?.accessKeyId) {
479-
span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_AUTH_ACCOUNT_ACCESS_KEY, credentials.accessKeyId);
473+
// Skip credential extraction if the context is not injectable
474+
if (suppressedContext.getValue(SKIP_CREDENTIAL_CAPTURE_KEY)) {
475+
await otelContext.with(suppressedContext, async () => {
476+
try {
477+
const credsProvider = this.config.credentials;
478+
if (credsProvider instanceof Function) {
479+
const credentials = await credsProvider();
480+
if (credentials?.accessKeyId) {
481+
span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_AUTH_ACCOUNT_ACCESS_KEY, credentials.accessKeyId);
482+
}
480483
}
481-
}
482-
if (this.config.region instanceof Function) {
483-
const region = await this.config.region();
484-
if (region) {
485-
span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_AUTH_REGION, region);
484+
if (this.config.region instanceof Function) {
485+
const region = await this.config.region();
486+
if (region) {
487+
span.setAttribute(AWS_ATTRIBUTE_KEYS.AWS_AUTH_REGION, region);
488+
}
486489
}
490+
} catch (err) {
491+
diag.debug('Failed to get auth account access key and region:', err);
487492
}
488-
} catch (err) {
489-
diag.debug('Failed to get auth account access key and region:', err);
490-
}
491-
});
493+
});
494+
}
492495
}
493496

494497
return await next(middlewareArgs);

aws-distro-opentelemetry-node-autoinstrumentation/test/patches/instrumentation-patch.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
TextMapSetter,
1616
INVALID_SPAN_CONTEXT,
1717
SpanStatusCode,
18+
ROOT_CONTEXT,
1819
} from '@opentelemetry/api';
1920
import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node';
2021
import { Instrumentation } from '@opentelemetry/instrumentation';
@@ -695,6 +696,50 @@ describe('InstrumentationPatchTest', () => {
695696
).toBeTruthy();
696697
expect(mockSpan.setAttribute.calledWith(AWS_ATTRIBUTE_KEYS.AWS_AUTH_REGION, 'us-west-2')).toBeTruthy();
697698
});
699+
700+
it('Skips credential extraction with non-injectable NoOp context', async () => {
701+
let credentialsProviderCallCount = 0;
702+
const NoOpContext = Object.create(ROOT_CONTEXT);
703+
NoOpContext.setValue = function () {
704+
return this;
705+
};
706+
NoOpContext.deleteValue = function () {
707+
return this;
708+
};
709+
710+
const mockSpan = sinon.createStubInstance(SDKSpan);
711+
const ctx = trace.setSpan(NoOpContext, mockSpan as unknown as Span);
712+
713+
sinon.stub(otelContext, 'active').returns(ctx);
714+
sinon.stub(trace, 'getSpan').returns(mockSpan as unknown as Span);
715+
716+
const middlewareStack: any[] = [];
717+
const recursiveSdkSend = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS)
718+
['_getV3SmithyClientSendPatch'](() => Promise.resolve())
719+
.bind({
720+
middlewareStack: { add: (middleware: any, config: any) => middlewareStack.push([middleware, config]) },
721+
config: {
722+
// Credentials provider that recursively calls SDK (simulates STS)
723+
credentials: async () => {
724+
credentialsProviderCallCount++;
725+
await middlewareStack[1][0](() => Promise.resolve(), null)({});
726+
return { accessKeyId: 'test-access-key' };
727+
},
728+
region: () => Promise.resolve('us-west-2'),
729+
},
730+
});
731+
732+
// Initial SDK call triggers middleware setup
733+
await recursiveSdkSend({}, null);
734+
735+
// Execute credentials extraction middleware
736+
await middlewareStack[1][0](() => Promise.resolve(), null)({});
737+
738+
expect(credentialsProviderCallCount).toBe(0);
739+
expect(
740+
mockSpan.setAttribute.calledWith(AWS_ATTRIBUTE_KEYS.AWS_AUTH_ACCOUNT_ACCESS_KEY, 'test-access-key')
741+
).toBeFalsy();
742+
});
698743
});
699744

700745
it('prevents recursion when credentials provider makes STS calls', async () => {

0 commit comments

Comments
 (0)