diff --git a/Cargo.lock b/Cargo.lock index f38eab53..05d3d0f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1688,8 +1688,9 @@ dependencies = [ name = "base-client-cli" version = "0.0.0" dependencies = [ - "alloy-rpc-types-engine", + "base-jwt", "clap", + "eyre", "url", ] diff --git a/crates/client/cli/Cargo.toml b/crates/client/cli/Cargo.toml index 463d0954..b9da0c87 100644 --- a/crates/client/cli/Cargo.toml +++ b/crates/client/cli/Cargo.toml @@ -15,4 +15,7 @@ workspace = true # General url.workspace = true clap.workspace = true -alloy-rpc-types-engine.workspace = true +eyre.workspace = true + +# Base +base-jwt = { workspace = true, features = ["engine-validation"] } diff --git a/crates/client/cli/src/l2.rs b/crates/client/cli/src/l2.rs index ed0198d8..201e374b 100644 --- a/crates/client/cli/src/l2.rs +++ b/crates/client/cli/src/l2.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; -use alloy_rpc_types_engine::JwtSecret; +use base_jwt::{JwtError, JwtSecret, JwtValidator, resolve_jwt_secret}; use url::Url; const DEFAULT_L2_ENGINE_TIMEOUT: u64 = 30_000; @@ -51,3 +51,28 @@ impl Default for L2ClientArgs { } } } + +impl L2ClientArgs { + /// Returns the L2 JWT secret for the engine API. + /// + /// Resolution order: + /// 1. Read from file path if `l2_engine_jwt_secret` is set + /// 2. Use encoded secret if `l2_engine_jwt_encoded` is set + /// 3. Fall back to default JWT file `l2_jwt.hex` + pub fn jwt_secret(&self) -> Result { + resolve_jwt_secret( + self.l2_engine_jwt_secret.as_deref(), + self.l2_engine_jwt_encoded, + "l2_jwt.hex", + ) + } + + /// Validate the jwt secret if specified by exchanging capabilities with the engine. + /// Since the engine client will fail if the jwt token is invalid, this allows to ensure + /// that the jwt token passed as a cli arg is correct. + pub async fn validate_jwt(&self) -> eyre::Result { + let jwt_secret = self.jwt_secret().map_err(|e| eyre::eyre!(e))?; + let validator = JwtValidator::new(jwt_secret); + validator.validate_with_engine(self.l2_engine_rpc.clone()).await.map_err(|e| eyre::eyre!(e)) + } +} diff --git a/deny.toml b/deny.toml index 144ac394..0352839e 100644 --- a/deny.toml +++ b/deny.toml @@ -1,3 +1,51 @@ +[advisories] +# Ignore unmaintained/vulnerable crates that come from upstream dependencies we cannot control +ignore = [ + # rustls-pemfile is unmaintained but comes from bollard -> testcontainers (dev dependency) + # No safe upgrade available, waiting for upstream to migrate to rustls-pki-types + "RUSTSEC-2025-0134", + + # tokio-tar has a PAX header vulnerability but comes from testcontainers (dev dependency) + # No safe upgrade available, tokio-tar is archived + "RUSTSEC-2025-0111", + + # backoff is unmaintained but comes from rollup-boost -> kona-engine (upstream dependency) + # No safe upgrade available + "RUSTSEC-2025-0012", + + # bincode is unmaintained but comes from reth-nippy-jar (upstream reth dependency) + # No safe upgrade available + "RUSTSEC-2025-0141", + + # instant is unmaintained but comes from backoff -> rollup-boost (upstream dependency) + # No safe upgrade available + "RUSTSEC-2024-0384", + + # paste is unmaintained but widely used in ecosystem (alloy, reth, etc.) + # No safe upgrade available + "RUSTSEC-2024-0436", +] + +[licenses] +allow = [ + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Unicode-3.0", + "Unlicense", + "Zlib", + "CC0-1.0", + "MPL-2.0", + "0BSD", + "BSL-1.0", + "OpenSSL", + "CDLA-Permissive-2.0", +] +confidence-threshold = 0.8 + [bans] deny = ["reth"] multiple-versions = "deny" @@ -61,7 +109,6 @@ skip = [ "redox_users", # Network crates - "yamux", "tungstenite", "tokio-tungstenite", @@ -75,7 +122,20 @@ skip = [ "cargo_metadata", "core-foundation", "crossterm", - "if-addrs", + "gloo-timers", + "indexmap", + "kona-genesis", + "opentelemetry", + "opentelemetry-http", + "opentelemetry-otlp", + "opentelemetry-proto", + "opentelemetry_sdk", + "prost", + "prost-derive", + "rustc-hash", + "tonic", + "tower", + "tracing-opentelemetry", "openssl-probe", "procfs", "procfs-core", @@ -84,6 +144,16 @@ skip = [ "toml_datetime", "toml_edit", "unicode-width", - "unsigned-varint", "webpki-roots", ] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" + +# Allow git sources from known upstream repositories +allow-git = [ + "https://github.com/paradigmxyz/reth", + "https://github.com/op-rs/kona", + "https://github.com/flashbots/rollup-boost.git", +]