Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/bench.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand Down
31 changes: 16 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,13 @@ jobs:
- uses: actions/checkout@v6
with:
persist-credentials: false
# dprint formats TOML + Markdown + Rust. The exec plugin shells out to
# rustfmt for Rust, so the toolchain (with rustfmt) must be on PATH first.
# Plugin versions/checksums are pinned in dprint.json, so output is
# deterministic regardless of CLI version.
- uses: dtolnay/rust-toolchain@stable
# dprint formats TOML + Markdown + Rust via its exec plugin, which shells
# out to rustfmt, so the toolchain must be present. setup-rust-toolchain
# installs it from rust-toolchain.toml (including the rustfmt component).
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt
cache: false
rustflags: ""
- uses: dprint/check@v2.3

check:
Expand All @@ -88,11 +88,7 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@stable
with:
components: clippy

- uses: Swatinem/rust-cache@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand All @@ -116,17 +112,22 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@nightly
- id: nightly
run: echo "toolchain=$(cat .rust-nightly)" >> "$GITHUB_OUTPUT"

- uses: Swatinem/rust-cache@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
workspaces: fuzz -> fuzz/target
toolchain: ${{ steps.nightly.outputs.toolchain }}
rustflags: ""
cache-workspaces: fuzz -> fuzz/target

- name: Install protoc
uses: arduino/setup-protoc@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}

- name: Check fuzz targets
run: cargo check
env:
NIGHTLY: ${{ steps.nightly.outputs.toolchain }}
run: cargo "+$NIGHTLY" check
working-directory: fuzz
6 changes: 3 additions & 3 deletions .github/workflows/demo-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@stable

- uses: Swatinem/rust-cache@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand Down
15 changes: 9 additions & 6 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,17 @@ jobs:
persist-credentials: false

- name: Install Rust nightly (required by cargo-doc-md)
uses: dtolnay/rust-toolchain@nightly

- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: nightly
cache: false
rustflags: ""

- uses: Swatinem/rust-cache@v2
- name: Install Rust (pinned in rust-toolchain.toml)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
shared-key: docs
rustflags: ""
cache-shared-key: docs

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand Down
14 changes: 10 additions & 4 deletions .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ jobs:
with:
persist-credentials: false

- uses: dtolnay/rust-toolchain@nightly
- id: nightly
run: echo "toolchain=$(cat .rust-nightly)" >> "$GITHUB_OUTPUT"

- uses: Swatinem/rust-cache@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
workspaces: fuzz -> fuzz/target
toolchain: ${{ steps.nightly.outputs.toolchain }}
rustflags: ""
cache-workspaces: fuzz -> fuzz/target

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand All @@ -40,4 +43,7 @@ jobs:
run: cargo binstall --no-confirm --locked cargo-fuzz

- name: Run ${{ matrix.target }}
run: cargo fuzz run --target x86_64-unknown-linux-gnu ${{ matrix.target }} -- -max_total_time=300
env:
NIGHTLY: ${{ steps.nightly.outputs.toolchain }}
TARGET: ${{ matrix.target }}
run: cargo "+$NIGHTLY" fuzz run --target x86_64-unknown-linux-gnu "$TARGET" -- -max_total_time=300
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,11 @@ jobs:
fi
echo "version=${VERSION}" >> "${GITHUB_OUTPUT}"

- uses: dtolnay/rust-toolchain@stable
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
targets: ${{ matrix.target }}
target: ${{ matrix.target }}
cache: false
rustflags: ""

- name: Install protoc
uses: arduino/setup-protoc@v3
Expand Down
1 change: 1 addition & 0 deletions .rust-nightly
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nightly-2026-06-04
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ version = "0.1.1"
edition = "2024"
license = "Apache-2.0"
repository = "https://github.com/Firma-AI/openfirma"
rust-version = "1.88.0"

[workspace.lints.clippy]
pedantic = { level = "deny", priority = -1 }
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ deny:

check: fmt lint test build audit deny

