Skip to content

Commit cd11382

Browse files
Block local author identity in public-boundary scanner
Reject commit metadata whose author or committer email uses the internal durable-workflow.local development domain so public repos cannot publish commits tagged with the local build identity. Issue: zorporation/durable-workflow#517
1 parent 1dd4ec6 commit cd11382

2 files changed

Lines changed: 108 additions & 0 deletions

File tree

scripts/check-public-boundary.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ metadata_patterns=(
3131
"$(pattern_from_hex 4c6f6f702d49443a)"
3232
"$(pattern_from_hex 2e746d702f6c6f6f70732f)"
3333
"$(pattern_from_hex 6c6f6f702d72756e6e6572)"
34+
"$(pattern_from_hex 4064757261626c652d776f726b666c6f772e6c6f63616c)"
3435
)
3536

3637
pathspec=(
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
"""Contract tests for ``scripts/check-public-boundary.sh``.
2+
3+
The scanner is the public/private boundary prevention gate for this public
4+
repo. These tests pin the behavior so that future edits to the scanner do not
5+
silently drop a denied pattern.
6+
"""
7+
8+
from __future__ import annotations
9+
10+
import os
11+
import shutil
12+
import subprocess
13+
from pathlib import Path
14+
15+
import pytest
16+
17+
REPO_ROOT = Path(__file__).resolve().parent.parent
18+
SCANNER = REPO_ROOT / "scripts" / "check-public-boundary.sh"
19+
20+
_LOCAL_IDENTITY_EMAIL = "build@" + "durable-workflow" + ".local"
21+
22+
23+
def _git(cwd: Path, *args: str, env: dict[str, str] | None = None) -> subprocess.CompletedProcess[str]:
24+
merged_env = os.environ.copy()
25+
merged_env.setdefault("GIT_CONFIG_GLOBAL", "/dev/null")
26+
merged_env.setdefault("GIT_CONFIG_SYSTEM", "/dev/null")
27+
merged_env.setdefault("HOME", str(cwd))
28+
if env:
29+
merged_env.update(env)
30+
return subprocess.run(
31+
["git", *args],
32+
cwd=cwd,
33+
env=merged_env,
34+
check=True,
35+
capture_output=True,
36+
text=True,
37+
)
38+
39+
40+
def _init_repo(cwd: Path) -> None:
41+
_git(cwd, "init", "-q", "-b", "main")
42+
_git(cwd, "config", "user.name", "Durable Workflow Test")
43+
_git(cwd, "config", "user.email", "test@example.invalid")
44+
45+
46+
def _commit(cwd: Path, name: str, body: str, *, author_email: str = "test@example.invalid") -> str:
47+
(cwd / name).write_text(body, encoding="utf-8")
48+
_git(cwd, "add", name)
49+
_git(
50+
cwd,
51+
"commit",
52+
"-q",
53+
"-m",
54+
f"Add {name}",
55+
env={
56+
"GIT_AUTHOR_NAME": "Durable Workflow Test",
57+
"GIT_AUTHOR_EMAIL": author_email,
58+
"GIT_COMMITTER_NAME": "Durable Workflow Test",
59+
"GIT_COMMITTER_EMAIL": author_email,
60+
},
61+
)
62+
return _git(cwd, "rev-parse", "HEAD").stdout.strip()
63+
64+
65+
def _run_scanner(cwd: Path, rev_range: str) -> subprocess.CompletedProcess[str]:
66+
env = os.environ.copy()
67+
env["PUBLIC_BOUNDARY_GIT_RANGE"] = rev_range
68+
return subprocess.run(
69+
["bash", str(SCANNER)],
70+
cwd=cwd,
71+
env=env,
72+
capture_output=True,
73+
text=True,
74+
)
75+
76+
77+
@pytest.fixture
78+
def scratch_repo(tmp_path: Path) -> Path:
79+
# Copy the scanner into the scratch repo so the scanner's relative "." root is stable.
80+
repo_dir = tmp_path / "repo"
81+
repo_dir.mkdir()
82+
scripts_dir = repo_dir / "scripts"
83+
scripts_dir.mkdir()
84+
shutil.copy2(SCANNER, scripts_dir / SCANNER.name)
85+
_init_repo(repo_dir)
86+
_git(repo_dir, "add", "scripts/check-public-boundary.sh")
87+
_git(repo_dir, "commit", "-q", "-m", "Seed scanner")
88+
return repo_dir
89+
90+
91+
class TestPublicBoundaryScanner:
92+
def test_clean_commit_passes(self, scratch_repo: Path) -> None:
93+
_commit(scratch_repo, "hello.txt", "hello world\n")
94+
result = _run_scanner(scratch_repo, "-1 HEAD")
95+
assert result.returncode == 0, result.stderr
96+
97+
def test_local_identity_commit_is_rejected(self, scratch_repo: Path) -> None:
98+
sha = _commit(
99+
scratch_repo,
100+
"hello.txt",
101+
"hello world\n",
102+
author_email=_LOCAL_IDENTITY_EMAIL,
103+
)
104+
result = _run_scanner(scratch_repo, "-1 HEAD")
105+
assert result.returncode == 1, (result.stdout, result.stderr)
106+
assert "forbidden commit metadata" in result.stderr
107+
assert sha[:12] in result.stderr

0 commit comments

Comments
 (0)