Skip to content
Open
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
3 changes: 3 additions & 0 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,9 @@ jobs:
- name: Verify telemetry can be compiled out
run: mise run rust:verify:telemetry-off

- name: Verify the defaults-without-telemetry feature alias tracks the default feature set
run: mise run rust:verify:defaults-without-telemetry

- name: Verify system CA roots build mode compiles and excludes bundled Mozilla roots
run: mise run rust:verify:system-ca-roots

Expand Down
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,15 @@ OpenShell collects anonymous telemetry to help improve the project for developer

Disable telemetry at runtime by setting `OPENSHELL_TELEMETRY_ENABLED=false` on the gateway deployment. For Helm installs, set `server.telemetryEnabled=false`. OpenShell propagates this deployment setting into sandbox supervisor environments so sandbox-side telemetry collection is disabled as well.

You can also compile telemetry out entirely. Telemetry support is a default-on `telemetry` Cargo feature; building with `--no-default-features` produces binaries that contain no telemetry endpoint, no telemetry HTTP client, and no emission code. Build telemetry-free artifacts with, for example, `cargo build --release -p openshell-server --no-default-features` (gateway) and the equivalent for `openshell-sandbox` and `openshell-driver-vm`. With telemetry compiled out, the gateway emits nothing and reports telemetry disabled to the sandboxes it launches.
You can also compile telemetry out entirely. Telemetry support is a default-on `telemetry` Cargo feature, and each crate that carries it also defines a `defaults-without-telemetry` alias covering every other default feature. Build telemetry-free artifacts with `--no-default-features --features defaults-without-telemetry`:

```shell
cargo build --release -p openshell-server --no-default-features --features defaults-without-telemetry
cargo build --release -p openshell-sandbox --no-default-features --features defaults-without-telemetry
cargo build --release -p openshell-driver-vm --no-default-features --features defaults-without-telemetry
```

The resulting binaries contain no telemetry endpoint, no telemetry HTTP client, and no emission code. With telemetry compiled out, the gateway emits nothing and reports telemetry disabled to the sandboxes it launches. Cargo has no way to subtract a single default feature, so `defaults-without-telemetry` must be paired with `--no-default-features`; passing it on its own leaves the defaults in place and fails the build rather than producing a binary that still emits.

Telemetry events are limited to anonymous operational categories and counts, such as sandbox lifecycle outcomes, provider profile buckets, policy decision counts, and aggregate network activity denial categories. OpenShell telemetry does not collect sandbox names or IDs, hostnames, file paths, binary paths, prompts, credentials, provider names, model names, or user content.

Expand Down
27 changes: 21 additions & 6 deletions architecture/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,27 @@ is the single switch that enables `openshell-core/telemetry` for its build
graph. In-process drivers (`docker`, `kubernetes`, `podman`) inherit the
gateway's setting through feature unification and carry no passthrough.

Building a binary with `--no-default-features` compiles out telemetry entirely:
no endpoint, no telemetry HTTP client, and no emission code. With telemetry
compiled out, `telemetry::enabled()` is always `false` and the `emit_*` helpers
are no-ops, so the data-model types stay available and dependent crates compile
unchanged. The runtime `OPENSHELL_TELEMETRY_ENABLED` switch remains the way to
disable telemetry in a default (telemetry-enabled) build.
Building a binary without the `telemetry` feature compiles out telemetry
entirely: no endpoint, no telemetry HTTP client, and no emission code. With
telemetry compiled out, `telemetry::enabled()` is always `false` and the
`emit_*` helpers are no-ops, so the data-model types stay available and
dependent crates compile unchanged. The runtime `OPENSHELL_TELEMETRY_ENABLED`
switch remains the way to disable telemetry in a default (telemetry-enabled)
build.

Cargo cannot subtract a single default feature, so each of the three binary
crates also defines a `defaults-without-telemetry` alias listing every default
except `telemetry`. Telemetry-free builds use
`--no-default-features --features defaults-without-telemetry` and stay correct
as the default set grows, instead of dropping unrelated defaults the way a bare
`--no-default-features` does on `openshell-sandbox`. The alias is a keep-list,
not a switch: enabling it on top of the defaults would otherwise yield a
telemetry-on binary that reads as telemetry-free, so each crate root carries a
`compile_error!` for the `telemetry` + `defaults-without-telemetry` combination.
`rust:verify:defaults-without-telemetry` guards both properties — that each
alias still equals its crate's defaults minus `telemetry`, and that the
mutual-exclusion error is wired up — and `rust:verify:telemetry-off` builds
through the alias and inspects the resulting binaries for telemetry markers.