# Requires nightly: rustup toolchain install nightly
# Pinned nightly lives in .rust-nightly (cargo-fuzz requires nightly).
fuzz-check:
cd fuzz && cargo +nightly check
cd fuzz && cargo +$(shell cat .rust-nightly) check

bench:
cargo bench --workspace --no-fail-fast
Expand Down
1 change: 0 additions & 1 deletion crates/firma-authority/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Mini Authority — policy loading, capability issuance, and gRPC streams for Firma OSS"

[dependencies]
Expand Down
1 change: 0 additions & 1 deletion crates/firma-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Platform config-path discovery for the firma CLI"

[lints]
Expand Down
1 change: 0 additions & 1 deletion crates/firma-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Shared types, capability tokens, Cedar wrapper, and error types for Firma OSS"

[dependencies]
Expand Down
1 change: 0 additions & 1 deletion crates/firma-demo-fixture/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Deterministic ALLOW/DENY fixture server and CI driver client for the Firma demo"

[lints]
Expand Down
1 change: 0 additions & 1 deletion crates/firma-demo-tui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true

[[bin]]
name = "firma-demo-tui"
Expand Down
1 change: 0 additions & 1 deletion crates/firma-grpc-interceptor-proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Protobuf/gRPC definitions for the Firma interceptor hook (agent to sidecar)"

[dependencies]
Expand Down
1 change: 0 additions & 1 deletion crates/firma-proto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Protobuf/gRPC service definitions and generated code for Firma OSS"

[dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/firma-proto/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn build_channel(
.connect_timeout(connect_timeout)
.keep_alive_timeout(Duration::from_secs(30))
.http2_keep_alive_interval(Duration::from_secs(30))
.tcp_keepalive(Some(Duration::from_secs(60)));
.tcp_keepalive(Some(Duration::from_mins(1)));

match scheme.as_str() {
"https" => {
Expand Down
1 change: 0 additions & 1 deletion crates/firma-run/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true

[lints]
workspace = true
Expand Down
22 changes: 14 additions & 8 deletions crates/firma-run/src/proxy_bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,12 +810,7 @@ fn find_crlf(buffer: &[u8]) -> Option<usize> {
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::time::Duration;

#[cfg(unix)]
use super::HostBridgeHandle;
use super::{BodyKind, append_missing_headers, find_header_terminator, parse_request_metadata};

#[test]
Expand Down Expand Up @@ -874,14 +869,27 @@ mod tests {
let meta = parse_request_metadata(req).expect("metadata");
assert_eq!(meta.body, BodyKind::Chunked);
}
}

// The bridge spins up real TCP listeners and only exists on the non-structural
// (macOS) path, so these tests are Unix-only and grouped here to keep the
// platform gate on the module rather than on each test and import.
#[cfg(test)]
#[cfg(unix)]
mod host_bridge_tests {
use std::collections::BTreeMap;
use std::io::{Read, Write};
use std::net::{SocketAddr, TcpListener, TcpStream};
use std::time::Duration;

use super::HostBridgeHandle;

/// Verifies that `HostBridgeHandle` injects `x-firma-session-id` into a
/// plain HTTP request routed through the bridge.
///
/// This is the regression test for FIR-213: on macOS (non-structural path)
/// the bridge was never started, so the sidecar received an empty
/// `session_id` and denied every request.
#[cfg(unix)]
#[test]
fn host_bridge_injects_session_id_into_http_request() {
// ── upstream mock ──────────────────────────────────────────────────
Expand Down Expand Up @@ -951,7 +959,6 @@ mod tests {

/// Verifies that `HostBridgeHandle` injects `x-firma-session-id` into the
/// CONNECT request that Claude Code issues for HTTPS destinations.
#[cfg(unix)]
#[test]
fn host_bridge_injects_session_id_into_connect_request() {
let upstream_listener = TcpListener::bind("127.0.0.1:0").expect("upstream bind");
Expand Down Expand Up @@ -1013,7 +1020,6 @@ mod tests {

/// Verifies that an existing `x-firma-session-id` header is not
/// duplicated when the client already carries one.
#[cfg(unix)]
#[test]
fn host_bridge_does_not_duplicate_existing_session_id() {
let upstream_listener = TcpListener::bind("127.0.0.1:0").expect("upstream bind");
Expand Down
1 change: 0 additions & 1 deletion crates/firma-sidecar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "HTTP proxy sidecar with enforcement pipeline for Firma OSS"

[features]
Expand Down
4 changes: 2 additions & 2 deletions crates/firma-sidecar/src/local_exec/endpoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ impl LocalExecEndpoint {
let store_for_pruner = self.handler.token_store();
let prune_cancel = cancel.clone();
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(60));
let mut interval = tokio::time::interval(Duration::from_mins(1));
loop {
tokio::select! {
() = prune_cancel.cancelled() => break,
Expand Down Expand Up @@ -375,7 +375,7 @@ mod tests {
let socket_path = tmp.path().join("test-local-exec.sock");
let config = LocalExecHandlerConfig {
default_action: action,
token_ttl: Duration::from_secs(60),
token_ttl: Duration::from_mins(1),
retry_after_ms: 500,
};
let handler = LocalExecHandler::new(config);
Expand Down
2 changes: 1 addition & 1 deletion crates/firma-sidecar/src/local_exec/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ mod tests {
fn config(action: DefaultAction) -> LocalExecHandlerConfig {
LocalExecHandlerConfig {
default_action: action,
token_ttl: Duration::from_secs(60),
token_ttl: Duration::from_mins(1),
retry_after_ms: 500,
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/firma-sidecar/src/local_exec/token_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ impl InMemoryTokenStore {
Self {
tokens: Mutex::new(HashMap::new()),
ttl,
expiry_grace: Duration::from_secs(300),
expiry_grace: Duration::from_mins(5),
}
}

Expand Down Expand Up @@ -423,7 +423,7 @@ mod tests {
use super::*;

fn store() -> InMemoryTokenStore {
InMemoryTokenStore::new(Duration::from_secs(60))
InMemoryTokenStore::new(Duration::from_mins(1))
}

fn issue_token(store: &InMemoryTokenStore) -> String {
Expand Down
1 change: 0 additions & 1 deletion crates/firma-stack/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Process supervision and observability primitives for the firma stack"

[lints]
Expand Down
6 changes: 3 additions & 3 deletions crates/firma-stack/src/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ fn spawn_stack_inner(cfg: &StackConfig, state_dir: &Path) -> Result<StackHandle>
let auth_addr = read_authority_listen_addr(&cfg.config_file)?;
std::fs::write(state_dir.join("authority.listen"), format!("{auth_addr}\n"))?;
debug!(addr = %auth_addr, "waiting for authority TCP listen");
wait_for_tcp("authority", auth_addr, Duration::from_secs(60))?;
wait_for_tcp("authority", auth_addr, Duration::from_mins(1))?;
info!(addr = %auth_addr, "authority listening");

debug!(config = %cfg.config_file.display(), exe = ?exe, "spawning sidecar");
Expand All @@ -100,12 +100,12 @@ fn spawn_stack_inner(cfg: &StackConfig, state_dir: &Path) -> Result<StackHandle>
let side_addr = read_sidecar_listen_addr(&cfg.config_file)?;
std::fs::write(state_dir.join("sidecar.listen"), format!("{side_addr}\n"))?;
debug!(addr = %side_addr, "waiting for sidecar TCP listen");
wait_for_tcp("sidecar", side_addr, Duration::from_secs(60))?;
wait_for_tcp("sidecar", side_addr, Duration::from_mins(1))?;
info!(addr = %side_addr, "sidecar listening");
debug!("waiting for sidecar CA material");
wait_for_ca_material(
&state_dir.join("generated-firma-ca"),
Duration::from_secs(60),
Duration::from_mins(1),
)?;
debug!("CA material present");

Expand Down
1 change: 0 additions & 1 deletion crates/firma/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
rust-version.workspace = true
description = "Firma CLI for managing and running OpenFirma components"

[[bin]]
Expand Down
Loading
Loading