mirror of
https://github.com/openai/codex.git
synced 2026-11-05 20:10:33 +00:00
Add direct SigV4 transport to exec-server (#42781)
## Why Allow remote exec servers to connect directly to AWS-hosted registries that authenticate registry requests and WebSocket handshakes with AWS SigV4. ## What changed - Add `--remote-transport direct` with SigV4 profile, region, and service options while keeping Noise as the default transport. - Register the `direct_jsonrpc_v1` transport and carry plain exec-server JSON-RPC messages over the authenticated WebSocket. - Reuse direct registrations across transient disconnects, refresh them after a `409 Conflict`, and require TLS for non-loopback endpoints. ## Testing - Cover CLI validation and SigV4 request signing. - Exercise direct registration, handshake retry behavior, JSON-RPC interoperability, and process recovery after reconnecting. GitOrigin-RevId: 0755df330ba3abe5db0a516fdaa49338d9bbe2d2
This commit is contained in:
@@ -144,30 +144,7 @@ impl ExecServerHarness {
|
||||
pub(crate) async fn disconnectable_websocket_proxy(
|
||||
&self,
|
||||
) -> anyhow::Result<DisconnectableWebSocketProxy> {
|
||||
let upstream = self
|
||||
.websocket_url
|
||||
.strip_prefix("ws://")
|
||||
.ok_or_else(|| anyhow!("exec-server websocket URL must use ws://"))?
|
||||
.to_string();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let websocket_url = format!("ws://{}", listener.local_addr()?);
|
||||
let (pause_tx, pause_rx) = oneshot::channel();
|
||||
let (blocked_connection_tx, blocked_connection_rx) = oneshot::channel();
|
||||
let (resume_tx, resume_rx) = oneshot::channel();
|
||||
let task = tokio::spawn(run_disconnectable_proxy(
|
||||
listener,
|
||||
upstream,
|
||||
pause_rx,
|
||||
blocked_connection_tx,
|
||||
resume_rx,
|
||||
));
|
||||
Ok(DisconnectableWebSocketProxy {
|
||||
websocket_url,
|
||||
pause_tx: Some(pause_tx),
|
||||
blocked_connection_rx: Some(blocked_connection_rx),
|
||||
resume_tx: Some(resume_tx),
|
||||
task,
|
||||
})
|
||||
DisconnectableWebSocketProxy::new(&self.websocket_url).await
|
||||
}
|
||||
|
||||
pub(crate) async fn send_request(
|
||||
@@ -278,6 +255,33 @@ impl ExecServerHarness {
|
||||
}
|
||||
|
||||
impl DisconnectableWebSocketProxy {
|
||||
pub(crate) async fn new(websocket_url: &str) -> anyhow::Result<Self> {
|
||||
let upstream = websocket_url
|
||||
.strip_prefix("ws://")
|
||||
.ok_or_else(|| anyhow!("exec-server websocket URL must use ws://"))?
|
||||
.trim_end_matches('/')
|
||||
.to_string();
|
||||
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
||||
let websocket_url = format!("ws://{}", listener.local_addr()?);
|
||||
let (pause_tx, pause_rx) = oneshot::channel();
|
||||
let (blocked_connection_tx, blocked_connection_rx) = oneshot::channel();
|
||||
let (resume_tx, resume_rx) = oneshot::channel();
|
||||
let task = tokio::spawn(run_disconnectable_proxy(
|
||||
listener,
|
||||
upstream,
|
||||
pause_rx,
|
||||
blocked_connection_tx,
|
||||
resume_rx,
|
||||
));
|
||||
Ok(DisconnectableWebSocketProxy {
|
||||
websocket_url,
|
||||
pause_tx: Some(pause_tx),
|
||||
blocked_connection_rx: Some(blocked_connection_rx),
|
||||
resume_tx: Some(resume_tx),
|
||||
task,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn websocket_url(&self) -> &str {
|
||||
&self.websocket_url
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user