Skip to content
Closed
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
23 changes: 14 additions & 9 deletions crates/capsem-core/src/credential_broker/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ struct EnvGuard {
}

impl EnvGuard {
fn install(capsem_home: &std::path::Path, home: &std::path::Path, test_store: &std::path::Path) -> Self {
fn install(
_lock: &tokio::sync::MutexGuard<'_, ()>,
capsem_home: &std::path::Path,
home: &std::path::Path,
test_store: &std::path::Path,
) -> Self {
CredentialStore::global().clear_for_test();
let old_home = std::env::var("HOME").ok();
let old_store = std::env::var(STORE_PATH_ENV).ok();
Expand Down Expand Up @@ -333,7 +338,7 @@ fn brokered_reference_does_not_leak_secret_to_unbound_domain() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

// Seed a real Anthropic secret and get its opaque broker reference.
let obs = CredentialObservation {
Expand Down Expand Up @@ -377,7 +382,7 @@ fn brokered_reference_substitutes_for_matching_provider_domain() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let obs = CredentialObservation {
provider: CredentialProvider::Anthropic,
Expand Down Expand Up @@ -405,7 +410,7 @@ fn broker_stores_secret_without_writing_user_settings() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let obs = CredentialObservation {
provider: CredentialProvider::Github,
Expand Down Expand Up @@ -443,7 +448,7 @@ fn duplicate_capture_is_memory_fast_and_does_not_rewrite_durable_store() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let obs = CredentialObservation {
provider: CredentialProvider::OpenAi,
Expand Down Expand Up @@ -476,7 +481,7 @@ fn replay_status_is_memory_only_and_hydration_is_explicit() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let empty_status = credential_store_status();
assert_eq!(empty_status.backend, "disk_override");
Expand Down Expand Up @@ -527,7 +532,7 @@ fn substitution_resolution_rehydrates_runtime_cache_on_real_use() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let obs = CredentialObservation {
provider: CredentialProvider::OpenAi,
Expand Down Expand Up @@ -558,7 +563,7 @@ fn broker_test_store_preserves_concurrent_captures() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let observations: Vec<_> = (0..64)
.map(|index| CredentialObservation {
Expand Down Expand Up @@ -601,7 +606,7 @@ fn replay_availability_requires_resolvable_broker_secret() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let missing = credential_reference("google", "not-stored");
assert!(!broker_reference_replay_available(Some("google"), &missing));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ fn brokered_reference_is_never_dereferenced_for_lookalike_domain() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let secret = "sk-openai-real-key-do-not-leak";
let reference = seed(CredentialProvider::OpenAi, secret);
Expand Down Expand Up @@ -148,7 +148,7 @@ fn injection_ledger_does_not_attribute_lookalike_domains_to_a_provider() {
let dir = tempfile::tempdir().unwrap();
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);
let reference = seed(CredentialProvider::Anthropic, "sk-ant-ledger-secret");

let found = detect_brokered_http_references("evil-anthropic.com", None, &bearer(&reference), None, None);
Expand Down
16 changes: 11 additions & 5 deletions crates/capsem-core/src/fs_monitor/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ struct EnvGuard {
}

impl EnvGuard {
fn install(capsem_home: &std::path::Path, home: &std::path::Path, test_store: &std::path::Path) -> Self {
fn install(
_lock: &tokio::sync::MutexGuard<'_, ()>,
capsem_home: &std::path::Path,
home: &std::path::Path,
test_store: &std::path::Path,
) -> Self {
let old_home = std::env::var("HOME").ok();
let old_store = std::env::var(crate::credential_broker::STORE_PATH_ENV).ok();
std::env::set_var("HOME", home);
Expand Down Expand Up @@ -334,7 +339,7 @@ async fn emit_brokers_env_credentials_and_persists_reference() {
let env_path = dir.path().join(".env");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);
std::fs::write(&env_path, "OPENAI_API_KEY=sk-env-secret\n").unwrap();

let db = DbWriter::open(&db_path, 64).unwrap();
Expand Down Expand Up @@ -585,7 +590,7 @@ async fn env_symlink_to_a_host_secret_is_never_read_or_brokered() {
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let host_secret = dir.path().join("host-credentials");
std::fs::write(&host_secret, "AWS_SECRET_ACCESS_KEY=sk-host-only-secret\n").unwrap();
Expand Down Expand Up @@ -630,7 +635,7 @@ async fn env_symlink_is_refused_by_the_open_even_if_it_claims_to_be_a_file() {
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let host_secret = dir.path().join("host-credentials");
std::fs::write(&host_secret, "AWS_SECRET_ACCESS_KEY=sk-host-only-secret\n").unwrap();
Expand Down Expand Up @@ -871,6 +876,7 @@ async fn overflow_defers_events_to_the_next_scan_and_records_a_marker() {
/// workspace wherever the guest moved it.
#[tokio::test]
async fn a_workspace_swapped_for_a_host_link_is_never_walked_or_read() {
let _lock = crate::credential_broker::TEST_ENV_LOCK.lock().await;
let dir = tempfile::tempdir().unwrap();
let share = dir.path().join("guest");
let workspace = share.join("workspace");
Expand All @@ -894,7 +900,7 @@ async fn a_workspace_swapped_for_a_host_link_is_never_walked_or_read() {

let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);
let db = DbWriter::open(&dir.path().join("session.db"), 64).unwrap();
let brokered = FsMonitor::broker_env_file_credentials(
&EmitContext {
Expand Down
48 changes: 27 additions & 21 deletions crates/capsem-core/src/net/mitm_proxy/telemetry_hook/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,38 +62,26 @@ fn any_conn() -> ConnMeta {

struct EnvGuard {
// Redirects CAPSEM_HOME/RUN_DIR/ASSETS_DIR together; restores on drop.
// None for trace-only guards, which redirect no paths.
_capsem_paths: Option<capsem_foundation::paths::CapsemPathsGuard>,
_capsem_paths: capsem_foundation::paths::CapsemPathsGuard,
old_home: Option<String>,
old_store: Option<String>,
old_trace: Option<String>,
}

impl EnvGuard {
fn install(capsem_home: &std::path::Path, home: &std::path::Path, test_store: &std::path::Path) -> Self {
fn install(
_lock: &tokio::sync::MutexGuard<'_, ()>,
capsem_home: &std::path::Path,
home: &std::path::Path,
test_store: &std::path::Path,
) -> Self {
let old_home = std::env::var("HOME").ok();
let old_store = std::env::var(crate::credential_broker::STORE_PATH_ENV).ok();
let old_trace = std::env::var("CAPSEM_TRACE_ID").ok();
std::env::set_var("HOME", home);
std::env::set_var(crate::credential_broker::STORE_PATH_ENV, test_store);
Self {
_capsem_paths: Some(capsem_foundation::paths::CapsemPathsGuard::redirect(capsem_home)),
old_home,
old_store,
old_trace,
}
}

fn trace_only(trace_id: &str) -> Self {
let old_home = std::env::var("HOME").ok();
let old_store = std::env::var(crate::credential_broker::STORE_PATH_ENV).ok();
let old_trace = std::env::var("CAPSEM_TRACE_ID").ok();
std::env::set_var("CAPSEM_TRACE_ID", trace_id);
Self {
_capsem_paths: None,
_capsem_paths: capsem_foundation::paths::CapsemPathsGuard::redirect(capsem_home),
old_home,
old_store,
old_trace,
}
}
}
Expand All @@ -108,6 +96,23 @@ impl Drop for EnvGuard {
Some(v) => std::env::set_var(crate::credential_broker::STORE_PATH_ENV, v),
None => std::env::remove_var(crate::credential_broker::STORE_PATH_ENV),
}
}
}

struct TraceEnvGuard {
old_trace: Option<String>,
}

impl TraceEnvGuard {
fn install(_lock: &tokio::sync::MutexGuard<'_, ()>, trace_id: &str) -> Self {
let old_trace = std::env::var("CAPSEM_TRACE_ID").ok();
std::env::set_var("CAPSEM_TRACE_ID", trace_id);
Self { old_trace }
}
}

impl Drop for TraceEnvGuard {
fn drop(&mut self) {
match &self.old_trace {
Some(v) => std::env::set_var("CAPSEM_TRACE_ID", v),
None => std::env::remove_var("CAPSEM_TRACE_ID"),
Expand Down Expand Up @@ -373,7 +378,8 @@ fn agy_google_tool_call_survives_into_ledger_counters() {

#[test]
fn openai_non_streaming_tool_call_carries_request_trace() {
let _trace_guard = EnvGuard::trace_only("feedfacecafebeef");
let _lock = crate::credential_broker::TEST_ENV_LOCK.blocking_lock();
let _trace_guard = TraceEnvGuard::install(&_lock, "feedfacecafebeef");
let mut req_ctx = anthropic_req_ctx();
req_ctx.domain = "127.0.0.1".into();
req_ctx.ai_provider = Some(ProviderKind::OpenAi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ async fn an_observed_credential_is_redacted_from_every_stored_header_and_body()
let dir = tempfile::tempdir().unwrap();
let db_path = dir.path().join("session.db");
let _guard = EnvGuard::install(
&_lock,
&dir.path().join("capsem-home"),
dir.path(),
&dir.path().join("credential-store.json"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async fn hook_writes_substitution_event_and_shared_credential_ref() {
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let db = Arc::new(DbWriter::open(&db_path, 64).expect("test db"));
let deps = Arc::new(TelemetryDeps {
Expand Down Expand Up @@ -87,7 +87,7 @@ async fn hook_does_not_repay_capture_ledger_for_repeated_identical_credential()
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let db = Arc::new(DbWriter::open(&db_path, 64).expect("test db"));
let deps = Arc::new(TelemetryDeps {
Expand Down Expand Up @@ -309,7 +309,7 @@ async fn hook_writes_injected_substitution_event_for_broker_ref_replay() {
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let db = Arc::new(DbWriter::open(&db_path, 64).expect("test db"));
let deps = Arc::new(TelemetryDeps {
Expand Down Expand Up @@ -379,7 +379,7 @@ async fn hook_detects_response_body_token_exchange_and_redacts_preview() {
let db_path = dir.path().join("session.db");
let capsem_home = dir.path().join("capsem-home");
let test_store = dir.path().join("credential-store.json");
let _guard = EnvGuard::install(&capsem_home, dir.path(), &test_store);
let _guard = EnvGuard::install(&_lock, &capsem_home, dir.path(), &test_store);

let db = Arc::new(DbWriter::open(&db_path, 64).expect("test db"));
let deps = Arc::new(TelemetryDeps {
Expand Down
Loading