Skip to content

Commit d19f5d9

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

File tree

2 files changed

+44
-0
lines changed

2 files changed

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

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

0 commit comments

Comments
 (0)