Skip to content

Commit be3f78f

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

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,10 @@ 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+
// Skip credential extraction if the context is not injectable
474+
if (!suppressedContext.getValue(SKIP_CREDENTIAL_CAPTURE_KEY)) {
475+
return await next(middlewareArgs);
476+
}
473477
await otelContext.with(suppressedContext, async () => {
474478
try {
475479
const credsProvider = this.config.credentials;

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

Lines changed: 39 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,44 @@ 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() { return this; };
704+
NoOpContext.deleteValue = function() { return this; };
705+
706+
const mockSpan = sinon.createStubInstance(SDKSpan);
707+
const ctx = trace.setSpan(NoOpContext, mockSpan as unknown as Span);
708+
709+
sinon.stub(otelContext, 'active').returns(ctx);
710+
sinon.stub(trace, 'getSpan').returns(mockSpan as unknown as Span);
711+
712+
const middlewareStack: any[] = [];
713+
const recursiveSdkSend = extractAwsSdkInstrumentation(PATCHED_INSTRUMENTATIONS)
714+
['_getV3SmithyClientSendPatch'](() => Promise.resolve())
715+
.bind({
716+
middlewareStack: { add: (middleware: any, config: any) => middlewareStack.push([middleware, config]) },
717+
config: {
718+
// Credentials provider that recursively calls SDK (simulates STS)
719+
credentials: async () => {
720+
credentialsProviderCallCount++;
721+
await middlewareStack[1][0](() => Promise.resolve(), null)({});
722+
return { accessKeyId: 'test-access-key' };
723+
},
724+
region: () => Promise.resolve('us-west-2'),
725+
},
726+
});
727+
728+
// Initial SDK call triggers middleware setup
729+
await recursiveSdkSend({}, null);
730+
731+
// Execute credentials extraction middleware
732+
await middlewareStack[1][0](() => Promise.resolve(), null)({});
733+
734+
expect(credentialsProviderCallCount).toBe(0);
735+
expect(mockSpan.setAttribute.calledWith(AWS_ATTRIBUTE_KEYS.AWS_AUTH_ACCOUNT_ACCESS_KEY, 'test-access-key')).toBeFalsy();
736+
});
698737
});
699738

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

0 commit comments

Comments
 (0)