Enforce private-by-default rail exposure

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
This commit is contained in:
codex 2026-08-22 12:34:25 +02:00
parent c6b045051f
commit 004f1c4dc1
7 changed files with 368 additions and 7 deletions

View file

@ -8,6 +8,7 @@ import json
import shutil
import subprocess
import sys
import tempfile
import time
import tomllib
import urllib.parse
@ -17,6 +18,9 @@ from datetime import UTC, datetime
from pathlib import Path
from typing import Any
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from exposure import ExposureError, validate_rendered_exposure # noqa: E402
SUPPORTED_SCHEMA = "railiance.app.v1"
@ -231,6 +235,8 @@ def deploy(argv: list[str]) -> int:
parser.add_argument("--apply", action="store_const", const="apply", dest="mode")
parser.add_argument("--server-dry-run", action="store_const", const="server-dry-run", dest="mode")
parser.add_argument("--approval-id", help="Operator approval/progress id required before apply when declared.")
parser.add_argument("--rapp-declaration", type=Path)
parser.add_argument("--reef-declaration", type=Path)
parser.add_argument("--stage1-result", help="Optional Stage 1 result JSON for same-candidate evidence.")
parser.add_argument("--timeout-minutes", type=int, default=10)
parser.add_argument("--json-out")
@ -242,6 +248,32 @@ def deploy(argv: list[str]) -> int:
context = stage2_context(app_dir, contract_path, data)
checks = local_prechecks(app_dir, data, args.mode, args.approval_id)
if args.mode in {"server-dry-run", "apply"} and shutil.which("helm"):
with tempfile.TemporaryDirectory(prefix="railiance-exposure-"):
render_args = [
"helm", "template", context["release"], context["chart"],
"--namespace", context["namespace"], "-f", context["values"],
]
rendered = subprocess.run(
render_args, cwd=app_dir, text=True, capture_output=True,
timeout=args.timeout_minutes * 60, check=False,
)
if rendered.returncode != 0:
checks.append(precheck("exposure-render", "failed", True, "helm template failed"))
else:
try:
exposure = validate_rendered_exposure(
rendered.stdout,
rapp_declaration=args.rapp_declaration,
reef_declaration=args.reef_declaration,
)
checks.append(precheck(
"adr-0008-exposure", "passed", True,
f"posture={exposure['posture']} hosts={len(exposure['public_hosts'])}",
))
except ExposureError as exc:
checks.append(precheck("adr-0008-exposure", "failed", True, str(exc)))
if args.stage1_result:
try:
stage1 = json.loads(Path(args.stage1_result).read_text(encoding="utf-8"))