From 37538cdbc13e11114abc8b9867e08d8270277a98 Mon Sep 17 00:00:00 2001 From: Jesse Rosenberger Date: Fri, 6 Mar 2026 11:54:50 +0200 Subject: [PATCH 1/2] fix(compliance): bump bytes, lru, and time to address security advisories - bytes 1.11.0 -> 1.11.1 (RUSTSEC-2026-0007: integer overflow in BytesMut::reserve) - lru 0.16.2 -> 0.16.3 (RUSTSEC-2026-0002: IterMut soundness issue) - time 0.3.44 -> 0.3.47 (RUSTSEC-2026-0009: DoS via stack exhaustion in RFC 2822 parser) - Remove obsolete advisory exemptions (RUSTSEC-2024-0376, RUSTSEC-2024-0421) from deny.toml - Bump cargo-deny to 0.19.0, cargo-binstall to 1.16.3, helm to 3.19.4 --- .config/mise/config.toml | 6 +++--- Cargo.lock | 26 +++++++++++++------------- deny.toml | 2 -- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/.config/mise/config.toml b/.config/mise/config.toml index dfb4128bad..901eb17bc5 100644 --- a/.config/mise/config.toml +++ b/.config/mise/config.toml @@ -1,9 +1,9 @@ [tools] # renovate-automation: rustc version rust = "1.91.1" -"aqua:cargo-bins/cargo-binstall" = "1.16.2" +"aqua:cargo-bins/cargo-binstall" = "1.16.3" "cargo:cargo-nextest" = "0.9.70" -"cargo:cargo-deny" = "0.18.2" +"cargo:cargo-deny" = "0.19.0" "cargo:cargo-edit" = "0.13.0" "cargo:cargo-about" = "0.8.0" "cargo:cargo-insta" = "1.38.0" @@ -13,7 +13,7 @@ rust = "1.91.1" "cargo:typos-cli" = "1.31.1" protoc = "33.1" gh = "2.72.0" -helm = "3.19.2" +helm = "3.19.4" helm-docs = "1.14.2" yq = "4.49.2" jq = "1.8.1" diff --git a/Cargo.lock b/Cargo.lock index e7c22d88a5..9f3335d8f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1469,9 +1469,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" dependencies = [ "serde", ] @@ -4095,9 +4095,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96051b46fc183dc9cd4a223960ef37b9af631b55191852a8274bfef064cda20f" +checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593" dependencies = [ "hashbrown 0.16.1", ] @@ -4425,9 +4425,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -6791,9 +6791,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -6801,22 +6801,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", diff --git a/deny.toml b/deny.toml index 043c48fa76..66561762ab 100644 --- a/deny.toml +++ b/deny.toml @@ -23,8 +23,6 @@ git-fetch-with-cli = true # rustsec advisory exemptions ignore = [ "RUSTSEC-2023-0071", - "RUSTSEC-2024-0376", # we do not use tonic::transport::Server - "RUSTSEC-2024-0421", # we only resolve trusted subgraphs # protobuf is used only through prometheus crates, enforced by # a `[bans]` entry below. in the prometheus crates, only the protobuf From af30b0ad1ccf30ebfd13eb914c8b6ef52d0ed960 Mon Sep 17 00:00:00 2001 From: Aaron Date: Thu, 18 Dec 2025 13:24:28 -0500 Subject: [PATCH 2/2] [THIS UNBLOCKS DEV] fix(allowed features): int test, log, erroring (#8768) --- .changesets/fix_license_handling.md | 7 ++++++ apollo-router/src/state_machine.rs | 22 ++++++++++++------- .../tests/integration/allowed_features.rs | 3 +++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 .changesets/fix_license_handling.md diff --git a/.changesets/fix_license_handling.md b/.changesets/fix_license_handling.md new file mode 100644 index 0000000000..86a2f25863 --- /dev/null +++ b/.changesets/fix_license_handling.md @@ -0,0 +1,7 @@ +### Fix: Proper handling of licenses in a warning state + +We allowed licenses in a warning state to bypass enforcement because we weren't returning an error, only the limits. This was happening, I think, because there's middleware handling expired licenses but not licenses in a warning state. So, we assumed that there'd be same kind of handling for licenses in a warning state. Alas, there's not. + +We now error out if there are restricted features in use. + +By [@aaronarinder](https://github.com/aaronarinder) in https://github.com/apollographql/router/pull/8768 diff --git a/apollo-router/src/state_machine.rs b/apollo-router/src/state_machine.rs index 882f55ca05..af5c1ce5e8 100644 --- a/apollo-router/src/state_machine.rs +++ b/apollo-router/src/state_machine.rs @@ -354,13 +354,15 @@ impl State { LicenseState::LicensedWarn { limits } => { if report.uses_restricted_features() { tracing::error!( - "License has expired. The Router will soon stop serving requests. In order to enable these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{}\n\nSee {LICENSE_EXPIRED_URL} for more information.", + "License violation, the router is using features not available for your license:\n\n{}\n\nThe license warning period has started. The Router will stop serving requests after the license expires. See {LICENSE_EXPIRED_URL} for more information.", report ); - limits + return Err(ApolloRouterError::LicenseViolation( + report.restricted_features_in_use(), + )); } else { - tracing::error!( - "License has expired. The Router will soon stop serving requests. In order to enable these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{:?}\n\nSee {LICENSE_EXPIRED_URL} for more information.", + tracing::warn!( + "License warning period has started. The Router will stop serving requests after the license expires. In order to continue using these features for a self-hosted instance of Apollo Router, the Router must be connected to a graph in GraphOS that provides an active license for the following features:\n\n{:?}\n\nSee {LICENSE_EXPIRED_URL} for more information.", // The report does not contain any features because they are contained within the allowedFeatures claim, // therefore we output all of the allowed features that the user's license enables them to use. license.get_allowed_features() @@ -1146,8 +1148,10 @@ mod tests { #[case] config: Arc, #[case] allowed_features: Vec, ) { - let router_factory = create_mock_router_configurator(1); - let (server_factory, shutdown_receivers) = create_mock_server_factory(1); + // errors happen before this would be hit; so, 0, but we still need to pass _something_ to + // execute() + let router_factory = create_mock_router_configurator(0); + let (server_factory, shutdown_receivers) = create_mock_server_factory(0); assert_matches!( execute( @@ -1166,9 +1170,11 @@ mod tests { ]) ) .await, - Ok(()) + // this is where the real test happens; we expect a license violation if we're using + // features that aren't being paid for + Err(ApolloRouterError::LicenseViolation(_)) ); - assert_eq!(shutdown_receivers.0.lock().len(), 1); + assert_eq!(shutdown_receivers.0.lock().len(), 0); } #[test(tokio::test)] diff --git a/apollo-router/tests/integration/allowed_features.rs b/apollo-router/tests/integration/allowed_features.rs index 4f82cda0b3..88c3f52e04 100644 --- a/apollo-router/tests/integration/allowed_features.rs +++ b/apollo-router/tests/integration/allowed_features.rs @@ -650,6 +650,9 @@ async fn feature_violation_when_license_past_warn_at_but_not_expired_allowed_fea .build() .await; + router.replace_config_string("http://localhost:{{PRODUCTS_PORT}}", "localhost:4001"); + router.replace_config_string("http://localhost:{{ACCOUNTS_PORT}}", "localhost:4002"); + router.start().await; router .assert_error_log_contained(LICENSE_ALLOWED_FEATURES_DOES_NOT_INCLUDE_FEATURE_MSG)