Skip to content

Commit 0f8661b

Browse files
author
Horde
committed
Bound artifact scans to shareable evidence
Exclude reconstructed environments, caches, and source clones so security scans finish predictably without implying that runtime state is shareable.
1 parent dcc2ab2 commit 0f8661b

5 files changed

Lines changed: 45 additions & 10 deletions

File tree

tools/perf_bisection/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ Important outputs include:
160160
- `security_scan.json`: value-free credential finding locations; a `blocked`
161161
status prohibits sharing until reviewed and remediated.
162162

163+
The security scan excludes `env-cache/`, `jit-cache/`, `kit-cache/`, and
164+
`sources/` because they are large, non-shareable runtime state. Do not include
165+
those directories when packaging evidence for another person or system.
166+
163167
Setup and tooling incompatibilities are structured skips, not performance
164168
verdicts. See [the compatibility policy](docs/compatibility.md).
165169

tools/perf_bisection/SECURITY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ credential is rotated. Re-run the scan explicitly with:
5858
isaaclab-bisect-scan-artifacts <OUTPUT_DIR>
5959
```
6060

61+
The scan excludes `env-cache/`, `jit-cache/`, `kit-cache/`, and `sources/`.
62+
These directories are runtime state, not evidence, and must not be included in
63+
anything shared or uploaded.
64+
6165
## Shared resources and releases
6266

6367
The agent does not merge pull requests, push protected branches, publish

tools/perf_bisection/docs/development.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ uv run --no-project python tools/skills/cli.py check
3232
Unit and synthetic tests must not require Isaac Sim, a GPU, or Docker.
3333
Scan any generated run directory with
3434
`isaaclab-bisect-scan-artifacts <OUTPUT_DIR>` before sharing it.
35+
The scanner excludes reconstructed environments, caches, and source clones;
36+
never include those excluded directories in a shared evidence archive.
3537

3638
## Container
3739

tools/perf_bisection/src/isaaclab_bisection/artifact_security.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99

1010
import argparse
1111
import json
12+
import os
1213
import re
1314
from collections.abc import Iterator
1415
from pathlib import Path
1516
from typing import Any
1617

1718
_MAX_FILE_SIZE = 10 * 1024 * 1024
19+
_EXCLUDED_DIRECTORY_NAMES = frozenset({"env-cache", "jit-cache", "kit-cache", "sources"})
1820
_PATTERNS = (
1921
("private_key", re.compile(r"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----")),
2022
("authorization_bearer", re.compile(r"(?i)\bauthorization\s*:\s*bearer\s+\S+")),
@@ -53,20 +55,28 @@ def scan_artifacts(root: Path) -> dict[str, Any]:
5355
"status": "blocked" if findings else "passed",
5456
"finding_count": len(findings),
5557
"findings": findings,
56-
"note": "Potential secret values are intentionally omitted. Review findings before sharing artifacts.",
58+
"excluded_directory_names": sorted(_EXCLUDED_DIRECTORY_NAMES),
59+
"note": (
60+
"Potential secret values are intentionally omitted. Review findings before sharing artifacts. "
61+
"Reconstructed environments, caches, and source clones are excluded and must not be shared."
62+
),
5763
}
5864

5965

6066
def _iter_text_files(root: Path) -> Iterator[Path]:
61-
"""Yield bounded regular files while excluding this scanner's own report."""
62-
for path in root.rglob("*"):
63-
if path.name == "security_scan.json" or not path.is_file():
64-
continue
65-
try:
66-
if path.stat().st_size <= _MAX_FILE_SIZE:
67-
yield path
68-
except OSError:
69-
continue
67+
"""Yield bounded evidence files without traversing non-shareable run caches."""
68+
for directory, names, filenames in os.walk(root):
69+
names[:] = [name for name in names if name not in _EXCLUDED_DIRECTORY_NAMES]
70+
directory_path = Path(directory)
71+
for filename in filenames:
72+
if filename == "security_scan.json":
73+
continue
74+
path = directory_path / filename
75+
try:
76+
if path.is_file() and path.stat().st_size <= _MAX_FILE_SIZE:
77+
yield path
78+
except OSError:
79+
continue
7080

7181

7282
def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:

tools/perf_bisection/tests/test_artifact_security.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,18 @@ def test_scan_artifacts_cli_passes_clean_directory(tmp_path: Path) -> None:
3030
assert main([str(tmp_path)]) == 0
3131
report = json.loads((tmp_path / "security_scan.json").read_text(encoding="utf-8"))
3232
assert report["status"] == "passed"
33+
34+
35+
def test_scan_artifacts_excludes_non_shareable_run_caches(tmp_path: Path) -> None:
36+
secret = "sk-" + "abcdefghijklmnopqrstuvwxyz123456"
37+
for name in ("env-cache", "jit-cache", "kit-cache", "sources"):
38+
directory = tmp_path / name
39+
directory.mkdir()
40+
(directory / "credential.txt").write_text(secret, encoding="utf-8")
41+
(tmp_path / "report.md").write_text("Canonical evidence.\n", encoding="utf-8")
42+
43+
report = scan_artifacts(tmp_path)
44+
45+
assert report["status"] == "passed"
46+
assert report["finding_count"] == 0
47+
assert report["excluded_directory_names"] == ["env-cache", "jit-cache", "kit-cache", "sources"]

0 commit comments

Comments
 (0)