Supervisor upstream TLS root-store selection is controlled by the
`bundled-ca-roots` Cargo feature (on by default). Default builds use Mozilla
Expand Down
9 changes: 9 additions & 0 deletions crates/openshell-driver-vm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ default = ["telemetry"]
## default; build with `--no-default-features` for a telemetry-free VM driver
## that reports telemetry disabled to the sandboxes it launches.
telemetry = ["openshell-core/telemetry"]
## Convenience alias: every default feature except `telemetry`. Build a
## telemetry-free VM driver with
## `--no-default-features --features defaults-without-telemetry` and stay
## correct as new default features are added. Cargo cannot subtract a single
## default feature, so this alias must be paired with `--no-default-features`;
## enabling it alongside `telemetry` is a compile error rather than a silent
## telemetry-on build. Kept in sync with `default` by
## `rust:verify:defaults-without-telemetry`.
defaults-without-telemetry = []

[dev-dependencies]
temp-env = "0.3"
Expand Down
10 changes: 10 additions & 0 deletions crates/openshell-driver-vm/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

// `defaults-without-telemetry` is an alias for the default feature set minus
// `telemetry`, not a switch that turns telemetry off. Cargo cannot subtract a
// default feature, so adding it on top of the defaults would otherwise produce
// a telemetry-on build that reads as telemetry-free. Fail the build instead.
#[cfg(all(feature = "telemetry", feature = "defaults-without-telemetry"))]
compile_error!(
"features `telemetry` and `defaults-without-telemetry` are mutually exclusive; \
build a telemetry-free VM driver with `--no-default-features --features defaults-without-telemetry`"
);

pub mod driver;
mod embedded_runtime;
mod ffi;
Expand Down
11 changes: 11 additions & 0 deletions crates/openshell-sandbox/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ default = ["telemetry", "bundled-ca-roots"]
## `--no-default-features --features system-ca-roots` to build a supervisor
## that uses the platform trust store with telemetry intact.
system-ca-roots = ["telemetry"]
## Convenience alias: every default feature except `telemetry`. Build a
## telemetry-free supervisor with
## `--no-default-features --features defaults-without-telemetry` and stay
## correct as new default features are added. Cargo cannot subtract a single
## default feature, so this alias must be paired with `--no-default-features`;
## enabling it alongside `telemetry` is a compile error rather than a silent
## telemetry-on build. Kept in sync with `default` by
## `rust:verify:defaults-without-telemetry`. Do not pair it with
## `system-ca-roots`, which re-enables `telemetry`; a build with neither
## telemetry nor bundled CA roots is plain `--no-default-features`.
defaults-without-telemetry = ["bundled-ca-roots"]

telemetry = ["openshell-core/telemetry"]
bundled-ca-roots = ["openshell-supervisor-network/bundled-ca-roots"]
Expand Down
10 changes: 10 additions & 0 deletions crates/openshell-sandbox/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
//!
//! This crate provides process sandboxing and monitoring capabilities.

// `defaults-without-telemetry` is an alias for the default feature set minus
// `telemetry`, not a switch that turns telemetry off. Cargo cannot subtract a
// default feature, so adding it on top of the defaults would otherwise produce
// a telemetry-on build that reads as telemetry-free. Fail the build instead.
#[cfg(all(feature = "telemetry", feature = "defaults-without-telemetry"))]
compile_error!(
"features `telemetry` and `defaults-without-telemetry` are mutually exclusive; \
build a telemetry-free supervisor with `--no-default-features --features defaults-without-telemetry`"
);

mod activity_aggregator;
mod denial_aggregator;
#[cfg_attr(not(target_os = "linux"), allow(dead_code))]
Expand Down
9 changes: 9 additions & 0 deletions crates/openshell-server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,15 @@ default = ["telemetry"]
## On by default; build with `--no-default-features` for a telemetry-free gateway
## that contains no telemetry endpoint, HTTP client, or emission code.
telemetry = ["openshell-core/telemetry"]
## Convenience alias: every default feature except `telemetry`. Build a
## telemetry-free gateway with
## `--no-default-features --features defaults-without-telemetry` and stay
## correct as new default features are added. Cargo cannot subtract a single
## default feature, so this alias must be paired with `--no-default-features`;
## enabling it alongside `telemetry` is a compile error rather than a silent
## telemetry-on build. Kept in sync with `default` by
## `rust:verify:defaults-without-telemetry`.
defaults-without-telemetry = []
bundled-z3 = ["openshell-prover/bundled-z3"]
test-support = []

Expand Down
10 changes: 10 additions & 0 deletions crates/openshell-server/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@
//! The VM launch plumbing now lives in [`compute::vm`]; keep this file limited
//! to selecting and acquiring drivers.

// `defaults-without-telemetry` is an alias for the default feature set minus
// `telemetry`, not a switch that turns telemetry off. Cargo cannot subtract a
// default feature, so adding it on top of the defaults would otherwise produce
// a telemetry-on build that reads as telemetry-free. Fail the build instead.
#[cfg(all(feature = "telemetry", feature = "defaults-without-telemetry"))]
compile_error!(
"features `telemetry` and `defaults-without-telemetry` are mutually exclusive; \
build a telemetry-free gateway with `--no-default-features --features defaults-without-telemetry`"
);

mod auth;
pub mod certgen;
pub mod cli;
Expand Down
12 changes: 9 additions & 3 deletions tasks/rust.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,19 @@ run = [
# markers, so the absent checks below can never become silently vacuous.
"cargo build -p openshell-server --bin openshell-gateway",
"tasks/scripts/verify-telemetry-compiled-out.sh present target/debug/openshell-gateway",
# Guard: telemetry-free builds must contain no telemetry markers.
"cargo build -p openshell-server --bin openshell-gateway --no-default-features",
# Guard: telemetry-free builds must contain no telemetry markers. Built
# through the `defaults-without-telemetry` alias, which is how the docs tell
# operators to produce these artifacts.
"cargo build -p openshell-server --bin openshell-gateway --no-default-features --features defaults-without-telemetry",
"tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-gateway",
"cargo build -p openshell-sandbox --bin openshell-sandbox --no-default-features --features bundled-ca-roots",
"cargo build -p openshell-sandbox --bin openshell-sandbox --no-default-features --features defaults-without-telemetry",
"tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-sandbox",
]

["rust:verify:defaults-without-telemetry"]
description = "Verify the defaults-without-telemetry feature alias matches default minus telemetry and cannot be used additively"
run = "tasks/scripts/verify-defaults-without-telemetry.sh"

["rust:verify:system-ca-roots"]
description = "Verify system CA roots build mode compiles and excludes bundled Mozilla root crates"
run = [
Expand Down
88 changes: 88 additions & 0 deletions tasks/scripts/verify-defaults-without-telemetry.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Verify the `defaults-without-telemetry` alias still means "every default
# feature except telemetry", and that it cannot be used additively.
#
# Cargo cannot subtract a single default feature, so telemetry-free builds use
# `--no-default-features --features defaults-without-telemetry`. Two failure
# modes follow from that, and this guard covers both:
#
# 1. Drift. The alias enumerates the keep-list by hand, so it silently rots
# the moment a crate gains a new default feature. Telemetry-free builds
# would then quietly lose an unrelated default.
# 2. Additive misuse. `--features defaults-without-telemetry` without
# `--no-default-features` would otherwise compile a telemetry-on binary
# that reads as telemetry-free. Each crate root carries a `compile_error!`
# for that combination; this asserts the error is actually wired up.

set -euo pipefail

# Crates that define the alias. Each must forward `telemetry` and define
# `defaults-without-telemetry`.
CRATES=(
openshell-server
openshell-sandbox
openshell-driver-vm
)

if ! command -v jq >/dev/null 2>&1; then
echo "error: 'jq' is required to inspect cargo metadata" >&2
exit 2
fi

metadata=$(cargo metadata --no-deps --format-version 1)

failed=0
for crate in "${CRATES[@]}"; do
features=$(jq -c --arg crate "$crate" \
'.packages[] | select(.name == $crate) | .features' <<<"$metadata")

if [[ -z $features || $features == "null" ]]; then
echo "FAIL: crate '$crate' not found in workspace metadata" >&2
failed=1
continue
fi

if ! jq -e 'has("defaults-without-telemetry")' <<<"$features" >/dev/null; then
echo "FAIL: $crate defines no 'defaults-without-telemetry' feature" >&2
failed=1
continue
fi

expected=$(jq -r '(.default // []) - ["telemetry"] | sort | join(",")' <<<"$features")
actual=$(jq -r '(."defaults-without-telemetry" // []) | sort | join(",")' <<<"$features")

if [[ $expected != "$actual" ]]; then
echo "FAIL: $crate 'defaults-without-telemetry' is out of sync with 'default'" >&2
echo " default minus telemetry: [${expected}]" >&2
echo " defaults-without-telemetry: [${actual}]" >&2
echo " Update 'defaults-without-telemetry' in crates/$crate/Cargo.toml to match." >&2
failed=1
continue
fi

echo "OK: $crate 'defaults-without-telemetry' == default minus telemetry [${expected}]"
done

# Additive misuse must be a hard error. Match on the `compile_error!` text
# rather than a nonzero exit code: openshell-driver-vm does not build on every
# host, and a check that failed for an unrelated reason would make this guard
# silently vacuous.
for crate in "${CRATES[@]}"; do
output=$(cargo check -p "$crate" --features defaults-without-telemetry 2>&1 || true)

if grep -qF "features \`telemetry\` and \`defaults-without-telemetry\` are mutually exclusive" <<<"$output"; then
echo "OK: $crate rejects 'telemetry' + 'defaults-without-telemetry'"
continue
fi

echo "FAIL: $crate did not reject 'telemetry' + 'defaults-without-telemetry'" >&2
echo " Expected the mutual-exclusion compile_error! in crates/$crate/src/lib.rs." >&2
echo " Got:" >&2
sed 's/^/ /' <<<"$output" | tail -20 >&2
failed=1
done

exit "$failed"
Loading