Skip to content

fix: prevent credential_process hang on Windows in stdio transport mode#293

Merged
rshevchuk-git merged 5 commits into
mainfrom
fix/credential-process-stdin-inheritance
May 29, 2026
Merged

fix: prevent credential_process hang on Windows in stdio transport mode#293
rshevchuk-git merged 5 commits into
mainfrom
fix/credential-process-stdin-inheritance

Conversation

@rshevchuk-git

Copy link
Copy Markdown
Collaborator

Summary

  • Monkey-patches botocore's ProcessProvider._retrieve_credentials_using to pass stdin=subprocess.DEVNULL when spawning credential_process subprocesses
  • Prevents the child process from inheriting the MCP JSON-RPC pipe as its stdin, which causes Popen.communicate() to hang indefinitely on Windows (IOCP)
  • Adds comprehensive stress tests validating the fix across concurrent calls, pipe inheritance, and end-to-end credential resolution

Problem

When mcp-proxy-for-aws runs in stdio transport mode, its stdin is the MCP JSON-RPC pipe. Botocore's ProcessProvider spawns credential_process subprocesses without specifying stdin, so the child inherits the pipe. On Windows this causes the subprocess to hang indefinitely because it holds an open handle to the pipe, blocking Popen.communicate() from completing.

This affects any user with credential_process in their AWS profile (e.g., isengardcli credentials) when using the MCP proxy on Windows through IDE integrations (Kiro, Cline, Claude Code).

Fixes D454977820

Test plan

  • 12 new unit tests covering:
    • Patch is active (stdin=DEVNULL present in source)
    • Pipe inheritance behavior with/without fix
    • Error handling preserved (failed process, invalid version)
    • Concurrent credential_process calls with active MCP pipe (10 threads)
    • End-to-end boto3 session with credential_process + simulated MCP pipe
  • All 192 existing unit tests pass
  • Verified RefreshableCredentials (expiring creds) path works
  • Verified static credentials profiles are unaffected
  • Verified failed credential_process error propagation works

Monkey-patch botocore's ProcessProvider to pass stdin=subprocess.DEVNULL
when spawning credential_process subprocesses. Without this, the child
inherits the MCP JSON-RPC pipe as stdin, causing Popen.communicate() to
hang indefinitely on Windows (IOCP) due to the open pipe handle.

Fixes D454977820
@rshevchuk-git
rshevchuk-git requested a review from a team as a code owner May 27, 2026 10:16
@rshevchuk-git
rshevchuk-git requested review from arangatang and jinet May 27, 2026 10:16
Comment thread mcp_proxy_for_aws/sigv4_helper.py Dismissed
anasstahr
anasstahr previously approved these changes May 27, 2026
Comment thread mcp_proxy_for_aws/sigv4_helper.py Outdated
Wrap ProcessProvider._popen via __init__ to inject stdin=DEVNULL,
rather than replacing the entire _retrieve_credentials_using method.
This is less fragile as it doesn't duplicate botocore's credential
parsing logic.
@rshevchuk-git
rshevchuk-git marked this pull request as draft May 28, 2026 08:28
Comment thread mcp_proxy_for_aws/sigv4_helper.py Fixed
@rshevchuk-git
rshevchuk-git marked this pull request as ready for review May 28, 2026 10:47
Comment thread tests/unit/test_credential_process_stdin_inheritance.py Outdated
Comment thread tests/unit/test_credential_process_stdin_inheritance.py Outdated
Comment thread tests/unit/test_credential_process_stdin_inheritance.py Outdated
Comment thread tests/unit/test_credential_process_stdin_inheritance.py Outdated
@rshevchuk-git
rshevchuk-git added this pull request to the merge queue May 29, 2026
Merged via the queue into main with commit 4ffd565 May 29, 2026
8 checks passed
@rshevchuk-git
rshevchuk-git deleted the fix/credential-process-stdin-inheritance branch May 29, 2026 08:24
@anasstahr anasstahr mentioned this pull request May 29, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants