diff --git a/agent/file_safety.py b/agent/file_safety.py index 2e08db3d02229..13693669b85bb 100644 --- a/agent/file_safety.py +++ b/agent/file_safety.py @@ -282,6 +282,7 @@ def get_read_block_error(path: str) -> Optional[str]: # to avoid re-fetching across back-to-back CLI invocations. The file # was introduced by #31968 but not added to this guard. os.path.join("cache", "bws_cache.json"), + os.path.join("cache", "bws_cache.enc.json"), ) for hd in hermes_dirs: for name in credential_file_names: diff --git a/tests/agent/test_file_safety_bws_enc.py b/tests/agent/test_file_safety_bws_enc.py new file mode 100644 index 0000000000000..04295833e6a32 --- /dev/null +++ b/tests/agent/test_file_safety_bws_enc.py @@ -0,0 +1,46 @@ +"""Regression tests verifying bws_cache.enc.json is denied in get_read_block_error.""" + +import os +from pathlib import Path +from unittest.mock import patch + +from agent.file_safety import get_read_block_error, is_write_denied, _hermes_home_path + + +class TestFileSafetyBwsEnc: + """Verify bws_cache.enc.json read protection parity with write protection.""" + + def test_bws_cache_enc_read_blocked(self, tmp_path): + home = tmp_path / "hermes_home" + home.mkdir() + cache_dir = home / "cache" + cache_dir.mkdir() + bws_enc = cache_dir / "bws_cache.enc.json" + bws_enc.write_text("{}") + + with patch("agent.file_safety._hermes_home_path", return_value=home), \ + patch("agent.file_safety._hermes_root_path", return_value=home): + err = get_read_block_error(str(bws_enc)) + assert err is not None + assert "Access denied" in err + assert "Hermes credential store" in err + + def test_bws_cache_plain_and_enc_parity(self, tmp_path): + home = tmp_path / "hermes_home" + home.mkdir() + cache_dir = home / "cache" + cache_dir.mkdir() + + plain = cache_dir / "bws_cache.json" + enc = cache_dir / "bws_cache.enc.json" + other = cache_dir / "image.png" + + plain.write_text("{}") + enc.write_text("{}") + other.write_text("data") + + with patch("agent.file_safety._hermes_home_path", return_value=home), \ + patch("agent.file_safety._hermes_root_path", return_value=home): + assert get_read_block_error(str(plain)) is not None + assert get_read_block_error(str(enc)) is not None + assert get_read_block_error(str(other)) is None