Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion codex-rs/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ workspace = true

[dependencies]
anyhow = { workspace = true }
clap = { workspace = true, features = ["derive"] }
clap = { workspace = true, features = ["derive", "env"] }
clap_complete = { workspace = true }
codex-app-server = { workspace = true }
codex-app-server-daemon = { workspace = true }
Expand Down
35 changes: 35 additions & 0 deletions codex-rs/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,14 @@ struct ExecServerCommand {
/// Use Agent Identity auth from CODEX_ACCESS_TOKEN for remote registration.
#[arg(long = "use-agent-identity-auth", requires = "remote")]
use_agent_identity_auth: bool,

/// Opt into Noise-encrypted remote relay communication.
#[arg(
long = "enable-noise",
env = "CODEX_EXEC_SERVER_ENABLE_NOISE",
requires = "remote"
)]
enable_noise: bool,
}

#[derive(Debug, clap::Subcommand)]
Expand Down Expand Up @@ -1611,6 +1619,9 @@ async fn run_exec_server_command(
if let Some(name) = cmd.name {
remote_config.name = name;
}
if cmd.enable_noise {
remote_config.relay_protocol = codex_exec_server::RemoteRelayProtocol::Noise;
}
codex_exec_server::run_remote_environment(remote_config, runtime_paths).await?;
Ok(())
} else {
Expand Down Expand Up @@ -3222,6 +3233,30 @@ mod tests {
.expect("exec-server should support root --strict-config");
}

#[test]
fn exec_server_enable_noise_is_explicit_remote_opt_in() {
let cli = MultitoolCli::try_parse_from([
"codex",
"exec-server",
"--remote",
"https://registry.example",
"--environment-id",
"environment-1",
"--enable-noise",
])
.expect("parse");

assert_matches!(
cli.subcommand,
Some(Subcommand::ExecServer(ExecServerCommand {
enable_noise: true,
..
}))
);
MultitoolCli::try_parse_from(["codex", "exec-server", "--enable-noise"])
.expect_err("--enable-noise should require --remote");
}

#[test]
fn root_strict_config_is_rejected_for_unsupported_subcommands() {
let cli = MultitoolCli::try_parse_from(["codex", "--strict-config", "mcp", "list"])
Expand Down
10 changes: 8 additions & 2 deletions codex-rs/exec-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ the wire.
The CLI entrypoint supports:

- `ws://IP:PORT` (default)
- `--remote URL --environment-id ID [--name NAME]`
- `--remote URL --environment-id ID [--name NAME] [--enable-noise]`

Remote mode registers the local exec-server with the environment registry,
then reconnects to the service-provided rendezvous websocket as the environment.
It uses the legacy relay contract by default for compatibility with existing
registries and harnesses. `--enable-noise` explicitly opts into Noise-encrypted
relay registration and requires both the registry and harness to support the
Noise relay contract. Container entrypoints can make the same explicit choice
by setting `CODEX_EXEC_SERVER_ENABLE_NOISE=true`.
It uses the standard Codex ChatGPT sign-in state; run `codex login` first when
remote registration needs authentication. Containerized callers that receive an
Agent Identity JWT in `CODEX_ACCESS_TOKEN` can opt into that auth path with
Expand All @@ -45,7 +50,8 @@ codex exec-server \
Wire framing:

- local websocket: one JSON-RPC message per websocket frame
- remote websocket: binary protobuf relay frames carrying JSON-RPC payloads
- legacy remote websocket: binary protobuf relay frames carrying JSON-RPC payloads
- Noise remote websocket: binary protobuf relay frames carrying encrypted payloads

## Remote Relay Message Format

Expand Down
1 change: 1 addition & 0 deletions codex-rs/exec-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ pub use protocol::WriteParams;
pub use protocol::WriteResponse;
pub use protocol::WriteStatus;
pub use remote::RemoteEnvironmentConfig;
pub use remote::RemoteRelayProtocol;
pub use remote::run_remote_environment;
pub use runtime_paths::ExecServerRuntimePaths;
pub use server::DEFAULT_LISTEN_URL;
Expand Down
Loading
Loading