Skip to content

fix(oab-mcp): install rustls CryptoProvider before first TLS handshake (studio#119) - #120

Merged
brettchien merged 1 commit into
mainfrom
fix/k8s-tls-crypto-provider-119
Aug 28, 2026
Merged

fix(oab-mcp): install rustls CryptoProvider before first TLS handshake (studio#119)#120
brettchien merged 1 commit into
mainfrom
fix/k8s-tls-crypto-provider-119

Conversation

@brettchien

Copy link
Copy Markdown
Contributor

Summary

Fixes the blocker in #119 (item 1 of the runbook) — the actual crash behind the New Fleet → Kubernetes wizard's namespace listing silently hanging for cert-based contexts (e.g. orbstack).

studio-cp pulls in both rustls crypto backends transitively: kube's rustls-tls feature → hyper-rustls defaults to ring; the AWS SDK crates (aws-sdk-sts etc.) default to aws-lc-rs. Nothing in the process installed a default, so the first real TLS handshake panics on a tokio-rt-worker thread:

Could not automatically determine the process-level CryptoProvider from Rustls crate features.
Call CryptoProvider::install_default() before this point...

Confirmed via cargo tree -e features -i ring / -i aws-lc-rs inside crates/studio-cp — both backends really are present in the resolved graph.

Why this showed up as two different symptoms (live-debugged with Brett via the Debug drawer's MCP log):

  • GKE context (exec-based auth): fails before reaching TLS, at the exec-spawn step → clean synchronous error, visible in the Activity log.
  • orbstack context (cert-based, no exec step): goes straight to the TLS handshake → hits the panic on a background tokio task → the list_namespaces JSON-RPC request never gets a response. Confirmed in the MCP debug log: request id:1053 with {"context":"orbstack"} has no matching result, unlike neighboring id:1052/1054/1055. Namespace field's datalist silently never populates.

Fix

Install aws-lc-rs as the process default in OabMcp::from_env() — the constructor shared by both the stdio binary (oab-mcp sidecar) and the in-process reverse-MCP tunnel driver, so both entry points are covered by one call site. Picked aws-lc-rs to match the backend the AWS SDK side of this same crate already uses. The install call's Result is discarded — install_default() can only succeed once per process, and if some other path already won that race, that's fine too, we only need a provider installed.

Verification

  • Not locally compiled — this environment reliably OOM-kills on aws-sdk-ec2 transitively pulled into the workspace resolve regardless of which crate is targeted (cargo check -p oab-mcp -j 1 still OOMs on it), a known pre-existing limitation (same as fix(src-tauri): register missing Tauri command bridges for k8s onboarding tools (studio#104) #117/feat(deploy): wire k8s provider through New Fleet wizard submit (studio#104) #118's disclaimer, not something new here).
  • API usage double-checked against rustls 0.23.43 docs: rustls::crypto::aws_lc_rs::default_provider() -> CryptoProvider, CryptoProvider::install_default(self) -> Result<(), Arc<Self>> — both signatures confirmed via docs.rs. Feature flag confirmed against rustls' own Cargo.toml (aws-lc-rs = ["aws_lc_rs"] alias, aws_lc_rs does not imply std so it's added explicitly).
  • CI's build-test job is the real compile gate here.
  • Recommend Brett re-test the New Fleet → Kubernetes → orbstack → namespace-listing path for real after this merges — same "can't verify in this environment" caveat as prior k8s PRs.

Ref #119.

🤖 Generated with Claude Code

…e (studio#119)

studio-cp pulls in both rustls crypto backends transitively (kube's
rustls-tls -> hyper-rustls defaults to "ring"; the AWS SDK crates default
to "aws-lc-rs"), and nothing installed a process-level default. The first
real TLS handshake panicked on a tokio worker thread instead of returning
an error, which silently hung any k8s call that reaches TLS without going
through an exec-based auth step first (confirmed live: cert-based contexts
like orbstack never got a response back over the MCP wire; exec-based
contexts like GKE failed earlier, at the exec-spawn step, so never hit
this).

Install aws-lc-rs explicitly in OabMcp::from_env() (shared by both the
stdio binary and the in-process reverse-MCP tunnel), matching the backend
the AWS SDK side already uses.

Ref #119.
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.

1 participant