Skip to content

Commit f0694c6

Browse files
committed
Scrub secrets
1 parent 2d40983 commit f0694c6

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

codeclash/utils/environment.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@
1010
# Patterns to exclude when copying between containers
1111
COPY_EXCLUDE_PATTERNS = [".git", "__pycache__"]
1212

13+
# Secret env vars whose values must never be recorded in command output / trajectories.
14+
_SECRET_ENV_VARS = ("GITHUB_TOKEN", "LLAMA_API_KEY")
15+
16+
17+
def redact_secrets(text: str | None) -> str | None:
18+
"""Replace known secret values with a placeholder so they never land in recorded output."""
19+
if not text:
20+
return text
21+
for var in _SECRET_ENV_VARS:
22+
val = os.getenv(var)
23+
if val and val in text:
24+
text = text.replace(val, f"<REDACTED_{var}>")
25+
return text
26+
1327

1428
def _scratch_dir() -> str | None:
1529
"""Local scratch dir for staging `docker cp` transfers. Defaults to the system temp dir.
@@ -30,12 +44,15 @@ class ClashDockerEnvironment(DockerEnvironment):
3044
def execute(self, action: str | dict, cwd: str = "", *, timeout: int | None = None) -> dict:
3145
if isinstance(action, str):
3246
action = {"command": action}
33-
return super().execute(action, cwd, timeout=timeout)
47+
result = super().execute(action, cwd, timeout=timeout)
48+
if isinstance(result, dict) and result.get("output"):
49+
result["output"] = redact_secrets(result["output"])
50+
return result
3451

3552

3653
def assert_zero_exit_code(result: dict, *, logger: logging.Logger | None = None) -> dict:
3754
if result.get("returncode", 0) != 0:
38-
msg = f"Command failed with exit code {result.get('returncode')}:\n{result.get('output')}"
55+
msg = f"Command failed with exit code {result.get('returncode')}:\n{redact_secrets(result.get('output'))}"
3956
if logger is not None:
4057
logger.error(msg)
4158
raise RuntimeError(msg)

0 commit comments

Comments
 (0)