feat(security): enforce ADR 0005 hosting boundary segregation strictly to family/

This commit is contained in:
Moritz Graf
2026-10-11 21:24:06 +02:00
parent 694d0c5072
commit bcb04711c0
3 changed files with 179 additions and 42 deletions
+22 -31
View File
@@ -808,17 +808,17 @@ def publish_to_s3(html_content: str, data_dir: Optional[Path] = None) -> str:
s3 = get_s3_client()
assets_dir = SCRIPT_DIR.parent / "assets"
# HTML files (both in family/mila.html and mila.html)
for key in ["family/mila.html", "mila.html"]:
s3.put_object(
Bucket=DEFAULT_BUCKET,
Key=key,
Body=html_content.encode("utf-8"),
ContentType="text/html; charset=utf-8",
CacheControl="no-cache, no-store, must-revalidate",
)
# HTML files (strictly under protected family/ path)
key = "family/mila.html"
s3.put_object(
Bucket=DEFAULT_BUCKET,
Key=key,
Body=html_content.encode("utf-8"),
ContentType="text/html; charset=utf-8",
CacheControl="no-cache, no-store, must-revalidate",
)
# Static PWA Assets to upload
# Static PWA Assets to upload (strictly under family/)
static_assets = [
("mila.webmanifest", "application/manifest+json; charset=utf-8", "no-cache, no-store, must-revalidate"),
("sw.js", "application/javascript; charset=utf-8", "no-cache, no-store, must-revalidate"),
@@ -831,24 +831,23 @@ def publish_to_s3(html_content: str, data_dir: Optional[Path] = None) -> str:
for fname, ctype, cache_ctrl in static_assets:
candidates = [assets_dir / fname]
if data_dir:
candidates.extend([data_dir.parent / "public" / "family" / fname, data_dir.parent / "public" / fname])
candidates.append(data_dir.parent / "public" / "family" / fname)
body_bytes = None
for candidate in candidates:
if candidate.is_file():
body_bytes = candidate.read_bytes()
break
if body_bytes:
for prefix in ["family/", ""]:
try:
s3.put_object(
Bucket=DEFAULT_BUCKET,
Key=f"{prefix}{fname}",
Body=body_bytes,
ContentType=ctype,
CacheControl=cache_ctrl,
)
except Exception as ex:
print(f"Warning: could not upload {prefix}{fname}: {ex}", file=sys.stderr)
try:
s3.put_object(
Bucket=DEFAULT_BUCKET,
Key=f"family/{fname}",
Body=body_bytes,
ContentType=ctype,
CacheControl=cache_ctrl,
)
except Exception as ex:
print(f"Warning: could not upload family/{fname}: {ex}", file=sys.stderr)
url = f"{DEFAULT_BASE_URL}/family/mila.html"
return url
@@ -867,21 +866,13 @@ def main():
print("Building Mila Dashboard from DuckDB...")
html = generate_dashboard_html(engine)
# 1. Save locally to knowledge-wiki/public/family/mila.html AND public/mila.html
# 1. Save locally strictly to knowledge-wiki/public/family/mila.html
wiki_public_family = data_dir.parent / "public" / "family"
wiki_public_family.mkdir(parents=True, exist_ok=True)
out_file = Path(args.output_file) if args.output_file else (wiki_public_family / "mila.html")
out_file.write_text(html, encoding="utf-8")
print(f"✅ Saved locally: {out_file}")
# Mirror to public/mila.html
root_mila = data_dir.parent / "public" / "mila.html"
try:
root_mila.write_text(html, encoding="utf-8")
print(f"✅ Synced locally: {root_mila}")
except Exception as e:
print(f"Warning: could not sync to {root_mila}: {e}", file=sys.stderr)
# 2. Upload to S3 hosting
if not args.skip_upload:
try: