railiance-infra/scripts/validate-reef-exposure.py
codex 61c6082ea8
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Gate reef web ports on exposure grants
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
2026-08-22 12:34:25 +02:00

66 lines
2.5 KiB
Python
Executable file

#!/usr/bin/env python3
"""Validate requested public web ports against an ADR-0008 reef declaration."""
from __future__ import annotations
import argparse
import json
import sys
from pathlib import Path
from typing import Any
import yaml
class GrantError(ValueError):
pass
def validate(payload: Any, ports: list[int]) -> dict[str, Any]:
if not isinstance(payload, dict):
raise GrantError("reef declaration must be a YAML object")
if any(port == 6443 for port in ports):
raise GrantError("6443 is operator-only and cannot be publicly granted")
if any(port not in {80, 443} for port in ports):
raise GrantError("the public web gate accepts only ports 80 and 443")
if not payload.get("primary_rail") and not payload.get("hosted_rails"):
raise GrantError("provider-delegated reefs cannot publish a public listener")
exposure = payload.get("exposure") or {}
if exposure.get("posture") != "public":
raise GrantError("reef exposure.posture must be public")
grants = exposure.get("grants") or []
for port in ports:
matches = [grant for grant in grants if isinstance(grant, dict) and grant.get("port") in {port, str(port)}]
if not matches:
raise GrantError(f"reef has no substrate grant for port {port}")
grant = matches[0]
missing = [field for field in ("reason", "approved_on", "residual_risk_owner") if not grant.get(field)]
if missing:
raise GrantError(f"port {port} grant is missing {', '.join(missing)}")
return {
"reef_id": payload.get("reef_id"),
"posture": "public",
"validated_ports": sorted(set(ports)),
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--reef-declaration", type=Path, required=True)
parser.add_argument("--ports", required=True, help="Comma-separated ports; only 80 and 443 are grantable")
args = parser.parse_args()
try:
ports = [int(value) for value in args.ports.split(",") if value]
if not ports:
raise GrantError("at least one requested port is required")
payload = yaml.safe_load(args.reef_declaration.read_text(encoding="utf-8"))
result = validate(payload, ports)
except (OSError, yaml.YAMLError, ValueError) as exc:
print(f"reef exposure validation failed: {exc}", file=sys.stderr)
return 1
print(json.dumps(result, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())