use serde_json::{json, Value}; pub const COORDINATOR_PROTOCOL_VERSION: u64 = 1; pub const COORDINATOR_WIRE_REQUEST_TYPE: &str = "coordinator_request"; pub fn coordinator_wire_request(request_id: impl Into, payload: Value) -> Value { let operation = coordinator_payload_operation(&payload); let authentication = coordinator_authentication_metadata(&payload); json!({ "type": COORDINATOR_WIRE_REQUEST_TYPE, "protocol_version": COORDINATOR_PROTOCOL_VERSION, "request_id": request_id.into(), "operation": operation, "authentication": authentication, "payload": payload, }) } pub fn coordinator_payload_operation(payload: &Value) -> String { payload .get("type") .and_then(Value::as_str) .unwrap_or("unknown") .to_owned() } pub fn coordinator_authentication_metadata(payload: &Value) -> Value { let operation = coordinator_payload_operation(payload); match operation.as_str() { "authenticated" => json!({ "kind": "cli_session", "session": true, "request_operation": payload .get("request") .map(coordinator_payload_operation) .unwrap_or_else(|| "unknown".to_owned()), }), "signed_node" => json!({ "kind": "node_signature", "node": payload.get("node").and_then(Value::as_str), }), "node_heartbeat" if payload.get("node_signature").is_some() => json!({ "kind": "node_signature", "node": payload.get("node").and_then(Value::as_str), }), "start_process" | "launch_task" if payload.get("agent_signature").is_some() => json!({ "kind": "agent_signature", "agent": payload.get("actor_agent").and_then(Value::as_str), "fingerprint": payload.get("agent_public_key_fingerprint").and_then(Value::as_str), }), "admin_status" | "suspend_tenant" if payload.get("admin_proof").is_some() => json!({ "kind": "admin_proof", "actor": payload.get("actor_user").and_then(Value::as_str), "nonce": payload.get("admin_nonce").and_then(Value::as_str), "issued_at_epoch_seconds": payload.get("issued_at_epoch_seconds").and_then(Value::as_u64), }), "exchange_node_enrollment_grant" => json!({ "kind": "node_enrollment_grant", "node": payload.get("node").and_then(Value::as_str), }), _ => json!({ "kind": "none", }), } } #[cfg(test)] mod tests { use super::*; #[test] fn coordinator_wire_request_wraps_payload_without_exposing_secret_metadata() { let envelope = coordinator_wire_request( "cli-1", json!({ "type": "authenticated", "session_secret": "secret-value", "request": { "type": "list_projects" }, }), ); assert_eq!(envelope["type"], COORDINATOR_WIRE_REQUEST_TYPE); assert_eq!(envelope["protocol_version"], COORDINATOR_PROTOCOL_VERSION); assert_eq!(envelope["request_id"], "cli-1"); assert_eq!(envelope["operation"], "authenticated"); assert_eq!(envelope["authentication"]["kind"], "cli_session"); assert_eq!( envelope["authentication"]["request_operation"], "list_projects" ); assert_eq!(envelope["authentication"].get("session_secret"), None); assert_eq!(envelope["payload"]["session_secret"], "secret-value"); } #[test] fn coordinator_wire_request_describes_signature_metadata() { let envelope = coordinator_wire_request( "node-1", json!({ "type": "signed_node", "node": "node-a", "node_signature": { "nonce": "nonce", "issued_at_epoch_seconds": 1, "signature": "ed25519:sig" }, "request": { "type": "poll_task_assignment", "node": "node-a" }, }), ); assert_eq!(envelope["authentication"]["kind"], "node_signature"); assert_eq!(envelope["authentication"]["node"], "node-a"); } }