From a7b9e175c1d10d0caa4e6541e236428698f9ac92 Mon Sep 17 00:00:00 2001 From: dinos Date: Wed, 8 Jul 2026 20:25:01 +0200 Subject: [PATCH] fix(config): set config.yaml permissions to 0x600 (#336) --- EvoScientist/config/settings.py | 8 ++++++++ tests/test_config.py | 17 +++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/EvoScientist/config/settings.py b/EvoScientist/config/settings.py index fb0088e..0793a9c 100644 --- a/EvoScientist/config/settings.py +++ b/EvoScientist/config/settings.py @@ -548,6 +548,10 @@ def save_config(config: EvoScientistConfig) -> None: """ config_path = get_config_path() config_path.parent.mkdir(parents=True, exist_ok=True) + try: + config_path.parent.chmod(0o700) + except OSError: + pass data = _config_to_dict(config) @@ -560,6 +564,10 @@ def save_config(config: EvoScientistConfig) -> None: sort_keys=False, allow_unicode=True, ) + try: + config_path.chmod(0o600) + except OSError: + pass def reset_config() -> None: diff --git a/tests/test_config.py b/tests/test_config.py index e68b1e5..8799da5 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -242,6 +242,23 @@ class TestLoadSaveReset: assert data["provider"] == "openai" assert data["model"] == "gpt-4o" + def test_save_restricts_config_permissions(self, temp_config_dir, clean_env): + """Config file permissions should not depend on the process umask.""" + original_umask = os.umask(0) + try: + save_config(EvoScientistConfig(anthropic_api_key="test-key")) + finally: + os.umask(original_umask) + + config_path = get_config_path() + if os.name == "nt": + assert config_path.exists() + # Windows reports pseudo-permission bits, so we don't test them here. + return + + assert config_path.parent.stat().st_mode & 0o777 == 0o700 + assert config_path.stat().st_mode & 0o777 == 0o600 + def test_load_reads_saved_config(self, temp_config_dir, clean_env): """Test that load reads previously saved config.""" original = EvoScientistConfig(