Something went wrong. Try again.
atproto Thingiverse but good
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279#!/usr/bin/env python3"""Check that runtime OAuth secrets never cross the frontend build boundary."""from __future__ import annotations
import argparseimport osimport reimport shutilimport subprocessimport sysimport tempfilefrom pathlib import Pathfrom typing import Callable, Iterable
SECRET_NAMES = ( "POLYMODEL_OAUTH_KEYSET_B64", "POLYMODEL_COOKIE_KEY_B64",)SENTINELS = ( "gc-unit-a-oauth-keyset-sentinel", "gc-unit-a-cookie-key-sentinel",)APP_OUTPUT = Path("target/dx/polymodel/debug/web/public")WORKER_FILES = (Path("public/renderer_worker.js"), Path("public/renderer_worker_bg.wasm"))
def fail(message: str) -> None: raise ValueError(message)
def read_text(path: Path) -> str: try: return path.read_text(encoding="utf-8") except UnicodeDecodeError: return path.read_bytes().decode("utf-8", errors="ignore")
def assert_absent(paths: Iterable[Path], needles: Iterable[str]) -> None: paths = list(paths) needles = tuple(needles) for path in paths: data = path.read_bytes() for needle in needles: if needle.encode() in data: fail(f"forbidden frontend secret material in {path}")
def blanket_frontend_environment_export_patterns(source: str) -> list[str]: patterns = ( r'File::create\s*\(\s*["\'](?:\./)?src/env\.rs', r'(?:strip_prefix|starts_with)\s*\(\s*["\']POLYMODEL_', r'env\s*::\s*vars\s*\(', r'env\s*::\s*vars_os\s*\(', r'cargo\s*:\s*rustc-env\s*=', ) return [pattern for pattern in patterns if re.search(pattern, source)]
def generated_frontend_env_surface_is_absent(root: Path) -> None: if (root / "src/env.rs").exists(): fail("src/env.rs exists; frontend environment generation was not removed") build = read_text(root / "build.rs") matches = blanket_frontend_environment_export_patterns(build) if matches: fail("build.rs still contains a blanket frontend environment export")
def oauth_secret_names_are_not_frontend_config(root: Path) -> None: build = read_text(root / "build.rs") main = read_text(root / "src/main.rs") if "mod env" in main or "POLYMODEL_*" in build: fail("frontend configuration module or wildcard export remains") if blanket_frontend_environment_export_patterns(build): fail("build.rs still contains a blanket frontend environment export") if any(name in build for name in SECRET_NAMES): fail("OAuth secret name appears in build.rs")
def oauth_runtime_secret_reads_remain_server_only(root: Path) -> None: oauth = read_text(root / "src/oauth/mod.rs") required = ( "Option<Keyset>", "ClientData::new(keyset, metadata)", "env_get(\"POLYMODEL_OAUTH_KEYSET_B64\")", "env_get(\"POLYMODEL_COOKIE_KEY_B64\")", "struct EnvSource", ) missing = [needle for needle in required if needle not in oauth] if missing: fail("OAuth runtime secret/public-mode seam is missing: " + ", ".join(missing))
def scan_frontend_artifacts(root: Path) -> None: output = root / APP_OUTPUT all_artifacts = sorted( path for path in output.rglob("*") if path.is_file() and path.suffix in {".js", ".wasm"} ) if output.is_dir() else [] worker_names = {path.name for path in WORKER_FILES} app_artifacts = [path for path in all_artifacts if path.name not in worker_names] worker_paths = [root / path for path in WORKER_FILES] if not app_artifacts: fail(f"no real app .js/.wasm artifacts found under {output}") if not any(path.suffix == ".js" for path in app_artifacts) or not any( path.suffix == ".wasm" for path in app_artifacts ): fail("real app artifact set must include both .js and .wasm files") missing_workers = [str(path) for path in worker_paths if not path.is_file()] if missing_workers: fail("missing renderer worker artifacts: " + ", ".join(missing_workers)) assert_absent([*all_artifacts, *worker_paths], (*SECRET_NAMES, *SENTINELS))
def copy_isolated_projects(root: Path, directory: Path) -> Path: """Copy the app and its ../jacquard sibling into the expected workspace layout.""" projects = directory / "Projects" projects.mkdir() checkout = projects / root.name jacquard = root.parent / "jacquard" if not jacquard.is_dir(): fail(f"required sibling dependency is missing: {jacquard}") ignore = shutil.ignore_patterns("target", ".jj", ".git", "src/env.rs") shutil.copytree(root, checkout, ignore=ignore) dependency_checkout = projects / "jacquard" shutil.copytree(jacquard, dependency_checkout, ignore=ignore) if not dependency_checkout.is_dir(): fail(f"isolated sibling dependency was not copied: {dependency_checkout}") return checkout
def run_clean_frontend_build(root: Path) -> None: with tempfile.TemporaryDirectory(prefix="polymodel-public-env-") as directory: checkout = copy_isolated_projects(root, Path(directory)) stale = checkout / "src/env.rs" if stale.exists(): stale.unlink() env = os.environ.copy() env.update({SECRET_NAMES[0]: SENTINELS[0], SECRET_NAMES[1]: SENTINELS[1]}) env["CARGO_TERM_COLOR"] = "never" result = subprocess.run( ["just", "build-web"], cwd=checkout, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, check=False, ) if result.returncode: print("isolated frontend build failed", file=sys.stderr) print("build output suppressed to avoid leaking secret sentinels", file=sys.stderr) raise RuntimeError(f"just build-web exited with {result.returncode}") generated_frontend_env_surface_is_absent(checkout) scan_frontend_artifacts(checkout)
def self_test() -> None: with tempfile.TemporaryDirectory(prefix="polymodel-public-env-self-test-") as directory: root = Path(directory) (root / "src").mkdir() (root / "src/main.rs").write_text("fn main() {}\n", encoding="utf-8") (root / "src/oauth").mkdir() (root / "src/oauth/mod.rs").write_text( "fn provision() -> Option<Keyset> { ClientData::new(keyset, metadata); " "env_get(\"POLYMODEL_OAUTH_KEYSET_B64\"); " "env_get(\"POLYMODEL_COOKIE_KEY_B64\"); struct EnvSource; }\n", encoding="utf-8", ) build = root / "build.rs" build.write_text( "fn main() { let _ = std::env::var(\"OUT_DIR\"); }\n", encoding="utf-8" ) generated_frontend_env_surface_is_absent(root) oauth_secret_names_are_not_frontend_config(root) oauth_runtime_secret_reads_remain_server_only(root)
def expect_failure(label: str, callback: Callable[[], None]) -> None: try: callback() except ValueError: return fail(f"negative {label} fixture unexpectedly passed")
(root / "src/env.rs").write_text("stale\n", encoding="utf-8") expect_failure("stale-env", lambda: generated_frontend_env_surface_is_absent(root)) (root / "src/env.rs").unlink()
for label, source in ( ("legacy-wildcard", 'File::create("./src/env.rs")'), ("prefix-wildcard", 'let _ = key.strip_prefix("POLYMODEL_");'), ("environment-iteration", "for (key, value) in std::env::vars() { use_it(key, value); }"), ("os-environment-iteration", "for (key, value) in std::env::vars_os() { use_it(key, value); }"), ("cargo-rustc-env", 'println!("cargo:rustc-env=POLYMODEL_FOO={value}");'), ): build.write_text(source, encoding="utf-8") expect_failure(label, lambda: generated_frontend_env_surface_is_absent(root)) build.write_text( "fn main() { let _ = std::env::var(\"OUT_DIR\"); }\n", encoding="utf-8" ) generated_frontend_env_surface_is_absent(root)
output = root / APP_OUTPUT workers = [root / path for path in WORKER_FILES]
def write_fixture( app_files: dict[str, bytes], worker_files: dict[str, bytes] | None = None ) -> None: shutil.rmtree(output, ignore_errors=True) shutil.rmtree(root / "public", ignore_errors=True) output.mkdir(parents=True) for relative, data in app_files.items(): path = output / relative path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes(data) for path in workers: path.parent.mkdir(parents=True, exist_ok=True) path.write_bytes((worker_files or {}).get(path.name, b"clean worker"))
complete_app = { "polymodel.js": b"clean app javascript", "polymodel_bg.wasm": b"clean app wasm", "nested/chunk.js": b"clean nested javascript", "nested/chunk.wasm": b"clean nested wasm", } write_fixture(complete_app) scan_frontend_artifacts(root)
write_fixture({"renderer_worker.js": b"worker-only", "renderer_worker_bg.wasm": b"worker-only"}) expect_failure("worker-only artifact", lambda: scan_frontend_artifacts(root)) write_fixture({}) expect_failure("empty artifact", lambda: scan_frontend_artifacts(root)) write_fixture({"polymodel.js": b"incomplete"}) expect_failure("incomplete artifact", lambda: scan_frontend_artifacts(root)) write_fixture(complete_app, {"renderer_worker.js": b"missing worker"}) (root / "public/renderer_worker_bg.wasm").unlink() expect_failure("missing worker", lambda: scan_frontend_artifacts(root))
for needle in (*SECRET_NAMES, *SENTINELS): write_fixture({"polymodel.js": needle.encode(), "polymodel_bg.wasm": b"clean"}) expect_failure("secret-bearing app artifact", lambda: scan_frontend_artifacts(root)) write_fixture(complete_app, {"renderer_worker.js": SENTINELS[0].encode()}) expect_failure("secret-bearing worker artifact", lambda: scan_frontend_artifacts(root)) print("check-public-env self-test passed")
def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--self-test", action="store_true") parser.add_argument("--skip-build", action="store_true", help="run source checks without building") parser.add_argument("checks", nargs="*", help="named checks to run") args = parser.parse_args() checks = { "generated_frontend_env_surface_is_absent": generated_frontend_env_surface_is_absent, "oauth_secret_names_are_not_frontend_config": oauth_secret_names_are_not_frontend_config, "oauth_runtime_secret_reads_remain_server_only": oauth_runtime_secret_reads_remain_server_only, } try: if args.self_test: self_test() return 0 selected = args.checks or list(checks) unknown = [name for name in selected if name not in checks] if unknown: fail("unknown check(s): " + ", ".join(unknown)) root = Path.cwd() for name in selected: checks[name](root) print(f"PASS {name}") if not args.skip_build: run_clean_frontend_build(root) print("PASS isolated_clean_frontend_build") except (OSError, RuntimeError, ValueError) as exc: print(f"check-public-env failed: {exc}", file=sys.stderr) return 1 return 0
if __name__ == "__main__": raise SystemExit(main())