diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab1fa2e7a..889cbeef0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -306,7 +306,7 @@ echo 'eval "$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc Project requirements: -- Rust 1.90+ +- Rust 1.94+ - Python 3.11+ - Docker (running) - CMake 3.16+ (only required when building with the `bundled-z3` feature) diff --git a/Cargo.lock b/Cargo.lock index fdd622b55..45410007e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,7 +127,7 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -138,7 +138,7 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -228,6 +228,40 @@ dependencies = [ "serde_json", ] +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "async-trait" version = "0.1.89" @@ -445,7 +479,7 @@ dependencies = [ "rustls-pki-types", "tokio", "tokio-rustls", - "tower 0.5.3", + "tower", "tracing", ] @@ -602,7 +636,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ "axum-core", - "base64 0.22.1", + "base64", "bytes", "form_urlencoded", "futures-util", @@ -625,7 +659,7 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-tungstenite 0.29.0", - "tower 0.5.3", + "tower", "tower-layer", "tower-service", "tracing", @@ -651,14 +685,14 @@ dependencies = [ ] [[package]] -name = "backoff" -version = "0.4.0" +name = "backon" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ - "getrandom 0.2.17", - "instant", - "rand 0.8.6", + "fastrand", + "gloo-timers", + "tokio", ] [[package]] @@ -697,12 +731,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.1" @@ -804,7 +832,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee04c4c84f1f811b017f2fbb7dd8815c976e7ca98593de9c1e2afad0f636bff4" dependencies = [ - "base64 0.22.1", + "base64", "bollard-stubs", "bytes", "futures-core", @@ -1523,17 +1551,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive_builder" version = "0.20.2" @@ -1719,6 +1736,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "either" version = "1.15.0" @@ -1777,6 +1806,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "enum-ordinalize" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.5", +] + [[package]] name = "enum_dispatch" version = "0.3.13" @@ -1822,18 +1871,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "etcetera" -version = "0.8.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +checksum = "de48cc4d1c1d97a20fd819def54b890cadde72ed3ad0c614822a0a433361be96" dependencies = [ "cfg-if", - "home", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -1847,6 +1895,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.4.1" @@ -1920,9 +1978,9 @@ dependencies = [ [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ "futures-core", "futures-sink", @@ -2178,6 +2236,18 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "group" version = "0.13.0" @@ -2224,10 +2294,6 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "hashbrown" @@ -2246,6 +2312,8 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" dependencies = [ + "allocator-api2", + "equivalent", "foldhash 0.2.0", ] @@ -2257,11 +2325,35 @@ checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" [[package]] name = "hashlink" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" dependencies = [ - "hashbrown 0.15.5", + "hashbrown 0.16.1", +] + +[[package]] +name = "headers" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb" +dependencies = [ + "base64", + "bytes", + "headers-core", + "http 1.4.0", + "httpdate", + "mime", + "sha1 0.10.6", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.4.0", ] [[package]] @@ -2352,6 +2444,17 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "hostname" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd" +dependencies = [ + "cfg-if", + "libc", + "windows-link", +] + [[package]] name = "http" version = "0.2.12" @@ -2462,6 +2565,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-http-proxy" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd1d471ea2f65ba45eddb1d6ab7d58ac2671d2d4ac14da5c6516ae1d97e1327a" +dependencies = [ + "bytes", + "futures-util", + "headers", + "http 1.4.0", + "hyper", + "hyper-rustls", + "hyper-util", + "pin-project-lite", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-named-pipe" version = "0.1.0" @@ -2513,7 +2635,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-util", @@ -2758,15 +2880,6 @@ dependencies = [ "hybrid-array", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - [[package]] name = "internal-russh-num-bigint" version = "0.5.0" @@ -2957,18 +3070,38 @@ dependencies = [ ] [[package]] -name = "jsonpath-rust" -version = "0.5.1" +name = "json-patch" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19d8fe85bd70ff715f31ce8c739194b423d79811a19602115d611a3ec85d6200" +checksum = "7421438de105a0827e44fadd05377727847d717c80ce29a229f85fd04c427b72" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "jsonpath-rust" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c00ae348f9f8fd2d09f82a98ca381c60df9e0820d8d79fce43e649b4dc3128b" dependencies = [ - "lazy_static", - "once_cell", "pest", "pest_derive", "regex", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", +] + +[[package]] +name = "jsonptr" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe" +dependencies = [ + "serde", + "serde_json", ] [[package]] @@ -2978,7 +3111,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" dependencies = [ "aws-lc-rs", - "base64 0.22.1", + "base64", "ed25519-dalek 2.2.0", "getrandom 0.2.17", "hmac 0.12.1", @@ -2997,11 +3130,11 @@ dependencies = [ [[package]] name = "k8s-openapi" -version = "0.21.1" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "550f99d93aa4c2b25de527bce492d772caf5e21d7ac9bd4b508ba781c8d91e30" +checksum = "2c75b990324f09bef15e791606b7b7a296d02fc88a344f6eba9390970a870ad5" dependencies = [ - "base64 0.21.7", + "base64", "chrono", "serde", "serde-value", @@ -3065,9 +3198,9 @@ dependencies = [ [[package]] name = "kube" -version = "0.90.0" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bfada4e00dac93a7b94e454ae4cde04ff8786645ac1b98f31352272e2682b5" +checksum = "9a4eb20010536b48abe97fec37d23d43069bcbe9686adcf9932202327bc5ca6e" dependencies = [ "k8s-openapi", "kube-client", @@ -3078,11 +3211,11 @@ dependencies = [ [[package]] name = "kube-client" -version = "0.90.0" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0708306b5c0085f249f5e3d2d56a9bbfe0cbbf4fd4eb9ed4bbba542ba7649a7" +checksum = "7fc2ed952042df20d15ac2fe9614d0ec14b6118eab89633985d4b36e688dccf1" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "chrono", "either", @@ -3092,6 +3225,7 @@ dependencies = [ "http-body 1.0.1", "http-body-util", "hyper", + "hyper-http-proxy", "hyper-rustls", "hyper-timeout", "hyper-util", @@ -3100,70 +3234,73 @@ dependencies = [ "kube-core", "pem", "rustls", - "rustls-pemfile", "secrecy", "serde", "serde_json", "serde_yaml", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "tokio-util", - "tower 0.4.13", - "tower-http 0.5.2", + "tower", + "tower-http", "tracing", ] [[package]] name = "kube-core" -version = "0.90.0" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7845bcc3e0f422df4d9049570baedd9bc1942f0504594e393e72fe24092559cf" +checksum = "ff0d0793db58e70ca6d689489183816cb3aa481673e7433dc618cf7e8007c675" dependencies = [ "chrono", "form_urlencoded", "http 1.4.0", - "json-patch", + "json-patch 4.2.0", "k8s-openapi", "schemars", "serde", + "serde-value", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] name = "kube-derive" -version = "0.90.0" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d0d2527a6ff7adf00b34d558c4c5de9404abe28808cb0a4c64b57e2c1b0716a" +checksum = "c562f58dc9f7ca5feac8a6ee5850ca221edd6f04ce0dd2ee873202a88cd494c9" dependencies = [ "darling", "proc-macro2", "quote", + "serde", "serde_json", "syn 2.0.117", ] [[package]] name = "kube-runtime" -version = "0.90.0" +version = "0.99.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4560e2c5c71366f6dceb6500ce33cf72299aede92381bb875dc2d4ba4f102c21" +checksum = "88f34cfab9b4bd8633062e0e85edb81df23cb09f159f2e31c60b069ae826ffdc" dependencies = [ "ahash", + "async-broadcast", + "async-stream", "async-trait", - "backoff", - "derivative", + "backon", + "educe", "futures", - "hashbrown 0.14.5", - "json-patch", + "hashbrown 0.15.5", + "hostname", + "json-patch 4.2.0", "k8s-openapi", "kube-client", "parking_lot", "pin-project", "serde", "serde_json", - "smallvec", - "thiserror 1.0.69", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -3305,12 +3442,12 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "md-5" -version = "0.10.6" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "69b6441f590336821bb897fb28fc622898ccceb1d6cea3fde5ea86b090c4de98" dependencies = [ "cfg-if", - "digest 0.10.7", + "digest 0.11.2", ] [[package]] @@ -3341,7 +3478,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3589659543c04c7dc5526ec858591015b87cd8746583b51b48ef4353f99dbcda" dependencies = [ - "base64 0.22.1", + "base64", "http-body-util", "hyper", "hyper-util", @@ -3570,7 +3707,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -3657,7 +3794,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64 0.21.7", + "base64", "chrono", "getrandom 0.2.17", "http 1.4.0", @@ -3780,7 +3917,7 @@ name = "openshell-cli" version = "0.0.0" dependencies = [ "anyhow", - "base64 0.22.1", + "base64", "bytes", "chrono", "clap", @@ -3821,7 +3958,7 @@ dependencies = [ "tokio-stream", "tokio-tungstenite 0.26.2", "tonic", - "tower 0.5.3", + "tower", "tracing", "tracing-subscriber", "url", @@ -3855,7 +3992,7 @@ name = "openshell-core" version = "0.0.0" dependencies = [ "async-trait", - "base64 0.22.1", + "base64", "chrono", "glob", "ipnet", @@ -3889,10 +4026,10 @@ name = "openshell-driver-db-credstore" version = "0.0.0" dependencies = [ "async-trait", - "base64 0.22.1", + "aws-lc-rs", + "base64", "futures", "openshell-core", - "ring", "serde", "serde_json", "sha2 0.10.9", @@ -3927,7 +4064,7 @@ dependencies = [ "tokio-stream", "toml", "tonic", - "tower-http 0.6.8", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", @@ -3964,7 +4101,7 @@ dependencies = [ "tokio-stream", "toml", "tonic", - "tower 0.5.3", + "tower", "tracing", "tracing-subscriber", ] @@ -3992,7 +4129,7 @@ dependencies = [ name = "openshell-driver-mxc" version = "0.0.0" dependencies = [ - "base64 0.22.1", + "base64", "futures", "noyalib", "openshell-core", @@ -4034,7 +4171,7 @@ dependencies = [ "tokio", "tokio-stream", "tonic", - "tower-http 0.6.8", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", @@ -4050,6 +4187,7 @@ dependencies = [ "miette", "openshell-core", "reqwest 0.12.28", + "rustls", "serde", "serde_json", "sha2 0.10.9", @@ -4097,7 +4235,7 @@ dependencies = [ "tokio", "tokio-stream", "tonic", - "tower-http 0.6.8", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", @@ -4119,7 +4257,7 @@ dependencies = [ "tokio", "tokio-stream", "tonic", - "tower 0.5.3", + "tower", ] [[package]] @@ -4142,7 +4280,7 @@ dependencies = [ "tempfile", "tokio", "tonic", - "tower 0.5.3", + "tower", "tracing", ] @@ -4150,7 +4288,7 @@ dependencies = [ name = "openshell-gateway-interceptors" version = "0.0.0" dependencies = [ - "json-patch", + "json-patch 1.4.0", "metrics", "openshell-core", "openshell-extension-core", @@ -4190,7 +4328,7 @@ dependencies = [ "thiserror 2.0.18", "tokio", "tonic", - "tower-http 0.6.8", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", @@ -4257,6 +4395,7 @@ dependencies = [ "noyalib", "openshell-core", "reqwest 0.12.28", + "rustls", "serde", "serde_json", "tempfile", @@ -4320,7 +4459,7 @@ dependencies = [ "tokio-stream", "tokio-tungstenite 0.26.2", "tonic", - "tower 0.5.3", + "tower", "tracing", "wiremock", ] @@ -4335,7 +4474,7 @@ dependencies = [ "aws-config", "aws-sdk-sts", "axum", - "base64 0.22.1", + "base64", "bytes", "clap", "futures", @@ -4383,7 +4522,6 @@ dependencies = [ "rand 0.9.4", "rcgen", "reqwest 0.12.28", - "ring", "rsa 0.9.10", "russh", "rustix 1.1.4", @@ -4395,6 +4533,7 @@ dependencies = [ "socket2", "spiffe", "sqlx", + "sqlx-core", "tempfile", "thiserror 2.0.18", "tokio", @@ -4403,8 +4542,8 @@ dependencies = [ "tokio-tungstenite 0.26.2", "toml", "tonic", - "tower 0.5.3", - "tower-http 0.6.8", + "tower", + "tower-http", "tracing", "tracing-opentelemetry", "tracing-subscriber", @@ -4463,7 +4602,7 @@ dependencies = [ "aws-credential-types", "aws-sigv4", "aws-smithy-runtime-api", - "base64 0.22.1", + "base64", "bytes", "flate2", "futures", @@ -4513,7 +4652,7 @@ name = "openshell-supervisor-process" version = "0.0.0" dependencies = [ "anyhow", - "base64 0.22.1", + "base64", "bytes", "capctl", "hex", @@ -4545,7 +4684,7 @@ dependencies = [ name = "openshell-tui" version = "0.0.0" dependencies = [ - "base64 0.22.1", + "base64", "crossterm 0.28.1", "indexmap", "miette", @@ -4820,7 +4959,7 @@ version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be" dependencies = [ - "base64 0.22.1", + "base64", "serde_core", ] @@ -5223,7 +5362,7 @@ version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01b80ea363c31af2de2b92e3c07ed1156628f7838c4afb4df75ee78a37fedbd1" dependencies = [ - "base64 0.22.1", + "base64", "prost", "prost-types", "serde", @@ -5545,8 +5684,8 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" dependencies = [ + "aws-lc-rs", "pem", - "ring", "rustls-pki-types", "time", "yasna", @@ -5630,7 +5769,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-channel", "futures-core", @@ -5645,7 +5784,6 @@ dependencies = [ "log", "percent-encoding", "pin-project-lite", - "quinn", "rustls", "rustls-native-certs", "rustls-pki-types", @@ -5655,8 +5793,8 @@ dependencies = [ "sync_wrapper", "tokio", "tokio-rustls", - "tower 0.5.3", - "tower-http 0.6.8", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", @@ -5670,7 +5808,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ - "base64 0.22.1", + "base64", "bytes", "futures-core", "futures-util", @@ -5695,8 +5833,8 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-util", - "tower 0.5.3", - "tower-http 0.6.8", + "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", @@ -5945,7 +6083,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5957,7 +6095,6 @@ dependencies = [ "aws-lc-rs", "log", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -6013,7 +6150,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6155,11 +6292,10 @@ dependencies = [ [[package]] name = "secrecy" -version = "0.8.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a" dependencies = [ - "serde", "zeroize", ] @@ -6528,7 +6664,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6554,7 +6690,7 @@ dependencies = [ "tokio-util", "tonic", "tonic-prost", - "tower 0.5.3", + "tower", "tracing", "url", "zeroize", @@ -6597,9 +6733,9 @@ checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "sqlx" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" +checksum = "378620ccc25c62c89d8be1c819e76a88d59bdcc3304733330788948e619bfd71" dependencies = [ "sqlx-core", "sqlx-macros", @@ -6610,12 +6746,13 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" +checksum = "05b44e85bf579a8eeb4ceaa77a3a523baf2bf0e9bac7e40f405d537b5d2d5ccb" dependencies = [ - "base64 0.22.1", + "base64", "bytes", + "cfg-if", "crc", "crossbeam-queue", "either", @@ -6624,12 +6761,11 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", - "hashbrown 0.15.5", + "hashbrown 0.16.1", "hashlink", "indexmap", "log", "memchr", - "once_cell", "percent-encoding", "rustls", "rustls-native-certs", @@ -6642,13 +6778,14 @@ dependencies = [ "tokio-stream", "tracing", "url", + "webpki-roots", ] [[package]] name = "sqlx-macros" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" +checksum = "bd2b84f2bc39a5705ef27ec785a11c934a41bbd4a24941e257927cddc26b60bf" dependencies = [ "proc-macro2", "quote", @@ -6659,15 +6796,15 @@ dependencies = [ [[package]] name = "sqlx-macros-core" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" +checksum = "fb8d96de5fdc85a5c4ec813432b523ec637e80ba98f046555f75f7908ddac7c3" dependencies = [ + "cfg-if", "dotenvy", "either", "heck", "hex", - "once_cell", "proc-macro2", "quote", "serde", @@ -6677,59 +6814,45 @@ dependencies = [ "sqlx-postgres", "sqlx-sqlite", "syn 2.0.117", + "thiserror 2.0.18", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" +checksum = "90b8020fe17c5f2c245bfa2505d7ef59c5604839527c740266ad2214acebea27" dependencies = [ - "atoi", - "base64 0.22.1", "bitflags 2.11.1", "byteorder", "bytes", "crc", - "digest 0.10.7", + "digest 0.11.2", "dotenvy", "either", - "futures-channel", "futures-core", - "futures-io", "futures-util", "generic-array 0.14.7", - "hex", - "hkdf 0.12.4", - "hmac 0.12.1", - "itoa", "log", - "md-5", - "memchr", - "once_cell", "percent-encoding", - "rand 0.8.6", - "rsa 0.9.10", - "sha1 0.10.6", - "sha2 0.10.9", - "smallvec", + "serde", + "sha1 0.11.0", + "sha2 0.11.0", "sqlx-core", - "stringprep", "thiserror 2.0.18", "tracing", - "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" +checksum = "87a2bdd6e83f6b3ea525ca9fee568030508b58355a43d0b2c1674d5f79dcd65e" dependencies = [ "atoi", - "base64 0.22.1", + "base64", "bitflags 2.11.1", "byteorder", "crc", @@ -6739,18 +6862,16 @@ dependencies = [ "futures-core", "futures-util", "hex", - "hkdf 0.12.4", - "hmac 0.12.1", - "home", + "hkdf 0.13.0", + "hmac 0.13.0", "itoa", "log", "md-5", "memchr", - "once_cell", - "rand 0.8.6", + "rand 0.10.2", "serde", "serde_json", - "sha2 0.10.9", + "sha2 0.11.0", "smallvec", "sqlx-core", "stringprep", @@ -6761,12 +6882,13 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.6" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" +checksum = "488e99c397a62007e4229aec669a179816339afc6d2620ca6fa420dbee2e982c" dependencies = [ "atoi", "flume", + "form_urlencoded", "futures-channel", "futures-core", "futures-executor", @@ -6776,7 +6898,6 @@ dependencies = [ "log", "percent-encoding", "serde", - "serde_urlencoded", "sqlx-core", "thiserror 2.0.18", "tracing", @@ -6956,9 +7077,9 @@ checksum = "a7973cce6668464ea31f176d85b13c7ab3bba2cb3b77a2ed26abd7801688010a" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -6967,9 +7088,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" dependencies = [ "proc-macro2", "quote", @@ -7026,7 +7147,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -7062,7 +7183,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -7326,7 +7447,7 @@ checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "axum", - "base64 0.22.1", + "base64", "bytes", "h2", "http 1.4.0", @@ -7343,7 +7464,7 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-stream", - "tower 0.5.3", + "tower", "tower-layer", "tower-service", "tracing", @@ -7399,23 +7520,6 @@ dependencies = [ "tonic", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.3" @@ -7435,39 +7539,22 @@ dependencies = [ "tracing", ] -[[package]] -name = "tower-http" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" -dependencies = [ - "base64 0.21.7", - "bitflags 2.11.1", - "bytes", - "http 1.4.0", - "http-body 1.0.1", - "http-body-util", - "mime", - "pin-project-lite", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower-http" version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ + "base64", "bitflags 2.11.1", "bytes", "futures-util", "http 1.4.0", "http-body 1.0.1", "iri-string", + "mime", "pin-project-lite", - "tower 0.5.3", + "tower", "tower-layer", "tower-service", "tracing", @@ -7486,7 +7573,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6511f1f32c7cb7fd4525edc0eb4dcf307db8f7eceb2833ab24a37b4cc10cda61" dependencies = [ - "base64 0.22.1", + "base64", "serde", "serde_json", "thiserror 2.0.18", @@ -7871,12 +7958,6 @@ dependencies = [ "wit-bindgen 0.51.0", ] -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - [[package]] name = "wasm-bindgen" version = "0.2.118" @@ -8019,13 +8100,9 @@ dependencies = [ [[package]] name = "whoami" -version = "1.6.1" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" -dependencies = [ - "libredox", - "wasite", -] +checksum = "626c4bac6755d76ffc12cb01b2eac751db1996b9e0041de9aa02c8c211ddc82c" [[package]] name = "winapi" @@ -8049,7 +8126,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] @@ -8481,7 +8558,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08db1edfb05d9b3c1542e521aea074442088292f00b5f28e435c714a98f85031" dependencies = [ "assert-json-diff", - "base64 0.22.1", + "base64", "deadpool", "futures", "http 1.4.0", diff --git a/Cargo.toml b/Cargo.toml index 47418d0fc..dcf698e2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ members = ["crates/*"] [workspace.package] version = "0.0.0" edition = "2024" -rust-version = "1.90" +rust-version = "1.94" license = "Apache-2.0" repository = "https://github.com/NVIDIA/OpenShell" @@ -35,10 +35,10 @@ http-body = "1.0" http-body-util = "0.1" # TLS -tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "ring"] } -rustls = { version = "0.23", default-features = false, features = ["std", "logging", "tls12", "ring"] } +tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "tls12", "aws_lc_rs"] } +rustls = { version = "0.23", default-features = false, features = ["std", "logging", "tls12", "aws_lc_rs"] } rustls-pemfile = "2" -rcgen = { version = "0.13", features = ["crypto", "pem"] } +rcgen = { version = "0.13", default-features = false, features = ["crypto", "pem", "aws_lc_rs"] } webpki-roots = "1" rustls-native-certs = "0.8" @@ -87,7 +87,7 @@ tower-mcp-types = "0.12.0" regex = "1" # HTTP client -reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls-native-roots"] } +reqwest = { version = "0.12.28", default-features = false, features = ["json", "rustls-tls-native-roots-no-provider"] } # AWS SDK aws-config = { version = "1", default-features = false, features = ["default-https-client", "rt-tokio", "behavior-version-latest"] } @@ -104,7 +104,7 @@ sha2 = "0.10" rand = "0.9" jsonwebtoken = { version = "10", features = ["aws_lc_rs"] } getrandom = "0.3" -ring = "0.17" +aws-lc-rs = "1.16" spiffe = { version = "0.15", default-features = false, features = ["workload-api-jwt", "jwt-verify-rust-crypto", "tracing"] } # Filesystem embedding @@ -124,12 +124,14 @@ url = "2" indexmap = "2" # Database -sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "tls-rustls-ring-native-roots", "postgres", "sqlite", "migrate", "macros"] } +sqlx = { version = "0.9", default-features = false, features = ["runtime-tokio", "tls-rustls-aws-lc-rs", "postgres", "sqlite", "migrate", "macros"] } +# SQLx's facade couples native roots to ring; select native roots independently. +sqlx-core = { version = "0.9", default-features = false, features = ["rustls-native-certs"] } # Kubernetes -kube = { version = "0.90", default-features = false, features = ["client", "runtime", "derive", "rustls-tls"] } -kube-runtime = "0.90" -k8s-openapi = { version = "0.21.1", features = ["v1_26"] } +kube = { version = "0.99", default-features = false, features = ["client", "runtime", "derive", "rustls-tls", "aws-lc-rs"] } +kube-runtime = "0.99" +k8s-openapi = { version = "0.24", features = ["v1_29"] } # IDs uuid = { version = "1.10", features = ["v4"] } diff --git a/architecture/build.md b/architecture/build.md index 4365356f9..5f371f8f1 100644 --- a/architecture/build.md +++ b/architecture/build.md @@ -25,6 +25,16 @@ Sandbox community images are built outside this repository. ## Build Features +Rust builds require Rust 1.94 or newer. TLS and certificate generation use +AWS-LC, including the CLI and standalone examples. Native and cross-build +environments must provide the C toolchain required by aws-lc-sys; the Nix +development shells provide static AWS-LC libraries. + +SQLx uses AWS-LC with native certificate roots. The server enables +`sqlx-core/rustls-native-certs` directly because SQLx's facade does not expose +that root selection independently of the crypto provider. Credential storage +continues to use the same AES-256-GCM envelope format across backend changes. + Anonymous telemetry emission is gated behind a default-on `telemetry` Cargo feature. It is defined in `openshell-core` (where the emission code, HTTP client, and endpoint live) and forwarded by the binary crates that emit or diff --git a/crates/openshell-cli/Cargo.toml b/crates/openshell-cli/Cargo.toml index ddaf09f88..9a803b77d 100644 --- a/crates/openshell-cli/Cargo.toml +++ b/crates/openshell-cli/Cargo.toml @@ -49,7 +49,7 @@ bytes = { workspace = true } http-body-util = { workspace = true } hyper = { workspace = true } hyper-util = { workspace = true } -hyper-rustls = { version = "0.27", default-features = false, features = ["native-tokio", "http1", "http2", "tls12", "logging", "ring"] } +hyper-rustls = { version = "0.27", default-features = false, features = ["native-tokio", "http1", "http2", "tls12", "logging", "aws-lc-rs"] } rustls = { workspace = true } rustls-pemfile = { workspace = true } tokio-rustls = { workspace = true } @@ -91,7 +91,7 @@ nix = { workspace = true } [dev-dependencies] futures = { workspace = true } -rcgen = { version = "0.13", features = ["crypto", "pem"] } +rcgen = { workspace = true } reqwest = { workspace = true } serde_json = { workspace = true } temp-env = "0.3" diff --git a/crates/openshell-cli/src/auth.rs b/crates/openshell-cli/src/auth.rs index 56601e2a3..bc1baae26 100644 --- a/crates/openshell-cli/src/auth.rs +++ b/crates/openshell-cli/src/auth.rs @@ -35,7 +35,7 @@ use tokio::sync::oneshot; use tracing::debug; /// Timeout for the browser auth flow. -const AUTH_TIMEOUT: Duration = Duration::from_secs(120); +const AUTH_TIMEOUT: Duration = Duration::from_mins(2); /// Length of the confirmation code (alphanumeric characters). const CODE_LENGTH: usize = 7; diff --git a/crates/openshell-cli/src/commands/gateway.rs b/crates/openshell-cli/src/commands/gateway.rs index 0a7950050..0e1fe9242 100644 --- a/crates/openshell-cli/src/commands/gateway.rs +++ b/crates/openshell-cli/src/commands/gateway.rs @@ -1970,7 +1970,6 @@ mod tests { #[test] fn gateway_add_registers_plaintext_loopback_gateway_without_local_flag() { - let _ = rustls::crypto::ring::default_provider().install_default(); let tmpdir = tempfile::tempdir().expect("create tmpdir"); with_tmp_xdg(tmpdir.path(), || { let runtime = tokio::runtime::Runtime::new().expect("create runtime"); @@ -2002,7 +2001,6 @@ mod tests { #[test] fn gateway_add_respects_local_flag_for_plaintext_registrations() { - let _ = rustls::crypto::ring::default_provider().install_default(); let tmpdir = tempfile::tempdir().expect("create tmpdir"); with_tmp_xdg(tmpdir.path(), || { let runtime = tokio::runtime::Runtime::new().expect("create runtime"); @@ -2032,7 +2030,6 @@ mod tests { #[tokio::test] async fn http_health_check_supports_plain_http_endpoints() { - let _ = rustls::crypto::ring::default_provider().install_default(); let listener = TcpListener::bind("127.0.0.1:0").expect("bind listener"); let addr = listener.local_addr().expect("listener addr"); let server = thread::spawn(move || { @@ -2061,7 +2058,6 @@ mod tests { #[test] fn gateway_add_oidc_rolls_back_on_auth_failure() { - let _ = rustls::crypto::ring::default_provider().install_default(); let tmpdir = tempfile::tempdir().expect("create tmpdir"); with_tmp_xdg(tmpdir.path(), || { let runtime = tokio::runtime::Runtime::new().expect("create runtime"); @@ -2118,7 +2114,6 @@ mod tests { } #[test] fn gateway_add_oidc_rollback_keeps_system_active_fallback_userless() { - let _ = rustls::crypto::ring::default_provider().install_default(); let user = tempfile::tempdir().expect("create user tmpdir"); let system = tempfile::tempdir().expect("create system tmpdir"); with_tmp_xdg_and_system(user.path(), system.path(), || { @@ -2159,7 +2154,6 @@ mod tests { #[test] fn gateway_add_cloud_rolls_back_on_auth_failure() { - let _ = rustls::crypto::ring::default_provider().install_default(); let tmpdir = tempfile::tempdir().expect("create tmpdir"); with_tmp_xdg(tmpdir.path(), || { let _no_browser = EnvVarGuard::set("OPENSHELL_NO_BROWSER", "0"); @@ -2217,7 +2211,6 @@ mod tests { } #[test] fn gateway_add_cloud_rollback_keeps_system_active_fallback_userless() { - let _ = rustls::crypto::ring::default_provider().install_default(); let user = tempfile::tempdir().expect("create user tmpdir"); let system = tempfile::tempdir().expect("create system tmpdir"); with_tmp_xdg_and_system(user.path(), system.path(), || { diff --git a/crates/openshell-cli/src/main.rs b/crates/openshell-cli/src/main.rs index a07083862..b481fa95a 100644 --- a/crates/openshell-cli/src/main.rs +++ b/crates/openshell-cli/src/main.rs @@ -2390,12 +2390,6 @@ fn run_main() -> Result<()> { #[allow(clippy::large_stack_frames)] // CLI dispatch holds many futures; run on an expanded Windows stack. async fn run_async() -> Result<()> { - // Install the rustls crypto provider before completion runs — completers may - // establish TLS connections to the gateway. - rustls::crypto::ring::default_provider() - .install_default() - .map_err(|e| miette::miette!("failed to install rustls crypto provider: {e:?}"))?; - CompleteEnv::with_factory(Cli::command).complete(); let cli = Cli::parse(); diff --git a/crates/openshell-cli/src/oidc_auth.rs b/crates/openshell-cli/src/oidc_auth.rs index 7fbdb5100..7e362bf42 100644 --- a/crates/openshell-cli/src/oidc_auth.rs +++ b/crates/openshell-cli/src/oidc_auth.rs @@ -29,7 +29,7 @@ use tokio::net::TcpListener; use tokio::sync::oneshot; use tracing::debug; -const AUTH_TIMEOUT: Duration = Duration::from_secs(120); +const AUTH_TIMEOUT: Duration = Duration::from_mins(2); /// OIDC discovery document (subset of fields we need). #[derive(Debug, Deserialize)] @@ -93,6 +93,7 @@ async fn discover(issuer: &str, insecure: bool) -> Result { } fn http_client(insecure: bool) -> reqwest::Client { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let mut builder = reqwest::ClientBuilder::new().redirect(reqwest::redirect::Policy::none()); if insecure { builder = builder.danger_accept_invalid_certs(true); diff --git a/crates/openshell-cli/src/tls.rs b/crates/openshell-cli/src/tls.rs index c24b84c7d..ed50804c7 100644 --- a/crates/openshell-cli/src/tls.rs +++ b/crates/openshell-cli/src/tls.rs @@ -287,7 +287,7 @@ impl ServerCertVerifier for InsecureServerCertVerifier { } fn supported_verify_schemes(&self) -> Vec { - rustls::crypto::ring::default_provider() + rustls::crypto::aws_lc_rs::default_provider() .signature_verification_algorithms .supported_schemes() } diff --git a/crates/openshell-cli/tests/ensure_providers_integration.rs b/crates/openshell-cli/tests/ensure_providers_integration.rs index ab8626e0a..7545786a1 100644 --- a/crates/openshell-cli/tests/ensure_providers_integration.rs +++ b/crates/openshell-cli/tests/ensure_providers_integration.rs @@ -7,9 +7,7 @@ mod helpers; -use helpers::{ - EnvVarGuard, build_ca, build_client_cert, build_server_cert, install_rustls_provider, -}; +use helpers::{EnvVarGuard, build_ca, build_client_cert, build_server_cert}; use openshell_cli::run; use openshell_cli::tls::TlsOptions; use openshell_core::proto::open_shell_server::{OpenShell, OpenShellServer}; @@ -733,8 +731,6 @@ struct TestServer { } async fn run_server() -> TestServer { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); diff --git a/crates/openshell-cli/tests/helpers/mod.rs b/crates/openshell-cli/tests/helpers/mod.rs index c4e9b4b75..e37b84a7b 100644 --- a/crates/openshell-cli/tests/helpers/mod.rs +++ b/crates/openshell-cli/tests/helpers/mod.rs @@ -160,14 +160,6 @@ impl Drop for EnvVarGuard { // ── TLS helpers ────────────────────────────────────────────────────────────── -/// Install the `rustls` ring crypto provider as the process default. -/// -/// Safe to call multiple times — subsequent calls are no-ops. -#[allow(dead_code)] -pub fn install_rustls_provider() { - let _ = rustls::crypto::ring::default_provider().install_default(); -} - /// Generate a self-signed CA certificate and its key pair. #[allow(dead_code)] pub fn build_ca() -> (Certificate, KeyPair) { diff --git a/crates/openshell-cli/tests/mtls_integration.rs b/crates/openshell-cli/tests/mtls_integration.rs index 321c4f469..29de1fe6f 100644 --- a/crates/openshell-cli/tests/mtls_integration.rs +++ b/crates/openshell-cli/tests/mtls_integration.rs @@ -3,9 +3,7 @@ mod helpers; -use helpers::{ - EnvVarGuard, build_ca, build_client_cert, build_server_cert, install_rustls_provider, -}; +use helpers::{EnvVarGuard, build_ca, build_client_cert, build_server_cert}; use openshell_bootstrap::{get_gateway_metadata, load_active_gateway}; use openshell_cli::{ run, @@ -651,8 +649,6 @@ fn isolated_gateway_add_env( #[tokio::test] async fn gateway_add_mtls_loopback_uses_explicit_gateway_name() { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); @@ -695,8 +691,6 @@ async fn gateway_add_mtls_loopback_uses_explicit_gateway_name() { #[tokio::test] async fn gateway_add_mtls_loopback_without_name_uses_openshell_default() { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); @@ -738,8 +732,6 @@ async fn gateway_add_mtls_loopback_without_name_uses_openshell_default() { #[tokio::test] async fn gateway_add_mtls_loopback_explicit_name_does_not_fallback_to_openshell_certs() { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); let ca_cert = ca.pem(); @@ -777,7 +769,6 @@ async fn gateway_add_mtls_loopback_explicit_name_does_not_fallback_to_openshell_ #[tokio::test] async fn cli_connects_with_client_cert() { let _env = EnvVarGuard::set(&[]); - install_rustls_provider(); let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); @@ -803,8 +794,6 @@ async fn cli_connects_with_client_cert() { #[tokio::test] async fn cli_requires_client_cert_for_https() { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let ca_cert = ca.pem(); @@ -851,7 +840,6 @@ async fn run_server_no_client_auth( #[tokio::test] async fn cli_connects_with_gateway_insecure() { let _env = EnvVarGuard::set(&[]); - install_rustls_provider(); let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); diff --git a/crates/openshell-cli/tests/provider_commands_integration.rs b/crates/openshell-cli/tests/provider_commands_integration.rs index 4211f9cef..2d1b3f25d 100644 --- a/crates/openshell-cli/tests/provider_commands_integration.rs +++ b/crates/openshell-cli/tests/provider_commands_integration.rs @@ -3,9 +3,7 @@ mod helpers; -use helpers::{ - EnvVarGuard, build_ca, build_client_cert, build_server_cert, install_rustls_provider, -}; +use helpers::{EnvVarGuard, build_ca, build_client_cert, build_server_cert}; use openshell_cli::run; use openshell_cli::tls::TlsOptions; use openshell_core::proto::open_shell_server::{OpenShell, OpenShellServer}; @@ -1162,8 +1160,6 @@ struct TestServer { } async fn run_server() -> TestServer { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); diff --git a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs index d2f50735d..33d15f7c5 100644 --- a/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs +++ b/crates/openshell-cli/tests/sandbox_create_lifecycle_integration.rs @@ -5,9 +5,7 @@ mod helpers; -use helpers::{ - EnvVarGuard, build_ca, build_client_cert, build_server_cert, install_rustls_provider, -}; +use helpers::{EnvVarGuard, build_ca, build_client_cert, build_server_cert}; use openshell_bootstrap::load_last_sandbox; use openshell_cli::run; use openshell_cli::tls::TlsOptions; @@ -944,8 +942,6 @@ struct TestServer { } async fn run_server() -> TestServer { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); diff --git a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs index bf0e1043e..fdb0ebbd0 100644 --- a/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs +++ b/crates/openshell-cli/tests/sandbox_name_fallback_integration.rs @@ -3,9 +3,7 @@ mod helpers; -use helpers::{ - EnvVarGuard, build_ca, build_client_cert, build_server_cert, install_rustls_provider, -}; +use helpers::{EnvVarGuard, build_ca, build_client_cert, build_server_cert}; use openshell_bootstrap::{load_last_sandbox, save_last_sandbox}; use openshell_cli::run; use openshell_cli::tls::TlsOptions; @@ -682,8 +680,6 @@ struct TestServer { } async fn run_server() -> TestServer { - install_rustls_provider(); - let (ca, ca_key) = build_ca(); let (server_cert, server_key) = build_server_cert(&ca, &ca_key); let (client_cert, client_key) = build_client_cert(&ca, &ca_key); diff --git a/crates/openshell-conformance/src/lib.rs b/crates/openshell-conformance/src/lib.rs index 63cd1677e..7b28fa688 100644 --- a/crates/openshell-conformance/src/lib.rs +++ b/crates/openshell-conformance/src/lib.rs @@ -92,7 +92,7 @@ pub fn default_scenarios() -> impl Iterator { .filter(|scenario| !scenario.requires_plan) } -const CLEANUP_TIMEOUT: Duration = Duration::from_secs(120); +const CLEANUP_TIMEOUT: Duration = Duration::from_mins(2); pub const STATUS_TIMEOUT: Duration = Duration::from_secs(30); const GATEWAY_STATUS_ATTEMPT_TIMEOUT: Duration = Duration::from_secs(10); const GATEWAY_STATUS_INTERVAL: Duration = Duration::from_secs(2); diff --git a/crates/openshell-conformance/src/scenarios/sandbox_continuity.rs b/crates/openshell-conformance/src/scenarios/sandbox_continuity.rs index 7fe1f0d06..81f8d4657 100644 --- a/crates/openshell-conformance/src/scenarios/sandbox_continuity.rs +++ b/crates/openshell-conformance/src/scenarios/sandbox_continuity.rs @@ -11,9 +11,9 @@ use crate::{ HostAction, OpenShellRunner, PlanRun, Poll, Scenario, ScenarioFuture, WorkloadExpectation, }; -const CREATE_TIMEOUT: Duration = Duration::from_secs(600); -const COMMAND_TIMEOUT: Duration = Duration::from_secs(120); -const RECOVERY_TIMEOUT: Duration = Duration::from_secs(240); +const CREATE_TIMEOUT: Duration = Duration::from_mins(10); +const COMMAND_TIMEOUT: Duration = Duration::from_mins(2); +const RECOVERY_TIMEOUT: Duration = Duration::from_mins(4); const RECOVERY_INTERVAL: Duration = Duration::from_secs(2); #[derive(Debug, Deserialize)] diff --git a/crates/openshell-conformance/src/scenarios/smoke.rs b/crates/openshell-conformance/src/scenarios/smoke.rs index cb5ca4012..7c5fa0068 100644 --- a/crates/openshell-conformance/src/scenarios/smoke.rs +++ b/crates/openshell-conformance/src/scenarios/smoke.rs @@ -9,11 +9,11 @@ use crate::{OpenShellRunner, PlanRun, STATUS_TIMEOUT, Scenario, ScenarioFuture}; use serde::Deserialize; use tokio::time::sleep; -const CREATE_TIMEOUT: Duration = Duration::from_secs(600); +const CREATE_TIMEOUT: Duration = Duration::from_mins(10); const LIST_ATTEMPT_TIMEOUT: Duration = Duration::from_secs(10); const LIST_PAGE_SIZE: u32 = 1_000; -const EXEC_TIMEOUT: Duration = Duration::from_secs(120); -const DELETE_TIMEOUT: Duration = Duration::from_secs(120); +const EXEC_TIMEOUT: Duration = Duration::from_mins(2); +const DELETE_TIMEOUT: Duration = Duration::from_mins(2); const DELETE_POLL_INTERVAL: Duration = Duration::from_secs(1); #[derive(Debug, Deserialize)] diff --git a/crates/openshell-core/Cargo.toml b/crates/openshell-core/Cargo.toml index c96d536f0..ff2cc638f 100644 --- a/crates/openshell-core/Cargo.toml +++ b/crates/openshell-core/Cargo.toml @@ -16,7 +16,7 @@ openshell-extension-core = { path = "../openshell-extension-core" } glob = { workspace = true } prost = { workspace = true } prost-types = { workspace = true } -tonic = { workspace = true, features = ["channel", "tls-ring"] } +tonic = { workspace = true, features = ["channel", "tls-aws-lc"] } tonic-prost = { workspace = true } tokio = { workspace = true } tokio-stream = { workspace = true } @@ -31,7 +31,7 @@ rustls = { workspace = true } rustls-pemfile = { workspace = true } base64 = { workspace = true } chrono = { version = "0.4", default-features = false, features = ["clock", "std"], optional = true } -reqwest = { workspace = true, features = ["blocking", "rustls-tls-native-roots"], optional = true } +reqwest = { workspace = true, features = ["blocking", "rustls-tls-native-roots-no-provider"], optional = true } tar = { version = "0.4", optional = true } tempfile = { version = "3", optional = true } diff --git a/crates/openshell-core/src/config.rs b/crates/openshell-core/src/config.rs index 350701112..76f534c88 100644 --- a/crates/openshell-core/src/config.rs +++ b/crates/openshell-core/src/config.rs @@ -995,7 +995,7 @@ mod tests { Config::new(None) .with_grpc_rate_limit(Some(10), Some(60)) .grpc_rate_limit(), - Some((10, Duration::from_secs(60))) + Some((10, Duration::from_mins(1))) ); } diff --git a/crates/openshell-core/src/oauth.rs b/crates/openshell-core/src/oauth.rs index c68ecfa6b..d3a9e3472 100644 --- a/crates/openshell-core/src/oauth.rs +++ b/crates/openshell-core/src/oauth.rs @@ -312,6 +312,7 @@ mod tests { } fn test_client() -> reqwest::Client { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); reqwest::Client::builder() .timeout(std::time::Duration::from_secs(5)) .no_proxy() diff --git a/crates/openshell-core/src/telemetry.rs b/crates/openshell-core/src/telemetry.rs index 63aa5f918..9541598fe 100644 --- a/crates/openshell-core/src/telemetry.rs +++ b/crates/openshell-core/src/telemetry.rs @@ -426,6 +426,7 @@ fn telemetry_worker(rx: mpsc::Receiver) { #[cfg(feature = "telemetry")] fn publish_payload(endpoint: &str, payload: Value) -> Result<(), reqwest::Error> { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); Client::builder() .use_rustls_tls() .tls_built_in_root_certs(true) diff --git a/crates/openshell-driver-db-credstore/Cargo.toml b/crates/openshell-driver-db-credstore/Cargo.toml index 805cb1c7d..9f3f5427b 100644 --- a/crates/openshell-driver-db-credstore/Cargo.toml +++ b/crates/openshell-driver-db-credstore/Cargo.toml @@ -16,7 +16,7 @@ openshell-core = { path = "../openshell-core", default-features = false } async-trait = "0.1" base64 = { workspace = true } futures = { workspace = true } -ring = { workspace = true } +aws-lc-rs = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } sha2 = { workspace = true } diff --git a/crates/openshell-driver-db-credstore/src/lib.rs b/crates/openshell-driver-db-credstore/src/lib.rs index 24c21e993..c9813870b 100644 --- a/crates/openshell-driver-db-credstore/src/lib.rs +++ b/crates/openshell-driver-db-credstore/src/lib.rs @@ -17,6 +17,8 @@ use std::path::{Path, PathBuf}; use std::sync::Arc; use async_trait::async_trait; +use aws_lc_rs::aead::{AES_256_GCM, Aad, LessSafeKey, Nonce, UnboundKey}; +use aws_lc_rs::rand::{SecureRandom, SystemRandom}; use base64::{ Engine as _, engine::general_purpose::{STANDARD as BASE64, STANDARD_NO_PAD as BASE64_NO_PAD}, @@ -26,8 +28,6 @@ use openshell_core::proto::credentials::v1::{ DeleteCredentialRequest, ResolveCredentialRequest, ResolvedCredential, StoreCredentialRequest, }; use openshell_core::{Error, Result as CoreResult}; -use ring::aead::{AES_256_GCM, Aad, LessSafeKey, Nonce, UnboundKey}; -use ring::rand::{SecureRandom, SystemRandom}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use tonic::Status; @@ -933,6 +933,46 @@ mod tests { use std::sync::{Arc, Mutex}; use tonic::Code; + #[test] + fn persisted_aes_gcm_ciphertexts_remain_compatible() { + // Fixed, non-secret ciphertexts produced by the previous crypto backend. + let cases = [ + ( + [0x11; KEY_LEN], + [0x22; NONCE_LEN], + dek_aad("fixture", "provider", "api_key"), + vec![0x33; KEY_LEN], + "JMQ0evP8rGzWDO0Pe5Xa5iyg/tFZsp94YXw52zrSVjCoSMvKkAYj5kygMADT9jIW", + ), + ( + [0x33; KEY_LEN], + [0x44; NONCE_LEN], + value_aad("fixture", "provider", "api_key"), + b"fixture-secret".to_vec(), + "Vvi85r906kbT58fgk+mUIc/KA4ar8d3Syu8Jz5h1", + ), + ]; + for (key, nonce, aad, plaintext, ciphertext) in cases { + let encrypted = EncryptedBytes { + nonce: BASE64.encode(nonce), + ciphertext: ciphertext.to_string(), + }; + assert_eq!(decrypt_bytes(&key, &aad, &encrypted).unwrap(), plaintext); + let mut sealed = plaintext; + aead_key(&key) + .unwrap() + .seal_in_place_append_tag( + Nonce::assume_unique_for_key(nonce), + Aad::from(aad.as_slice()), + &mut sealed, + ) + .unwrap(); + assert_eq!(BASE64.encode(sealed), ciphertext); + assert!(decrypt_bytes(&key, b"wrong-aad", &encrypted).is_err()); + assert!(decrypt_bytes(&[0xff; KEY_LEN], &aad, &encrypted).is_err()); + } + } + #[derive(Debug, Default)] struct MemoryObjectStore { objects: Mutex>, diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 3a1991738..1e790bf34 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -54,7 +54,7 @@ use openshell_core::proto::compute::v1::{ }; use openshell_core::proto_struct::{struct_to_json_object, value_to_json}; use serde::Deserialize; -use std::collections::{BTreeMap, HashSet}; +use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::path::{Path, PathBuf}; use std::pin::Pin; use std::sync::Arc; @@ -1965,7 +1965,7 @@ impl KubernetesComputeDriver { loop { tokio::select! { event = sandbox_stream.next() => match event { - Some(Event::Applied(obj)) => { + Some(Event::Apply(obj) | Event::InitApply(obj)) => { if let Ok((kube_name, sandbox)) = sandbox_from_object(&namespace, obj) { update_indexes(&mut sandbox_name_to_id, &mut agent_pod_to_id, &kube_name, &sandbox); let event = WatchSandboxesEvent { @@ -1978,7 +1978,7 @@ impl KubernetesComputeDriver { } } } - Some(Event::Deleted(obj)) => { + Some(Event::Delete(obj)) => { if is_openshell_managed(&obj) && let Ok(sandbox_id) = sandbox_id_from_object(&obj) { @@ -1993,21 +1993,7 @@ impl KubernetesComputeDriver { } } } - Some(Event::Restarted(objs)) => { - for obj in objs { - if let Ok((kube_name, sandbox)) = sandbox_from_object(&namespace, obj) { - update_indexes(&mut sandbox_name_to_id, &mut agent_pod_to_id, &kube_name, &sandbox); - let event = WatchSandboxesEvent { - payload: Some(watch_sandboxes_event::Payload::Sandbox( - WatchSandboxesSandboxEvent { sandbox: Some(sandbox) } - )), - }; - if tx.send(Ok(event)).await.is_err() { - return; - } - } - } - } + Some(Event::Init | Event::InitDone) => {} None => { let _ = tx.send(Err(KubernetesDriverError::Message( "sandbox watcher stream ended unexpectedly".to_string() @@ -2016,7 +2002,7 @@ impl KubernetesComputeDriver { } }, event = event_stream.next() => match event { - Some(Event::Applied(obj)) => { + Some(Event::Apply(obj)) => { if let Some((sandbox_id, event)) = map_kube_event_to_platform( &sandbox_name_to_id, &agent_pod_to_id, @@ -2032,8 +2018,8 @@ impl KubernetesComputeDriver { } } } - Some(Event::Deleted(_)) => {} - Some(Event::Restarted(_)) => { + Some(Event::Delete(_) | Event::InitApply(_) | Event::InitDone) => {} + Some(Event::Init) => { debug!(namespace = %namespace, "Kubernetes event watcher restarted"); } None => { @@ -2082,7 +2068,7 @@ where loop { tokio::select! { event = sandbox_stream.next() => match event { - Some(Event::Applied(obj)) => { + Some(Event::Apply(obj) | Event::InitApply(obj)) => { let ns = obj.metadata.namespace.clone() .unwrap_or_else(|| default_namespace.clone()); if let Ok((_kube_name, sandbox)) = sandbox_from_object(&ns, obj) { @@ -2096,7 +2082,7 @@ where } } } - Some(Event::Deleted(obj)) => { + Some(Event::Delete(obj)) => { if is_openshell_managed(&obj) && let Ok(sandbox_id) = sandbox_id_from_object(&obj) { @@ -2110,22 +2096,7 @@ where } } } - Some(Event::Restarted(objs)) => { - for obj in objs { - let ns = obj.metadata.namespace.clone() - .unwrap_or_else(|| default_namespace.clone()); - if let Ok((_kube_name, sandbox)) = sandbox_from_object(&ns, obj) { - let event = WatchSandboxesEvent { - payload: Some(watch_sandboxes_event::Payload::Sandbox( - WatchSandboxesSandboxEvent { sandbox: Some(sandbox) } - )), - }; - if tx.send(Ok(event)).await.is_err() { - return; - } - } - } - } + Some(Event::Init | Event::InitDone) => {} None => { let _ = tx.send(Err(KubernetesDriverError::Message( "sandbox watcher stream ended unexpectedly".to_string() @@ -2318,7 +2289,6 @@ fn managed_ssh_network_policy(namespace: &str, config: &KubernetesComputeConfig) }]), ..Default::default() }), - status: None, } } @@ -4723,6 +4693,7 @@ fn spawn_namespace_label_watcher( let mut retry_attempt = 0; loop { let mut stream = watcher::watcher(ns_api.clone(), watcher_config.clone()).boxed(); + let mut relisted_names = BTreeSet::new(); loop { let event = tokio::select! { @@ -4735,37 +4706,9 @@ fn spawn_namespace_label_watcher( } }; match event { - Ok(Some(Event::Applied(ns))) => { + Ok(Some(event)) => { retry_attempt = 0; - if let Some(name) = ns.metadata.name.as_deref() - && allowlist.insert(name.to_string()) - { - info!(namespace = name, "operator namespace added to allowlist"); - } - } - Ok(Some(Event::Deleted(ns))) => { - retry_attempt = 0; - if let Some(name) = ns.metadata.name.as_deref() - && allowlist.remove(name) - { - info!( - namespace = name, - "operator namespace removed from allowlist" - ); - } - } - Ok(Some(Event::Restarted(namespaces))) => { - retry_attempt = 0; - let names: std::collections::BTreeSet = namespaces - .into_iter() - .filter_map(|ns| ns.metadata.name) - .collect(); - let count = names.len(); - allowlist.replace(names); - info!( - total = count, - "operator namespace allowlist replaced from full relist" - ); + apply_namespace_watch_event(&allowlist, &mut relisted_names, event); } Ok(None) => { warn!("operator namespace watcher stream ended unexpectedly"); @@ -4807,7 +4750,7 @@ fn namespace_watcher_retry_delay(attempt: u32, jitter_seed: u64) -> Duration { Duration::from_secs(base_secs + jitter_secs) } -fn load_namespace_file(path: &Path) -> Result, String> { +fn load_namespace_file(path: &Path) -> Result, String> { let contents = std::fs::read_to_string(path) .map_err(|e| format!("failed to read {}: {e}", path.display()))?; let names: Vec = serde_json::from_str(&contents) @@ -4815,6 +4758,47 @@ fn load_namespace_file(path: &Path) -> Result Ok(names.into_iter().collect()) } +fn apply_namespace_watch_event( + allowlist: &OperatorNamespaceAllowlist, + relisted_names: &mut BTreeSet, + event: Event, +) { + match event { + Event::Apply(ns) => { + if let Some(name) = ns.metadata.name + && allowlist.insert(name.clone()) + { + info!(namespace = name, "operator namespace added to allowlist"); + } + } + Event::Delete(ns) => { + if let Some(name) = ns.metadata.name + && allowlist.remove(&name) + { + info!( + namespace = name, + "operator namespace removed from allowlist" + ); + } + } + Event::Init => relisted_names.clear(), + Event::InitApply(ns) => { + if let Some(name) = ns.metadata.name { + relisted_names.insert(name); + } + } + Event::InitDone => { + // Readers must see a complete snapshot, including during interrupted relists. + let count = relisted_names.len(); + allowlist.replace(std::mem::take(relisted_names)); + info!( + total = count, + "operator namespace allowlist replaced from full relist" + ); + } + } +} + fn spawn_namespace_file_watcher( path: PathBuf, allowlist: OperatorNamespaceAllowlist, @@ -5062,7 +5046,7 @@ mod tests { } #[tokio::test] - async fn sandbox_watcher_error_does_not_hide_restarted_recovery_event() { + async fn sandbox_watcher_error_does_not_hide_relist() { let recovered = DynamicObject { types: None, metadata: ObjectMeta { @@ -5073,22 +5057,22 @@ mod tests { }; let source = futures::stream::iter([ Err(expired_watch_error()), - Ok(Event::Restarted(vec![recovered])), + Ok(Event::Init), + Ok(Event::InitApply(recovered)), + Ok(Event::InitDone), ]); let mut stream = continue_on_watcher_errors(source, "sandbox-resource"); + assert!(matches!(stream.next().await, Some(Event::Init))); let event = stream .next() .await .expect("410 Expired must not terminate the watcher stream"); - let Event::Restarted(objects) = event else { - panic!("expected kube-runtime recovery to emit Restarted"); + let Event::InitApply(object) = event else { + panic!("expected kube-runtime recovery to emit InitApply"); }; - assert_eq!(objects.len(), 1); - assert_eq!( - objects[0].metadata.name.as_deref(), - Some("recovered-sandbox") - ); + assert_eq!(object.metadata.name.as_deref(), Some("recovered-sandbox")); + assert!(matches!(stream.next().await, Some(Event::InitDone))); assert!( stream.next().await.is_none(), "source closure must be preserved" @@ -5117,7 +5101,9 @@ mod tests { }; let source = futures::stream::iter([ Err(expired_watch_error()), - Ok(Event::Restarted(vec![recovered])), + Ok(Event::Init), + Ok(Event::InitApply(recovered)), + Ok(Event::InitDone), ]) .chain(futures::stream::pending()); let sandbox_stream = recovering_watcher_stream(source, "sandbox-resource").boxed(); @@ -5144,10 +5130,12 @@ mod tests { } #[tokio::test] - async fn kubernetes_event_watcher_error_does_not_hide_restarted_recovery_event() { + async fn kubernetes_event_watcher_error_does_not_hide_relist() { let source = futures::stream::iter([ Err(expired_watch_error()), - Ok(Event::Restarted(vec![KubeEventObj::default()])), + Ok(Event::Init), + Ok(Event::InitApply(KubeEventObj::default())), + Ok(Event::InitDone), ]); let mut stream = continue_on_watcher_errors(source, "kubernetes-event"); @@ -5155,16 +5143,65 @@ mod tests { .next() .await .expect("410 Expired must not terminate the watcher stream"); - let Event::Restarted(events) = event else { - panic!("expected kube-runtime recovery to emit Restarted"); - }; - assert_eq!(events.len(), 1); + assert!(matches!(event, Event::Init)); + assert!(matches!(stream.next().await, Some(Event::InitApply(_)))); + assert!(matches!(stream.next().await, Some(Event::InitDone))); assert!( stream.next().await.is_none(), "source closure must be preserved" ); } + #[test] + fn namespace_relist_replaces_only_completed_snapshots() { + let allowlist = OperatorNamespaceAllowlist::from_set(BTreeSet::from(["old".to_string()])); + let mut pending = BTreeSet::new(); + let namespace = |name: &str| Namespace { + metadata: ObjectMeta { + name: Some(name.to_string()), + ..Default::default() + }, + ..Default::default() + }; + let config = KubernetesComputeConfig { + workspace_mode: WorkspaceMode::Operator, + ..Default::default() + }; + + apply_namespace_watch_event(&allowlist, &mut pending, Event::Init); + apply_namespace_watch_event( + &allowlist, + &mut pending, + Event::InitApply(namespace("partial")), + ); + assert!(accepts_auth_namespace(&config, Some(&allowlist), "old")); + assert!(!accepts_auth_namespace( + &config, + Some(&allowlist), + "partial" + )); + + apply_namespace_watch_event(&allowlist, &mut pending, Event::Init); + apply_namespace_watch_event(&allowlist, &mut pending, Event::InitApply(namespace("new"))); + apply_namespace_watch_event(&allowlist, &mut pending, Event::InitDone); + assert!(accepts_auth_namespace(&config, Some(&allowlist), "new")); + assert!(!accepts_auth_namespace(&config, Some(&allowlist), "old")); + assert!(!accepts_auth_namespace( + &config, + Some(&allowlist), + "partial" + )); + + apply_namespace_watch_event(&allowlist, &mut pending, Event::Apply(namespace("live"))); + assert!(accepts_auth_namespace(&config, Some(&allowlist), "live")); + apply_namespace_watch_event(&allowlist, &mut pending, Event::Delete(namespace("live"))); + assert!(!accepts_auth_namespace(&config, Some(&allowlist), "live")); + + apply_namespace_watch_event(&allowlist, &mut pending, Event::Init); + apply_namespace_watch_event(&allowlist, &mut pending, Event::InitDone); + assert!(!accepts_auth_namespace(&config, Some(&allowlist), "new")); + } + fn authenticated_token_review(username: &str) -> TokenReviewStatus { TokenReviewStatus { authenticated: Some(true), @@ -5372,7 +5409,7 @@ mod tests { assert_eq!( kubernetes_sandbox_stop_timeout(&sandbox), - Duration::from_secs(60), + Duration::from_mins(1), "an omitted grace period uses the Kubernetes 30-second default" ); diff --git a/crates/openshell-driver-podman/src/client.rs b/crates/openshell-driver-podman/src/client.rs index 508b604ce..5f381daa9 100644 --- a/crates/openshell-driver-podman/src/client.rs +++ b/crates/openshell-driver-podman/src/client.rs @@ -719,7 +719,7 @@ impl PodmanClient { url_encode(policy), ); // Image pulls can be slow — use a generous timeout. - let pull_timeout = Duration::from_secs(600); + let pull_timeout = Duration::from_mins(10); let (status, bytes) = self .request(hyper::Method::POST, &path, None, pull_timeout) .await?; diff --git a/crates/openshell-driver-vault/Cargo.toml b/crates/openshell-driver-vault/Cargo.toml index 2d3878ed6..fe12c2e20 100644 --- a/crates/openshell-driver-vault/Cargo.toml +++ b/crates/openshell-driver-vault/Cargo.toml @@ -21,6 +21,7 @@ clap = { workspace = true } futures = { workspace = true } miette = { workspace = true } reqwest = { workspace = true } +rustls = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } sha2 = { workspace = true } diff --git a/crates/openshell-driver-vault/src/lib.rs b/crates/openshell-driver-vault/src/lib.rs index d93200570..9fee593fb 100644 --- a/crates/openshell-driver-vault/src/lib.rs +++ b/crates/openshell-driver-vault/src/lib.rs @@ -126,6 +126,7 @@ impl VaultCredentialDriver { pub fn from_config(config: &toml::Table) -> CoreResult { let settings = VaultDriverSettings::from_table(config)?; let timeout_secs = timeout_secs(config)?; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder() .timeout(Duration::from_secs(timeout_secs)) .build() diff --git a/crates/openshell-extension-core/src/jwt.rs b/crates/openshell-extension-core/src/jwt.rs index 4bf5d3918..9d85858de 100644 --- a/crates/openshell-extension-core/src/jwt.rs +++ b/crates/openshell-extension-core/src/jwt.rs @@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize}; /// /// Extension credentials cross the gateway trust boundary and must remain /// short-lived even when legacy sandbox bootstrap credentials do not expire. -pub const MAX_EXTENSION_TOKEN_TTL: Duration = Duration::from_secs(3_600); +pub const MAX_EXTENSION_TOKEN_TTL: Duration = Duration::from_hours(1); /// Explicit `typ` header value carried by every extension bearer token. /// diff --git a/crates/openshell-extension-core/src/transport.rs b/crates/openshell-extension-core/src/transport.rs index 4552faf70..98bbeb89d 100644 --- a/crates/openshell-extension-core/src/transport.rs +++ b/crates/openshell-extension-core/src/transport.rs @@ -292,7 +292,6 @@ mod tests { #[tokio::test] async fn custom_ca_verifies_certificate_and_hostname() { - let _ = rustls::crypto::ring::default_provider().install_default(); let ca_key = KeyPair::generate().unwrap(); let mut ca_params = CertificateParams::new(Vec::::new()).unwrap(); ca_params.is_ca = IsCa::Ca(BasicConstraints::Unconstrained); diff --git a/crates/openshell-router/Cargo.toml b/crates/openshell-router/Cargo.toml index 97bbf4dc7..6b300adc2 100644 --- a/crates/openshell-router/Cargo.toml +++ b/crates/openshell-router/Cargo.toml @@ -14,6 +14,7 @@ repository.workspace = true openshell-core = { path = "../openshell-core", default-features = false } bytes = { workspace = true } reqwest = { workspace = true } +rustls = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } thiserror = { workspace = true } diff --git a/crates/openshell-router/src/backend.rs b/crates/openshell-router/src/backend.rs index 84a5c6acf..3b771dd9a 100644 --- a/crates/openshell-router/src/backend.rs +++ b/crates/openshell-router/src/backend.rs @@ -1104,6 +1104,7 @@ mod tests { .await; let route = test_route(&mock_server.uri(), &["model_discovery"], AuthHeader::Bearer); + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::new(); let result = proxy_to_backend( &client, @@ -1151,6 +1152,7 @@ mod tests { #[tokio::test] async fn read_capped_response_body_rejects_over_cap_chunked() { let addr = spawn_chunked_upstream(&["aaaa", "bbbb", "cccc"]).await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let response = reqwest::Client::new() .get(format!("http://{addr}/")) .send() @@ -1172,6 +1174,7 @@ mod tests { #[tokio::test] async fn read_capped_response_body_accepts_body_at_cap() { let addr = spawn_chunked_upstream(&["aaaa", "bbbb"]).await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let response = reqwest::Client::new() .get(format!("http://{addr}/")) .send() @@ -1358,6 +1361,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let validated = verify_backend_endpoint(&client, &route).await.unwrap(); @@ -1373,6 +1377,7 @@ mod tests { AuthHeader::Bearer, ); + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let validated = verify_backend_endpoint(&client, &route).await.unwrap(); @@ -1402,6 +1407,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let validated = verify_backend_endpoint(&client, &route).await.unwrap(); @@ -1445,6 +1451,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let validated = verify_backend_endpoint(&client, &route).await.unwrap(); @@ -1491,6 +1498,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::new(); let validated = verify_backend_endpoint(&client, &route) .await @@ -1526,6 +1534,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::new(); let err = verify_backend_endpoint(&client, &route) .await @@ -1629,6 +1638,7 @@ mod tests { /// Helper: run `verify_backend_endpoint` and return the expected failure. async fn reqwest_verify(route: &ResolvedRoute) -> ValidationFailure { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); verify_backend_endpoint(&reqwest::Client::new(), route) .await .expect_err("validation should fail") @@ -1651,6 +1661,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let result = verify_backend_endpoint(&client, &route).await; @@ -1691,6 +1702,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let validated = verify_backend_endpoint(&client, &route).await.unwrap(); assert!( @@ -1897,6 +1909,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -1966,6 +1979,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); // Simulate a client (e.g. Claude Code) that always sends "model" in the body. let body = bytes::Bytes::from( @@ -2028,6 +2042,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -2086,6 +2101,7 @@ mod tests { request_path_override: None, }; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -2212,6 +2228,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -2274,6 +2291,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -2338,6 +2356,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder().build().unwrap(); let body = bytes::Bytes::from( serde_json::to_vec(&serde_json::json!({ @@ -2557,6 +2576,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder() .timeout(Duration::from_secs(5)) .build() @@ -2674,6 +2694,7 @@ mod tests { })) .unwrap(); + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::new(); let result = proxy_to_backend( &client, @@ -2701,6 +2722,7 @@ mod tests { /// but if it ever did, we must not silently forward. #[test] fn bedrock_route_rejects_non_bedrock_path() { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::new(); let route = test_route( "https://bedrock-bridge.example", diff --git a/crates/openshell-router/src/config.rs b/crates/openshell-router/src/config.rs index 81fac6048..03218e201 100644 --- a/crates/openshell-router/src/config.rs +++ b/crates/openshell-router/src/config.rs @@ -9,7 +9,7 @@ pub use openshell_core::inference::AuthHeader; use crate::RouterError; -pub const DEFAULT_ROUTE_TIMEOUT: Duration = Duration::from_secs(60); +pub const DEFAULT_ROUTE_TIMEOUT: Duration = Duration::from_mins(1); #[derive(Debug, Clone, Deserialize)] pub struct RouterConfig { diff --git a/crates/openshell-router/src/lib.rs b/crates/openshell-router/src/lib.rs index 79bbfe6ca..6ef5286fa 100644 --- a/crates/openshell-router/src/lib.rs +++ b/crates/openshell-router/src/lib.rs @@ -37,6 +37,7 @@ pub struct Router { impl Router { pub fn new() -> Result { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder() .connect_timeout(Duration::from_secs(30)) .build() diff --git a/crates/openshell-sandbox/src/main.rs b/crates/openshell-sandbox/src/main.rs index e67b9b48a..a1bcea006 100644 --- a/crates/openshell-sandbox/src/main.rs +++ b/crates/openshell-sandbox/src/main.rs @@ -533,7 +533,6 @@ fn main() -> Result<()> { .build() .into_diagnostic()?; return runtime.block_on(async move { - let _ = rustls::crypto::ring::default_provider().install_default(); let exit = openshell_supervisor_process::debug_rpc::run(&raw_args[2..]).await?; std::process::exit(exit); }); @@ -578,9 +577,6 @@ fn main() -> Result<()> { .into_diagnostic()?; let result = runtime.block_on(async move { - // Install rustls crypto provider before any TLS connections (including log push). - let _ = rustls::crypto::ring::default_provider().install_default(); - // Set up optional log push layer (gRPC mode only). let log_push_state = if let (Some(sandbox_id), Some(endpoint)) = (&args.sandbox_id, &args.openshell_endpoint) diff --git a/crates/openshell-sdk/src/oidc.rs b/crates/openshell-sdk/src/oidc.rs index 3f59c25cd..c39e8300a 100644 --- a/crates/openshell-sdk/src/oidc.rs +++ b/crates/openshell-sdk/src/oidc.rs @@ -139,6 +139,7 @@ pub async fn discover(issuer: &str, insecure: bool) -> Result { /// followed; OIDC providers should not redirect on the token endpoint. /// When `insecure` is true, TLS certificate verification is disabled. pub fn http_client(insecure: bool) -> reqwest::Client { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let mut builder = reqwest::ClientBuilder::new().redirect(reqwest::redirect::Policy::none()); if insecure { builder = builder.danger_accept_invalid_certs(true); diff --git a/crates/openshell-sdk/src/refresh.rs b/crates/openshell-sdk/src/refresh.rs index a70d88276..fd38e28ed 100644 --- a/crates/openshell-sdk/src/refresh.rs +++ b/crates/openshell-sdk/src/refresh.rs @@ -175,7 +175,7 @@ impl TokenSource { })), refresher, flight: Arc::new(Mutex::new(Flight::default())), - skew: Duration::from_secs(60), + skew: Duration::from_mins(1), } } diff --git a/crates/openshell-sdk/src/transport.rs b/crates/openshell-sdk/src/transport.rs index 9b25ced28..84f7096c0 100644 --- a/crates/openshell-sdk/src/transport.rs +++ b/crates/openshell-sdk/src/transport.rs @@ -183,7 +183,7 @@ impl ServerCertVerifier for InsecureServerCertVerifier { } fn supported_verify_schemes(&self) -> Vec { - rustls::crypto::ring::default_provider() + rustls::crypto::aws_lc_rs::default_provider() .signature_verification_algorithms .supported_schemes() } diff --git a/crates/openshell-server/Cargo.toml b/crates/openshell-server/Cargo.toml index 2619fee5c..750132ea0 100644 --- a/crates/openshell-server/Cargo.toml +++ b/crates/openshell-server/Cargo.toml @@ -84,12 +84,12 @@ base64 = { workspace = true } futures = { workspace = true } bytes = { workspace = true } pin-project-lite = { workspace = true } -ring = { workspace = true } serde = { workspace = true } serde_json = { workspace = true } toml = { workspace = true } tokio-stream = { workspace = true } sqlx = { workspace = true } +sqlx-core = { workspace = true } reqwest = { workspace = true } aws-config = { workspace = true } aws-sdk-sts = { workspace = true } @@ -123,8 +123,8 @@ test-support = [] [dev-dependencies] base64 = { workspace = true } -hyper-rustls = { version = "0.27", default-features = false, features = ["native-tokio", "http1", "tls12", "logging", "ring"] } -rcgen = { version = "0.13", features = ["crypto", "pem"] } +hyper-rustls = { version = "0.27", default-features = false, features = ["native-tokio", "http1", "tls12", "logging", "aws-lc-rs"] } +rcgen = { workspace = true } rsa = { version = "0.9", features = ["pem"] } tokio-tungstenite = { workspace = true } futures-util = "0.3" diff --git a/crates/openshell-server/src/auth/extension_mint_limit.rs b/crates/openshell-server/src/auth/extension_mint_limit.rs index 0495cf034..fc825404b 100644 --- a/crates/openshell-server/src/auth/extension_mint_limit.rs +++ b/crates/openshell-server/src/auth/extension_mint_limit.rs @@ -18,7 +18,7 @@ use std::collections::HashMap; use std::sync::Mutex; use std::time::{Duration, Instant}; -const DEFAULT_WINDOW: Duration = Duration::from_secs(60); +const DEFAULT_WINDOW: Duration = Duration::from_mins(1); const DEFAULT_MAX_PER_WINDOW: u32 = 10; /// Number of tracked sandboxes above which expired windows are pruned. @@ -102,7 +102,7 @@ mod tests { #[test] fn allows_a_burst_then_refuses_within_the_window() { - let limiter = ExtensionMintLimiter::new(Duration::from_secs(60), 3); + let limiter = ExtensionMintLimiter::new(Duration::from_mins(1), 3); let start = Instant::now(); for _ in 0..3 { @@ -113,17 +113,17 @@ mod tests { #[test] fn window_rollover_restores_capacity() { - let limiter = ExtensionMintLimiter::new(Duration::from_secs(60), 1); + let limiter = ExtensionMintLimiter::new(Duration::from_mins(1), 1); let start = Instant::now(); assert!(limiter.try_acquire_at("sandbox-a", start)); assert!(!limiter.try_acquire_at("sandbox-a", start + Duration::from_secs(59))); - assert!(limiter.try_acquire_at("sandbox-a", start + Duration::from_secs(60))); + assert!(limiter.try_acquire_at("sandbox-a", start + Duration::from_mins(1))); } #[test] fn sandboxes_are_limited_independently() { - let limiter = ExtensionMintLimiter::new(Duration::from_secs(60), 1); + let limiter = ExtensionMintLimiter::new(Duration::from_mins(1), 1); let start = Instant::now(); assert!(limiter.try_acquire_at("sandbox-a", start)); @@ -147,7 +147,7 @@ mod tests { #[test] fn a_zero_bound_disables_limiting() { - let limiter = ExtensionMintLimiter::new(Duration::from_secs(60), 0); + let limiter = ExtensionMintLimiter::new(Duration::from_mins(1), 0); let start = Instant::now(); for _ in 0..1_000 { assert!(limiter.try_acquire_at("sandbox-a", start)); diff --git a/crates/openshell-server/src/auth/oidc.rs b/crates/openshell-server/src/auth/oidc.rs index b81e0e068..303dcb3c5 100644 --- a/crates/openshell-server/src/auth/oidc.rs +++ b/crates/openshell-server/src/auth/oidc.rs @@ -407,6 +407,7 @@ impl JwksCache { ); } + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let http = Client::builder() .timeout(Duration::from_secs(10)) .build() @@ -1607,7 +1608,7 @@ mod tests { // cooldown window, even if the test task is descheduled while the // rest of the server suite runs in parallel. *cache.last_kid_miss_refresh.write().await = - Instant::now().checked_add(Duration::from_secs(60)).unwrap(); + Instant::now().checked_add(Duration::from_mins(1)).unwrap(); for _ in 0..4 { let err = cache.validate_token(&unknown_kid_token).await.unwrap_err(); assert_eq!(err.code(), tonic::Code::Unauthenticated); diff --git a/crates/openshell-server/src/auth/sandbox_jwt.rs b/crates/openshell-server/src/auth/sandbox_jwt.rs index 9dc10b840..4b086f49c 100644 --- a/crates/openshell-server/src/auth/sandbox_jwt.rs +++ b/crates/openshell-server/src/auth/sandbox_jwt.rs @@ -417,7 +417,7 @@ mod tests { } fn pair() -> (SandboxJwtIssuer, SandboxJwtAuthenticator) { - pair_with_ttl(Duration::from_secs(3600)) + pair_with_ttl(Duration::from_hours(1)) } fn pair_with_ttl(ttl: Duration) -> (SandboxJwtIssuer, SandboxJwtAuthenticator) { @@ -472,7 +472,7 @@ mod tests { mat.signing_key_pem.as_bytes(), mat.kid.clone(), "test-gateway", - Duration::from_secs(3600), + Duration::from_hours(1), ) .expect("issuer"); let auth = SandboxJwtAuthenticator::from_pem( @@ -582,7 +582,7 @@ mod tests { mat.signing_key_pem.as_bytes(), mat.kid.clone(), "g", - Duration::from_secs(3600), + Duration::from_hours(1), ) .unwrap(); let auth = @@ -623,7 +623,7 @@ mod tests { &extension_audience("urn:openshell:extension:middleware:scanner"), ExtensionCallerKind::Gateway, None, - Duration::from_secs(300), + Duration::from_mins(5), ) .expect("gateway token"); let mut validation = Validation::new(Algorithm::EdDSA); @@ -644,7 +644,7 @@ mod tests { &extension_audience("urn:openshell:extension:middleware:scanner"), ExtensionCallerKind::Supervisor, Some("sandbox-a"), - Duration::from_secs(300), + Duration::from_mins(5), ) .expect("supervisor token"); let claims = decode::(&supervisor.token, &decoding_key, &validation) @@ -662,7 +662,7 @@ mod tests { mat.signing_key_pem.as_bytes(), mat.kid.clone(), "gateway-a", - Duration::from_secs(3600), + Duration::from_hours(1), ) .expect("issuer"); @@ -671,7 +671,7 @@ mod tests { &extension_audience("urn:openshell:extension:middleware:scanner"), ExtensionCallerKind::Gateway, None, - Duration::from_secs(300), + Duration::from_mins(5), ) .expect("extension token"); assert_eq!( @@ -704,7 +704,7 @@ mod tests { &extension_audience("service-a"), ExtensionCallerKind::Gateway, None, - Duration::from_secs(60), + Duration::from_mins(1), ) .expect("token"); let decoding_key = DecodingKey::from_ed_pem(mat.public_key_pem.as_bytes()).unwrap(); @@ -722,7 +722,7 @@ mod tests { &extension_audience("openshell-gateway:test-gateway"), ExtensionCallerKind::Supervisor, Some("sandbox-a"), - Duration::from_secs(60), + Duration::from_mins(1), ) .expect_err("gateway sandbox audience must be reserved"); assert_eq!(error.code(), tonic::Code::InvalidArgument); @@ -755,7 +755,7 @@ mod tests { &extension_audience("service"), ExtensionCallerKind::Supervisor, None, - Duration::from_secs(60), + Duration::from_mins(1), ) .is_err() ); @@ -765,7 +765,7 @@ mod tests { &extension_audience("service"), ExtensionCallerKind::Gateway, Some("sandbox-a"), - Duration::from_secs(60), + Duration::from_mins(1), ) .is_err() ); diff --git a/crates/openshell-server/src/cli.rs b/crates/openshell-server/src/cli.rs index 33008774b..b8b7dfd07 100644 --- a/crates/openshell-server/src/cli.rs +++ b/crates/openshell-server/src/cli.rs @@ -230,10 +230,6 @@ pub async fn run_cli() -> Result<()> { /// Run the gateway CLI with the compute drivers linked by the binary. pub async fn run_cli_with_compute_drivers(compute_drivers: ComputeDriverRegistry) -> Result<()> { - rustls::crypto::ring::default_provider() - .install_default() - .map_err(|e| miette::miette!("failed to install rustls crypto provider: {e:?}"))?; - let matches = command().get_matches(); let cli = Cli::from_arg_matches(&matches).expect("clap validated args"); diff --git a/crates/openshell-server/src/compute/lease.rs b/crates/openshell-server/src/compute/lease.rs index 3310946da..fbf039ec8 100644 --- a/crates/openshell-server/src/compute/lease.rs +++ b/crates/openshell-server/src/compute/lease.rs @@ -505,7 +505,7 @@ mod tests { l2.renew(&mut guard2).await.unwrap(); // Replica-1 cannot re-acquire (lease exists) - let l1_retry = lease(store.clone(), "replica-1", Duration::from_secs(60)); + let l1_retry = lease(store.clone(), "replica-1", Duration::from_mins(1)); let err = l1_retry.try_acquire().await.unwrap_err(); assert!(matches!(err, LeaseError::AlreadyHeld)); diff --git a/crates/openshell-server/src/compute/mod.rs b/crates/openshell-server/src/compute/mod.rs index 2b11946a6..70356e1ad 100644 --- a/crates/openshell-server/src/compute/mod.rs +++ b/crates/openshell-server/src/compute/mod.rs @@ -315,11 +315,11 @@ pub struct ComputeDriverInfoSnapshot { } /// Interval between store-vs-backend reconciliation sweeps. -const RECONCILE_INTERVAL: Duration = Duration::from_secs(60); +const RECONCILE_INTERVAL: Duration = Duration::from_mins(1); /// How long a sandbox can remain provisioning in the store without a /// corresponding backend resource before it is considered orphaned. -const ORPHAN_GRACE_PERIOD: Duration = Duration::from_secs(300); +const ORPHAN_GRACE_PERIOD: Duration = Duration::from_mins(5); // Re-export the shared error type under the name used by this module. pub use openshell_core::ComputeDriverError as ComputeError; diff --git a/crates/openshell-server/src/compute/rootfs_tar.rs b/crates/openshell-server/src/compute/rootfs_tar.rs index f14759d8e..3df1f831f 100644 --- a/crates/openshell-server/src/compute/rootfs_tar.rs +++ b/crates/openshell-server/src/compute/rootfs_tar.rs @@ -23,7 +23,7 @@ use tonic::Status; use tracing::{info, warn}; /// How long an allocated slot survives without being consumed. -const STAGING_TOKEN_TTL: Duration = Duration::from_secs(30 * 60); +const STAGING_TOKEN_TTL: Duration = Duration::from_mins(30); /// Outstanding slots one caller may hold. Bounds the directories a single /// authenticated caller can create by calling `begin` in a loop. const MAX_SLOTS_PER_CALLER: usize = 4; diff --git a/crates/openshell-server/src/grpc/auth_rpc.rs b/crates/openshell-server/src/grpc/auth_rpc.rs index 104d63958..62547cc29 100644 --- a/crates/openshell-server/src/grpc/auth_rpc.rs +++ b/crates/openshell-server/src/grpc/auth_rpc.rs @@ -193,7 +193,7 @@ pub async fn handle_refresh_sandbox_token( } const MAX_EXTENSION_CREDENTIALS_PER_REFRESH: usize = 64; -const DEFAULT_EXTENSION_TOKEN_TTL: Duration = Duration::from_secs(15 * 60); +const DEFAULT_EXTENSION_TOKEN_TTL: Duration = Duration::from_mins(15); #[allow(clippy::result_large_err)] fn mint_extension_credentials( @@ -323,7 +323,7 @@ mod tests { mat.signing_key_pem.as_bytes(), mat.kid, "test-gateway", - Duration::from_secs(3600), + Duration::from_hours(1), ) .unwrap(); state.sandbox_jwt_issuer = Some(Arc::new(issuer)); diff --git a/crates/openshell-server/src/grpc/policy.rs b/crates/openshell-server/src/grpc/policy.rs index 7e588fcac..054a3c34c 100644 --- a/crates/openshell-server/src/grpc/policy.rs +++ b/crates/openshell-server/src/grpc/policy.rs @@ -3215,7 +3215,13 @@ pub(super) async fn handle_update_config( let update = request.get_ref(); let should_emit_policy_failure = should_emit_config_update_policy_telemetry(sandbox_caller) && (update.policy.is_some() || !update.merge_operations.is_empty()); - let result = handle_update_config_inner(state, request, &principal, sandbox_caller).await; + let result = Box::pin(handle_update_config_inner( + state, + request, + &principal, + sandbox_caller, + )) + .await; if result.is_err() && should_emit_policy_failure { emit_sandbox_policy_update_failure(); } @@ -4599,7 +4605,7 @@ pub(super) async fn handle_submit_policy_analysis( // string means findings or infrastructure error, both of which // require human attention. if auto_approve_enabled - && let Err(err) = auto_approve_chunk( + && let Err(err) = Box::pin(auto_approve_chunk( state, &effective_id, AutoApproveChunkContext { @@ -4608,7 +4614,7 @@ pub(super) async fn handle_submit_policy_analysis( source: &req.analysis_mode, resolved_from, }, - ) + )) .await { persist_pending_application_error(state, &effective_id, &err).await; diff --git a/crates/openshell-server/src/grpc/provider.rs b/crates/openshell-server/src/grpc/provider.rs index 764c0bbfd..7238a3de5 100644 --- a/crates/openshell-server/src/grpc/provider.rs +++ b/crates/openshell-server/src/grpc/provider.rs @@ -2362,6 +2362,7 @@ const MAX_INTERMEDIATE_TOKEN_CACHE_ENTRIES: usize = 1024; static TOKEN_EXCHANGE_HTTP_CLIENT: LazyLock> = LazyLock::new(|| { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); reqwest::Client::builder() .timeout(std::time::Duration::from_secs(30)) .connect_timeout(std::time::Duration::from_secs(30)) diff --git a/crates/openshell-server/src/inference.rs b/crates/openshell-server/src/inference.rs index b83fd6be4..891dd5f0e 100644 --- a/crates/openshell-server/src/inference.rs +++ b/crates/openshell-server/src/inference.rs @@ -940,6 +940,7 @@ async fn verify_provider_endpoint( model_id: &str, route: &ResolvedProviderRoute, ) -> Result { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder() .timeout(Duration::from_secs(30)) .build() diff --git a/crates/openshell-server/src/lib.rs b/crates/openshell-server/src/lib.rs index a8c8afdf0..4582853ad 100644 --- a/crates/openshell-server/src/lib.rs +++ b/crates/openshell-server/src/lib.rs @@ -98,7 +98,7 @@ struct GatewayExtensionCredential { fn extension_token_ttl(issuer: &auth::sandbox_jwt::SandboxJwtIssuer) -> Duration { if issuer.ttl().is_zero() { - Duration::from_secs(15 * 60) + Duration::from_mins(15) } else { issuer.ttl().min(MAX_EXTENSION_TOKEN_TTL) } @@ -703,9 +703,9 @@ pub(crate) async fn run_server( } state.compute.spawn_watchers(shutdown_rx.clone()); - ssh_sessions::spawn_session_reaper(store.clone(), Duration::from_secs(3600)); + ssh_sessions::spawn_session_reaper(store.clone(), Duration::from_hours(1)); supervisor_session::spawn_relay_reaper(state.clone(), Duration::from_secs(30)); - provider_refresh::spawn_refresh_worker(state.clone(), Duration::from_secs(60)); + provider_refresh::spawn_refresh_worker(state.clone(), Duration::from_mins(1)); // Create the multiplexed service let service = MultiplexService::new(state.clone()); @@ -1610,9 +1610,8 @@ mod tests { use tokio::sync::watch; use crate::{ - compute::GatewayListenerRequirement, - gateway_listener::GatewayListenerSpec, - tls_test_utils::{generate_test_certs_with_ca, install_rustls_provider}, + compute::GatewayListenerRequirement, gateway_listener::GatewayListenerSpec, + tls_test_utils::generate_test_certs_with_ca, }; static DETECTION_PROBE_ORDER: LazyLock>> = @@ -1642,7 +1641,7 @@ mod tests { material.signing_key_pem.as_bytes(), material.kid, "gateway-a", - Duration::from_secs(900), + Duration::from_mins(15), ) .expect("issuer"), ) @@ -1773,8 +1772,6 @@ mod tests { } fn test_tls_acceptor() -> (TempDir, TlsAcceptor) { - install_rustls_provider(); - let dir = tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); diff --git a/crates/openshell-server/src/persistence/sqlite.rs b/crates/openshell-server/src/persistence/sqlite.rs index 3e96040e3..63852cef8 100644 --- a/crates/openshell-server/src/persistence/sqlite.rs +++ b/crates/openshell-server/src/persistence/sqlite.rs @@ -822,7 +822,8 @@ AND EXISTS ( ) .unwrap(); - let mut query = sqlx::query(&sql) + // Label paths above escape SQL quotes; all values remain bound parameters. + let mut query = sqlx::query(sqlx::AssertSqlSafe(sql.as_str())) .bind(object_type) .bind(member_type) .bind(member_name); diff --git a/crates/openshell-server/src/provider_refresh.rs b/crates/openshell-server/src/provider_refresh.rs index bba28c384..11f46daaf 100644 --- a/crates/openshell-server/src/provider_refresh.rs +++ b/crates/openshell-server/src/provider_refresh.rs @@ -1537,6 +1537,7 @@ async fn request_token( } } + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let client = reqwest::Client::builder() .timeout(Duration::from_secs(30)) .build() @@ -2401,6 +2402,7 @@ mod tests { .mount(&mock_server) .await; + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); let response = reqwest::get(format!("{}/oversized", mock_server.uri())) .await .unwrap(); diff --git a/crates/openshell-server/src/supervisor_session.rs b/crates/openshell-server/src/supervisor_session.rs index c8491dc1e..24413f0f1 100644 --- a/crates/openshell-server/src/supervisor_session.rs +++ b/crates/openshell-server/src/supervisor_session.rs @@ -1663,7 +1663,7 @@ mod tests { "sbx-test", relay_tx, Instant::now() - .checked_sub(Duration::from_secs(60)) + .checked_sub(Duration::from_mins(1)) .expect("test duration should be before now"), ), ); @@ -1741,7 +1741,7 @@ mod tests { "sbx-test", relay_tx, Instant::now() - .checked_sub(Duration::from_secs(60)) + .checked_sub(Duration::from_mins(1)) .expect("test duration should be before now"), ), ); diff --git a/crates/openshell-server/src/tls.rs b/crates/openshell-server/src/tls.rs index aa627746c..531daf787 100644 --- a/crates/openshell-server/src/tls.rs +++ b/crates/openshell-server/src/tls.rs @@ -18,7 +18,7 @@ use openshell_ocsf::{ ConfigStateChangeBuilder, OCSF_TARGET, SandboxContext, SeverityId, StateId, StatusId, }; use rustls::ServerConfig; -use rustls::crypto::ring::sign; +use rustls::crypto::aws_lc_rs::sign; use rustls::pki_types::{CertificateDer, PrivateKeyDer}; use rustls::server::{ClientHello, ResolvesServerCert, WebPkiClientVerifier}; use rustls::sign::CertifiedKey; @@ -488,9 +488,7 @@ fn tls_ocsf_ctx() -> SandboxContext { #[cfg(test)] mod tests { use super::*; - use crate::tls_test_utils::{ - generate_test_certs_with_ca, install_rustls_provider, write_test_file, - }; + use crate::tls_test_utils::{generate_test_certs_with_ca, write_test_file}; use rcgen::{CertificateParams, IsCa, KeyPair, KeyUsagePurpose}; use tokio::net::{TcpListener, TcpStream}; @@ -532,7 +530,6 @@ mod tests { #[test] fn test_build_server_config() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); let _ = generate_test_certs_with_ca(dir.path()); @@ -553,7 +550,6 @@ mod tests { #[test] fn test_reload_success() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); @@ -574,7 +570,6 @@ mod tests { #[test] fn test_reload_invalid_preserves_old() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); @@ -607,8 +602,6 @@ mod tests { #[tokio::test(flavor = "multi_thread")] async fn test_concurrent_handshake_and_reload() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); let acceptor = TlsAcceptor::from_files( @@ -702,8 +695,6 @@ mod tests { #[tokio::test] async fn test_reload_serves_new_cert() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); let acceptor = TlsAcceptor::from_files( @@ -778,8 +769,6 @@ mod tests { #[tokio::test] async fn test_reload_worker_shutdown() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); let acceptor = TlsAcceptor::from_files( @@ -812,8 +801,6 @@ mod tests { #[tokio::test] async fn test_reload_worker_detects_file_change() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); let acceptor = TlsAcceptor::from_files( @@ -902,8 +889,6 @@ mod tests { #[tokio::test] async fn test_reload_mtls_ca_rotation() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); let (initial_ca_cert, initial_ca_key) = generate_test_certs_with_ca(dir.path()); @@ -1110,7 +1095,6 @@ mod tests { #[test] fn test_build_cert_resolver_returns_none_when_no_external() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); @@ -1127,7 +1111,6 @@ mod tests { #[test] fn test_build_cert_resolver_errors_on_cert_without_key() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); @@ -1147,7 +1130,6 @@ mod tests { #[test] fn test_build_cert_resolver_errors_on_key_without_cert() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); generate_test_certs_with_ca(dir.path()); @@ -1167,7 +1149,6 @@ mod tests { #[test] fn test_build_cert_resolver_errors_on_empty_server_names() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); generate_named_cert( @@ -1195,7 +1176,6 @@ mod tests { #[test] fn test_dual_cert_resolver_returns_external_on_sni_match() { - install_rustls_provider(); let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); generate_named_cert( @@ -1233,8 +1213,6 @@ mod tests { #[tokio::test(flavor = "multi_thread")] async fn test_dual_cert_resolver_sni_selects_correct_cert() { - install_rustls_provider(); - let dir = tempfile::tempdir().expect("failed to create tempdir"); let (ca_cert, ca_key) = generate_test_certs_with_ca(dir.path()); generate_named_cert( diff --git a/crates/openshell-server/src/tls_test_utils.rs b/crates/openshell-server/src/tls_test_utils.rs index aee83c49e..bcb71b0b5 100644 --- a/crates/openshell-server/src/tls_test_utils.rs +++ b/crates/openshell-server/src/tls_test_utils.rs @@ -9,14 +9,6 @@ use std::path::Path; use rcgen::{CertificateParams, IsCa, KeyPair}; -/// Install the default rustls crypto provider. -/// -/// Must be called once at the start of any test that exercises TLS handshakes. -/// Multiple calls are harmless (subsequent calls return an error, ignored). -pub fn install_rustls_provider() { - let _ = rustls::crypto::ring::default_provider().install_default(); -} - /// Write bytes to a file inside `dir`, panicking on failure. pub fn write_test_file(dir: &Path, name: &str, data: &[u8]) { let path = dir.join(name); diff --git a/crates/openshell-server/tests/common/mod.rs b/crates/openshell-server/tests/common/mod.rs index 42711a754..695d8d8f2 100644 --- a/crates/openshell-server/tests/common/mod.rs +++ b/crates/openshell-server/tests/common/mod.rs @@ -613,11 +613,6 @@ impl OpenShell for TestOpenShell { // TLS / PKI helpers (used by TLS integration tests) // --------------------------------------------------------------------------- -/// Initialise the rustls crypto provider (idempotent). -pub fn install_rustls_provider() { - let _ = rustls::crypto::ring::default_provider().install_default(); -} - /// PKI bundle: CA cert, server cert+key, client cert+key (all PEM). #[allow(clippy::struct_field_names)] pub struct PkiBundle { diff --git a/crates/openshell-server/tests/edge_tunnel_auth.rs b/crates/openshell-server/tests/edge_tunnel_auth.rs index be70e4567..c236d9995 100644 --- a/crates/openshell-server/tests/edge_tunnel_auth.rs +++ b/crates/openshell-server/tests/edge_tunnel_auth.rs @@ -29,7 +29,7 @@ mod common; use bytes::Bytes; use common::{ PkiBundle, build_tls_root, generate_pki, generate_rogue_pki, grpc_client_mtls, - install_rustls_provider, start_test_server, + start_test_server, }; use http_body_util::Empty; use hyper::{Request, StatusCode}; @@ -160,7 +160,6 @@ fn https_client_no_cert( /// Valid client cert is accepted when a CA is configured. #[tokio::test] async fn mtls_valid_client_cert_accepted() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = TlsAcceptor::from_files( @@ -204,7 +203,6 @@ async fn mtls_valid_client_cert_accepted() { /// always optional. Auth is deferred to the application layer. #[tokio::test] async fn no_client_cert_accepted_with_ca_configured() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = TlsAcceptor::from_files( @@ -250,7 +248,6 @@ async fn no_client_cert_accepted_with_ca_configured() { /// cert is presented. #[tokio::test] async fn bearer_header_reaches_server_without_client_cert() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = TlsAcceptor::from_files( @@ -284,7 +281,6 @@ async fn bearer_header_reaches_server_without_client_cert() { /// client certs are optional — presented certs are still validated. #[tokio::test] async fn rogue_cert_rejected() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = TlsAcceptor::from_files( @@ -333,7 +329,6 @@ async fn rogue_cert_rejected() { /// client certificates. Clients connect with server-only TLS. #[tokio::test] async fn https_only_no_client_cert_required() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = TlsAcceptor::from_files( diff --git a/crates/openshell-server/tests/multiplex_tls_integration.rs b/crates/openshell-server/tests/multiplex_tls_integration.rs index 3447aad51..adc6837cc 100644 --- a/crates/openshell-server/tests/multiplex_tls_integration.rs +++ b/crates/openshell-server/tests/multiplex_tls_integration.rs @@ -6,7 +6,7 @@ mod common; use bytes::Bytes; use common::{ PkiBundle, build_tls_root, generate_pki, generate_rogue_pki, grpc_client_mtls, - install_rustls_provider, start_test_server, + start_test_server, }; use http_body_util::Empty; use hyper::Request; @@ -54,7 +54,6 @@ fn https_client_mtls( #[tokio::test] async fn serves_grpc_and_http_over_tls_on_same_port() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = openshell_server::TlsAcceptor::from_files( @@ -96,7 +95,6 @@ async fn serves_grpc_and_http_over_tls_on_same_port() { #[tokio::test] async fn mtls_valid_client_cert_accepted() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = openshell_server::TlsAcceptor::from_files( @@ -127,7 +125,6 @@ async fn mtls_valid_client_cert_accepted() { #[tokio::test] async fn no_client_cert_accepted_with_ca() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = openshell_server::TlsAcceptor::from_files( @@ -166,7 +163,6 @@ async fn no_client_cert_accepted_with_ca() { #[tokio::test] async fn no_client_cert_rejected_when_required() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = openshell_server::TlsAcceptor::from_files( @@ -206,7 +202,6 @@ async fn no_client_cert_rejected_when_required() { #[tokio::test] async fn mtls_wrong_ca_client_cert_rejected() { - install_rustls_provider(); let (temp, pki) = generate_pki(); let tls_acceptor = openshell_server::TlsAcceptor::from_files( diff --git a/crates/openshell-supervisor-network/src/inference_routes.rs b/crates/openshell-supervisor-network/src/inference_routes.rs index 22b406b8d..a262394b1 100644 --- a/crates/openshell-supervisor-network/src/inference_routes.rs +++ b/crates/openshell-supervisor-network/src/inference_routes.rs @@ -472,7 +472,7 @@ mod tests { ); assert_eq!( routes[1].timeout, - Duration::from_secs(120), + Duration::from_mins(2), "timeout_secs=120 should map to 120s" ); } diff --git a/crates/openshell-supervisor-network/src/l7/relay.rs b/crates/openshell-supervisor-network/src/l7/relay.rs index 1a5e82f64..aec52cf9c 100644 --- a/crates/openshell-supervisor-network/src/l7/relay.rs +++ b/crates/openshell-supervisor-network/src/l7/relay.rs @@ -7732,7 +7732,7 @@ network_policies: .await }); - let scenario = tokio::time::timeout(std::time::Duration::from_secs(60), async { + let scenario = tokio::time::timeout(std::time::Duration::from_mins(1), async { app.write_all( b"GET /ws HTTP/1.1\r\nHost: api.example.test\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\nSec-WebSocket-Version: 13\r\nSec-WebSocket-Extensions: permessage-deflate; client_no_context_takeover\r\n\r\n", ) diff --git a/crates/openshell-supervisor-network/src/l7/tls.rs b/crates/openshell-supervisor-network/src/l7/tls.rs index 2275a60d3..63e04089c 100644 --- a/crates/openshell-supervisor-network/src/l7/tls.rs +++ b/crates/openshell-supervisor-network/src/l7/tls.rs @@ -465,7 +465,6 @@ mod tests { #[test] fn upstream_config_alpn() { - let _ = rustls::crypto::ring::default_provider().install_default(); let config = build_upstream_client_config("").unwrap(); assert_eq!(config.alpn_protocols, vec![b"http/1.1".to_vec()]); } diff --git a/crates/openshell-supervisor-network/src/l7/websocket.rs b/crates/openshell-supervisor-network/src/l7/websocket.rs index febec7000..dab11a111 100644 --- a/crates/openshell-supervisor-network/src/l7/websocket.rs +++ b/crates/openshell-supervisor-network/src/l7/websocket.rs @@ -30,8 +30,8 @@ pub const MAX_QUEUED_WEBSOCKET_ASSEMBLIES: usize = MAX_CONCURRENT_WEBSOCKET_ASSE const MAX_RAW_FRAME_PAYLOAD_BYTES: u64 = 16 * 1024 * 1024; const MAX_MESSAGE_FRAGMENTS: usize = 4096; const TEXT_MESSAGE_ASSEMBLY_IDLE_TIMEOUT: StdDuration = StdDuration::from_secs(30); -const TEXT_MESSAGE_ASSEMBLY_TOTAL_TIMEOUT: StdDuration = StdDuration::from_secs(120); -const TEXT_MESSAGE_FORWARD_TOTAL_TIMEOUT: StdDuration = StdDuration::from_secs(120); +const TEXT_MESSAGE_ASSEMBLY_TOTAL_TIMEOUT: StdDuration = StdDuration::from_mins(2); +const TEXT_MESSAGE_FORWARD_TOTAL_TIMEOUT: StdDuration = StdDuration::from_mins(2); const COPY_BUF_SIZE: usize = 8192; const OPCODE_CONTINUATION: u8 = 0x0; const OPCODE_TEXT: u8 = 0x1; diff --git a/crates/openshell-supervisor-network/src/policy_dns/mod.rs b/crates/openshell-supervisor-network/src/policy_dns/mod.rs index b7dd13ca9..6c692e495 100644 --- a/crates/openshell-supervisor-network/src/policy_dns/mod.rs +++ b/crates/openshell-supervisor-network/src/policy_dns/mod.rs @@ -580,7 +580,7 @@ mod tests { calls: AtomicUsize::new(0), answer: TrustedAnswer { addresses, - ttl: Duration::from_secs(300), + ttl: Duration::from_mins(5), }, }, Arc::new(ResolvedEndpointStore::new( @@ -984,6 +984,6 @@ process: { run_as_user: sandbox, run_as_group: sandbox } clamp_mapping_ttl(Duration::from_secs(10)), Duration::from_secs(10) ); - assert_eq!(clamp_mapping_ttl(Duration::from_secs(300)), MAX_MAPPING_TTL); + assert_eq!(clamp_mapping_ttl(Duration::from_mins(5)), MAX_MAPPING_TTL); } } diff --git a/crates/openshell-supervisor-network/src/proxy.rs b/crates/openshell-supervisor-network/src/proxy.rs index 84df3801c..70c90b015 100644 --- a/crates/openshell-supervisor-network/src/proxy.rs +++ b/crates/openshell-supervisor-network/src/proxy.rs @@ -145,7 +145,7 @@ const MAX_STREAMING_BODY: usize = 1024; /// between "thinking" and output phases. 120s provides headroom while still /// catching genuinely stuck streams. #[cfg(not(test))] -const CHUNK_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(120); +const CHUNK_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_mins(2); // Exercise idle-timeout truncation without slowing the full package test suite. #[cfg(test)] const CHUNK_IDLE_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(100); @@ -6783,7 +6783,7 @@ network_policies: ) .await }); - let scenario = tokio::time::timeout(std::time::Duration::from_secs(60), async { + let scenario = tokio::time::timeout(std::time::Duration::from_mins(1), async { let (client, upstream) = tokio::join!(client, upstream); client.expect("join plaintext WebSocket client"); assert_eq!( diff --git a/crates/openshell-supervisor-network/src/token_grant.rs b/crates/openshell-supervisor-network/src/token_grant.rs index 15aea6fcc..4e4237f68 100644 --- a/crates/openshell-supervisor-network/src/token_grant.rs +++ b/crates/openshell-supervisor-network/src/token_grant.rs @@ -49,6 +49,7 @@ use spiffe::WorkloadApiClient; /// Token cache shared across all provider token grants. static TOKEN_CACHE: LazyLock = LazyLock::new(TokenCache::new); static TOKEN_GRANT_HTTP_CLIENT: LazyLock = LazyLock::new(|| { + let _ = rustls::crypto::aws_lc_rs::default_provider().install_default(); reqwest::Client::builder() .timeout(Duration::from_secs(30)) .connect_timeout(Duration::from_secs(30)) diff --git a/crates/openshell-supervisor-network/src/upstream_proxy.rs b/crates/openshell-supervisor-network/src/upstream_proxy.rs index f95c5a3e8..9cb5481df 100644 --- a/crates/openshell-supervisor-network/src/upstream_proxy.rs +++ b/crates/openshell-supervisor-network/src/upstream_proxy.rs @@ -1129,13 +1129,6 @@ mod tests { config_from(pairs).unwrap().unwrap() } - /// Install the process-wide rustls crypto provider once. Building a - /// `ClientConfig` (for an `https://` proxy) requires it; the install is - /// idempotent, so tests that build TLS configs call this first. - fn install_crypto_provider() { - let _ = rustls::crypto::ring::default_provider().install_default(); - } - #[test] fn no_env_yields_none() { assert!(config_from(&[]).unwrap().is_none()); @@ -1270,7 +1263,6 @@ mod tests { #[test] fn https_proxy_scheme_enables_tls_and_requires_explicit_port() { - install_crypto_provider(); // An explicit port is required (no scheme-default fallback), matching // the http:// grammar. let err = config_from(&[(HTTPS_PROXY, "https://proxy.corp.com")]).unwrap_err(); @@ -1314,7 +1306,6 @@ mod tests { #[test] fn unreadable_ca_bundle_is_fatal_for_https_proxy() { - install_crypto_provider(); let err = config_from(&[ (HTTPS_PROXY, "https://proxy.corp.com:3130"), (PROXY_CA_BUNDLE, "/nonexistent/proxy-ca.pem"), @@ -1338,7 +1329,6 @@ mod tests { #[test] fn ca_bundle_with_no_certificates_is_fatal() { - install_crypto_provider(); let bundle = tempfile::NamedTempFile::new().unwrap(); std::fs::write(bundle.path(), "not a certificate\n").unwrap(); let path = bundle.path().to_string_lossy().into_owned(); @@ -1352,7 +1342,6 @@ mod tests { #[test] fn ca_bundle_with_invalid_der_certificates_is_fatal() { - install_crypto_provider(); let bundle = tempfile::NamedTempFile::new().unwrap(); std::fs::write( bundle.path(), @@ -1439,7 +1428,6 @@ mod tests { #[test] fn auth_file_without_insecure_acknowledgement_is_allowed_for_https_proxy() { - install_crypto_provider(); let file = tempfile::NamedTempFile::new().unwrap(); std::fs::write(file.path(), "user:secret\n").unwrap(); let path = file.path().to_str().unwrap().to_string(); @@ -2013,8 +2001,6 @@ mod tests { const SERVER_HOSTNAME: &str = "upstream.example.test"; - let _ = rustls::crypto::ring::default_provider().install_default(); - // Trusted CA; the client config trusts it, and the fake upstream // server presents a leaf for SERVER_HOSTNAME signed by it. let ca = tls::SandboxCa::generate().unwrap(); @@ -2246,7 +2232,6 @@ mod tests { /// the server task (yielding the received CONNECT request), and the /// server certificate PEM to use as the corporate CA bundle. async fn fake_tls_proxy() -> (SocketAddr, tokio::task::JoinHandle, String) { - install_crypto_provider(); let key = rcgen::KeyPair::generate().unwrap(); let cert = rcgen::CertificateParams::new(vec!["127.0.0.1".to_string()]) .unwrap() diff --git a/deny.toml b/deny.toml index c0b4db8c1..b91a0699f 100644 --- a/deny.toml +++ b/deny.toml @@ -53,6 +53,7 @@ registries = [] # -- Bans ---------------------------------------------------------------------- [bans] +deny = [{ name = "ring", reason = "Use the AWS-LC crypto backend instead." }] multiple-versions = "warn" wildcards = "allow" highlight = "all" diff --git a/deploy/docker/Dockerfile.cli-macos b/deploy/docker/Dockerfile.cli-macos index af509ee97..f86cd594b 100644 --- a/deploy/docker/Dockerfile.cli-macos +++ b/deploy/docker/Dockerfile.cli-macos @@ -74,9 +74,7 @@ COPY crates/openshell-prover/Cargo.toml crates/openshell-prover/Cargo.toml COPY crates/openshell-core/build.rs crates/openshell-core/build.rs COPY proto/ proto/ -# Scope workspace to CLI crates only — avoids compiling aws-lc-sys (pulled -# by russh in openshell-sandbox/openshell-server) which is difficult to -# cross-compile and unnecessary for the CLI binary. +# Scope workspace to CLI crates only to avoid compiling unrelated runtimes. RUN sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-cli", "crates/openshell-core", "crates/openshell-bootstrap", "crates/openshell-policy", "crates/openshell-prover", "crates/openshell-providers", "crates/openshell-tui"]|' Cargo.toml RUN mkdir -p crates/openshell-cli/src \ diff --git a/e2e/rust/Cargo.lock b/e2e/rust/Cargo.lock index 88049ec0d..c5235dff8 100644 --- a/e2e/rust/Cargo.lock +++ b/e2e/rust/Cargo.lock @@ -31,6 +31,30 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "untrusted", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "axum" version = "0.8.9" @@ -157,6 +181,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -172,6 +198,15 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "cpufeatures" version = "0.2.17" @@ -218,6 +253,12 @@ dependencies = [ "syn 3.0.3", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.17.0" @@ -237,7 +278,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -267,6 +308,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.33" @@ -346,10 +393,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -665,6 +710,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.103" @@ -678,17 +733,20 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" dependencies = [ + "aws-lc-rs", "base64", + "getrandom 0.2.17", "js-sys", "pem", - "ring", "serde", "serde_json", + "signature", "simple_asn1", + "zeroize", ] [[package]] @@ -756,7 +814,7 @@ checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -923,6 +981,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + [[package]] name = "potential_utf" version = "0.1.5" @@ -1007,7 +1071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ "rand_chacha", - "rand_core", + "rand_core 0.9.5", ] [[package]] @@ -1017,7 +1081,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", ] [[package]] @@ -1038,20 +1111,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.17", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rustc-hash" version = "2.1.3" @@ -1068,7 +1127,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -1218,6 +1277,15 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "simple_asn1" version = "0.6.4" @@ -1249,7 +1317,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -1307,7 +1375,7 @@ dependencies = [ "getrandom 0.4.3", "once_cell", "rustix", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -1384,7 +1452,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", - "windows-sys 0.61.2", + "windows-sys", ] [[package]] @@ -1545,9 +1613,9 @@ checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "untrusted" -version = "0.9.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" @@ -1670,15 +1738,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - [[package]] name = "windows-sys" version = "0.61.2" @@ -1688,70 +1747,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - [[package]] name = "wit-bindgen" version = "0.57.1" @@ -1828,6 +1823,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "zerotrie" version = "0.2.4" diff --git a/e2e/rust/Cargo.toml b/e2e/rust/Cargo.toml index 8eb3403c6..4f34caa25 100644 --- a/e2e/rust/Cargo.toml +++ b/e2e/rust/Cargo.toml @@ -211,7 +211,7 @@ futures-util = "0.3" http-body-util = "0.1" hyper = { version = "1", features = ["client", "http1"] } hyper-util = { version = "0.1", features = ["tokio"] } -jsonwebtoken = "9" +jsonwebtoken = { version = "10", features = ["aws_lc_rs"] } prost = "0.14" tokio = { version = "1.43", features = ["full"] } tokio-stream = { version = "0.1", features = ["net"] } diff --git a/examples/governance-interceptor/Cargo.lock b/examples/governance-interceptor/Cargo.lock index b946e1f55..b0df0429d 100644 --- a/examples/governance-interceptor/Cargo.lock +++ b/examples/governance-interceptor/Cargo.lock @@ -55,6 +55,30 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "axum" version = "0.8.9" @@ -162,6 +186,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -185,7 +211,16 @@ checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cpufeatures 0.3.0", - "rand_core", + "rand_core 0.10.1", +] + +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", ] [[package]] @@ -281,6 +316,12 @@ dependencies = [ "syn", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.16.0" @@ -342,6 +383,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.32" @@ -398,10 +445,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -413,7 +458,7 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "rand_core", + "rand_core 0.10.1", ] [[package]] @@ -778,6 +823,16 @@ dependencies = [ "syn", ] +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "js-sys" version = "0.3.103" @@ -791,17 +846,20 @@ dependencies = [ [[package]] name = "jsonwebtoken" -version = "9.3.1" +version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +checksum = "eba32bfb4ffdeaca3e34431072faf01745c9b26d25504aa7a6cf5684334fc4fc" dependencies = [ + "aws-lc-rs", "base64", + "getrandom 0.2.17", "js-sys", "pem", - "ring", "serde", "serde_json", + "signature", "simple_asn1", + "zeroize", ] [[package]] @@ -1183,6 +1241,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + [[package]] name = "portable-atomic" version = "1.15.0" @@ -1396,7 +1460,16 @@ checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ "chacha20", "getrandom 0.4.3", - "rand_core", + "rand_core 0.10.1", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", ] [[package]] @@ -1411,8 +1484,8 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" dependencies = [ + "aws-lc-rs", "pem", - "ring", "rustls-pki-types", "time", "yasna", @@ -1466,7 +1539,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] @@ -1510,9 +1583,9 @@ version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ + "aws-lc-rs", "log", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -1555,9 +1628,10 @@ version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -1699,6 +1773,15 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "simd_cesu8" version = "1.2.0" @@ -2154,6 +2237,12 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -2415,6 +2504,20 @@ name = "zeroize" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "zerotrie" diff --git a/examples/governance-interceptor/Cargo.toml b/examples/governance-interceptor/Cargo.toml index e55d18efd..890ef67dc 100644 --- a/examples/governance-interceptor/Cargo.toml +++ b/examples/governance-interceptor/Cargo.toml @@ -7,18 +7,18 @@ name = "openshell-governance-interceptor-example" version = "0.0.0" edition = "2024" -rust-version = "1.90" +rust-version = "1.94" license = "Apache-2.0" [dependencies] -jsonwebtoken = "9" +jsonwebtoken = { version = "10", features = ["aws_lc_rs"] } openshell-core = { path = "../../crates/openshell-core", default-features = false } openshell-policy = { path = "../../crates/openshell-policy" } openshell-providers = { path = "../../crates/openshell-providers" } prost = "0.14" prost-reflect = { version = "0.16.5", features = ["serde"] } prost-types = "0.14" -rcgen = { version = "0.13", features = ["crypto", "pem"] } +rcgen = { version = "0.13", default-features = false, features = ["crypto", "pem", "aws_lc_rs"] } serde = { version = "1", features = ["derive"] } serde_json = "1" serde_yml = { package = "noyalib", version = "0.0.28", default-features = false, features = ["std", "compat-serde-yaml"] } diff --git a/examples/supervisor-middleware-content-guard/Cargo.lock b/examples/supervisor-middleware-content-guard/Cargo.lock index 8ce16c010..f19951981 100644 --- a/examples/supervisor-middleware-content-guard/Cargo.lock +++ b/examples/supervisor-middleware-content-guard/Cargo.lock @@ -99,6 +99,29 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "aws-lc-rs" +version = "1.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" +dependencies = [ + "aws-lc-sys", + "zeroize", +] + +[[package]] +name = "aws-lc-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" +dependencies = [ + "cc", + "cmake", + "dunce", + "fs_extra", + "pkg-config", +] + [[package]] name = "axum" version = "0.8.9" @@ -191,6 +214,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", + "jobserver", + "libc", "shlex", ] @@ -246,6 +271,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +[[package]] +name = "cmake" +version = "0.1.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f78a02292a74a88ac736019ab962ece0bc380e3f977bf72e376c5d78ff0678" +dependencies = [ + "cc", +] + [[package]] name = "colorchoice" version = "1.0.5" @@ -279,6 +313,12 @@ dependencies = [ "syn", ] +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + [[package]] name = "either" version = "1.16.0" @@ -340,6 +380,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + [[package]] name = "futures-channel" version = "0.3.32" @@ -699,6 +745,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +[[package]] +name = "jobserver" +version = "0.1.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" +dependencies = [ + "getrandom 0.4.3", + "libc", +] + [[package]] name = "libc" version = "0.2.186" @@ -970,6 +1026,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pkg-config" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" + [[package]] name = "potential_utf" version = "0.1.5" @@ -1227,9 +1289,9 @@ version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ + "aws-lc-rs", "log", "once_cell", - "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -1272,6 +1334,7 @@ version = "0.103.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" dependencies = [ + "aws-lc-rs", "ring", "rustls-pki-types", "untrusted", diff --git a/examples/supervisor-middleware-content-guard/Cargo.toml b/examples/supervisor-middleware-content-guard/Cargo.toml index ef0d1f47c..135316979 100644 --- a/examples/supervisor-middleware-content-guard/Cargo.toml +++ b/examples/supervisor-middleware-content-guard/Cargo.toml @@ -8,7 +8,7 @@ name = "openshell-supervisor-middleware-content-guard" description = "Example OpenShell supervisor middleware service" version = "0.0.0" edition = "2024" -rust-version = "1.90" +rust-version = "1.94" license = "Apache-2.0" publish = false