mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
428cd44154
## Why Rendezvous forwards traffic between the orchestrator and exec-server. The endpoints need to authenticate each other and encrypt that traffic without trusting Rendezvous with plaintext or endpoint keys. ## Changes - Adds a hybrid Noise IK channel through Clatter using X25519, ML-KEM-768, AES-256-GCM, and SHA-256. - Binds each handshake to `environment_id`, `executor_registration_id`, and `stream_id`. - Pins the registry-provided executor key and carries the harness authorization inside the encrypted handshake. - Orders relay frames before consuming Noise nonces and fragments large JSON-RPC messages into bounded records. - Bounds handshake payloads, frames, streams, and message reassembly. Runtime activation is in [openai/codex#26245](https://github.com/openai/codex/pull/26245). ## Stack 1. **[openai/codex#26242](https://github.com/openai/codex/pull/26242)**: Noise channel and relay transport 2. [openai/codex#26245](https://github.com/openai/codex/pull/26245): remote registration and runtime activation ## Verification - `just test -p codex-exec-server` - Oversized initiator payload regression coverage - `just fix -p codex-exec-server` - `just bazel-lock-check` - `cargo shear` --------- Co-authored-by: Codex <noreply@openai.com>
53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
use pretty_assertions::assert_eq;
|
|
|
|
use super::MAX_PENDING_BYTES;
|
|
use super::OrderedCiphertextFrames;
|
|
|
|
#[test]
|
|
fn releases_ciphertexts_only_in_nonce_order() {
|
|
let mut frames = OrderedCiphertextFrames::default();
|
|
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 1, b"second".to_vec()).unwrap(),
|
|
Vec::<Vec<u8>>::new()
|
|
);
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 0, b"first".to_vec()).unwrap(),
|
|
vec![b"first".to_vec(), b"second".to_vec()]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn ignores_duplicate_ciphertexts_without_replacing_buffered_record() {
|
|
let mut frames = OrderedCiphertextFrames::default();
|
|
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 1, b"first copy".to_vec()).unwrap(),
|
|
Vec::<Vec<u8>>::new()
|
|
);
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 1, b"replacement".to_vec()).unwrap(),
|
|
Vec::<Vec<u8>>::new()
|
|
);
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 0, b"zero".to_vec()).unwrap(),
|
|
vec![b"zero".to_vec(), b"first copy".to_vec()]
|
|
);
|
|
assert_eq!(
|
|
frames.push(/*seq*/ 0, b"duplicate".to_vec()).unwrap(),
|
|
Vec::<Vec<u8>>::new()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn rejects_unbounded_reordering() {
|
|
let mut frames = OrderedCiphertextFrames::default();
|
|
|
|
assert!(frames.push(/*seq*/ 65, Vec::new()).is_err());
|
|
assert!(
|
|
frames
|
|
.push(/*seq*/ 1, vec![0; MAX_PENDING_BYTES + 1])
|
|
.is_err()
|
|
);
|
|
}
|