From 47dfb61a7f1ada50e8f565652035eaf943c7a4e4 Mon Sep 17 00:00:00 2001 From: mrwulf Date: Mon, 6 Jul 2026 19:14:52 +0200 Subject: [PATCH] Move the log service to ltl.zkdefi.org (root path); keep path-mount support - serve/webdocs/cli default to base_path='' (own subdomain, root serving) - webdocs link builder handles the empty base like web.py already did - all docs, paper, notebook 06b, and published-mirror README point at https://ltl.zkdefi.org; DEPLOY.md rewritten for subdomain + redirect - tests: root mount is the production shape; one test keeps exercising the path-mounted variant Co-Authored-By: Claude Fable 5 --- DEPLOY.md | 50 ++++++++++++------ README.md | 6 +-- notebooks/06b_agent_verify_inclusion.ipynb | 2 +- paper/ltl.pdf | Bin 413959 -> 413903 bytes paper/ltl.tex | 4 +- provider/src/pacta_provider/cli.py | 6 ++- .../src/pacta_provider/published_assets.py | 2 +- provider/src/pacta_provider/web.py | 4 +- provider/src/pacta_provider/webdocs.py | 2 +- scripts/build_curriculum_notebooks.py | 2 +- src/pacta/cli.py | 2 +- tests/test_web_and_witness.py | 6 ++- 12 files changed, 54 insertions(+), 32 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index e51e99d..f79a186 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,4 +1,4 @@ -# Deploying the online log at zkdefi.org/lean-transparency-log +# Deploying the online log at ltl.zkdefi.org STATUS: DEPLOYED (2026-07-06) and serving. This file is now the as-built record plus the update runbook. Deliberately generic about the host: it @@ -101,7 +101,7 @@ After=network.target User=pacta WorkingDirectory=/srv/pacta/app Environment=PYTHONPATH=/srv/pacta/app/src:/srv/pacta/app/provider/src -ExecStart=/usr/bin/python3 -m pacta_provider serve --log-dir /srv/pacta/log --base-path lean-transparency-log --host 127.0.0.1 --port 8461 +ExecStart=/usr/bin/python3 -m pacta_provider serve --log-dir /srv/pacta/log --host 127.0.0.1 --port 8461 Restart=on-failure # hardening: read-only service, no key material anywhere near it ProtectSystem=strict @@ -115,16 +115,21 @@ WantedBy=multi-user.target ```bash sudo systemctl daemon-reload && sudo systemctl enable --now pacta-log -curl -s http://127.0.0.1:8461/lean-transparency-log/healthz +curl -s http://127.0.0.1:8461/healthz ``` -## 3. Reverse proxy on zkdefi.org +The service serves from the root path by default (it lives on its own +subdomain); pass `--base-path ` only if you must mount it under +a path instead. -Caddy (inside the existing `zkdefi.org` site block): +## 3. Reverse proxy: ltl.zkdefi.org + +DNS: an `A` record for `ltl` pointing at the same host (or a `CNAME` to +the apex). Caddy then gets its own site block and handles the +certificate automatically: ```caddy -redir /lean-transparency-log /lean-transparency-log/docs -route /lean-transparency-log/* { +ltl.zkdefi.org { reverse_proxy 127.0.0.1:8461 { transport http { response_header_timeout 15s @@ -133,21 +138,34 @@ route /lean-transparency-log/* { } ``` +If the log was ever served under a path (the original deployment used +`zkdefi.org/lean-transparency-log`), keep a permanent redirect in the +old site block so published links stay alive: + +```caddy +redir /lean-transparency-log https://ltl.zkdefi.org/ permanent +handle_path /lean-transparency-log/* { + redir https://ltl.zkdefi.org{uri} permanent +} +``` + nginx equivalent, with basic rate limiting (the backend is a stdlib threading server - let the proxy absorb abuse): ```nginx limit_req_zone $binary_remote_addr zone=pactalog:1m rate=20r/s; -location /lean-transparency-log/ { - limit_req zone=pactalog burst=40 nodelay; - proxy_read_timeout 15s; - proxy_pass http://127.0.0.1:8461/lean-transparency-log/; - proxy_set_header Host $host; +server { + server_name ltl.zkdefi.org; + location / { + limit_req zone=pactalog burst=40 nodelay; + proxy_read_timeout 15s; + proxy_pass http://127.0.0.1:8461/; + proxy_set_header Host $host; + } } -location = /lean-transparency-log { return 301 /lean-transparency-log/docs; } ``` -Check: `https://zkdefi.org/lean-transparency-log/docs` renders the customer +Check: `https://ltl.zkdefi.org/docs` renders the customer documentation; `/v1/sth` returns the dogfood-signed head. ## 4. Second mirror (any Forgejo/Gitea/GitLab you operate) @@ -182,12 +200,12 @@ sudo systemctl restart pacta-log ## 6. Smoke tests from anywhere ```bash -pacta log-fetch --url https://zkdefi.org/lean-transparency-log --component dalek-ed25519-verified --out-dir /tmp/e +pacta log-fetch --url https://ltl.zkdefi.org --component dalek-ed25519-verified --out-dir /tmp/e pacta receipt-verify --attestation /tmp/e/dalek-ed25519-verified.attestation.json \ --receipt /tmp/e/dalek-ed25519-verified.receipt.json \ --log-public-key \ --sth-store ~/.pacta-pins.json -pacta sth-refresh --url https://zkdefi.org/lean-transparency-log \ +pacta sth-refresh --url https://ltl.zkdefi.org \ --sth-store ~/.pacta-pins.json --log-public-key git clone https://github.com/saymrwulf/lean-transparency-log && cd lean-transparency-log && python3 verify.py --all ``` diff --git a/README.md b/README.md index 92b36dc..a66bc4a 100644 --- a/README.md +++ b/README.md @@ -238,7 +238,7 @@ The log has three synchronized faces, transport being orthogonal to trust: every leaf, every signed tree head (the WITNESS CHANNEL - all cloners see the same heads), per-component receipts, the provider public key, and a standalone stdlib-only `verify.py`. Anyone: `python3 verify.py --all`. -3. **HTTP service** (deployed at `zkdefi.org/lean-transparency-log`, see +3. **HTTP service** (deployed at `ltl.zkdefi.org`, see `DEPLOY.md`): read-only CT-style endpoints + customer docs. The web process never touches private keys - heads are signed offline; a compromised server can withhold or replay (pinning + freshness detect @@ -247,8 +247,8 @@ The log has three synchronized faces, transport being orthogonal to trust: ```bash PYTHONPATH=src:provider/src python -m pacta_provider serve --log-dir ... --base-path lean-transparency-log PYTHONPATH=src:provider/src python -m pacta_provider log-publish --log-dir ... --git-dir --public-key -pacta log-fetch --url https://zkdefi.org/lean-transparency-log --component dalek-ed25519-verified --out-dir fetched -pacta sth-refresh --url https://zkdefi.org/lean-transparency-log --sth-store pins.json --log-public-key +pacta log-fetch --url https://ltl.zkdefi.org --component dalek-ed25519-verified --out-dir fetched +pacta sth-refresh --url https://ltl.zkdefi.org --sth-store pins.json --log-public-key pacta witness-audit --published-dir --log-public-key ``` diff --git a/notebooks/06b_agent_verify_inclusion.ipynb b/notebooks/06b_agent_verify_inclusion.ipynb index be4cf70..c4825e9 100644 --- a/notebooks/06b_agent_verify_inclusion.ipynb +++ b/notebooks/06b_agent_verify_inclusion.ipynb @@ -220,7 +220,7 @@ "(`pacta witness-audit` recomputes every prefix root from the\n", "published leaves; run `python3 verify.py --all` in a clone for the\n", "no-install version). The ONLINE SERVICE\n", - "(`zkdefi.org/lean-transparency-log`) adds live endpoints: fetch\n", + "(`ltl.zkdefi.org`) adds live endpoints: fetch\n", "fresh evidence (`pacta log-fetch`), advance your pin with an\n", "online consistency proof (`pacta sth-refresh`). The verification\n", "you do afterwards is IDENTICAL in all three transports - this\n", diff --git a/paper/ltl.pdf b/paper/ltl.pdf index 29dfa8fc721c69d505a0ad17b78f551faf0b09b4..42c12a150377cbe4a4fce3630b4878b2334a5d86 100644 GIT binary patch delta 24761 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 delta 24829 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 argparse.ArgumentParser: serve = sub.add_parser("serve", help="Serve the log read-only over HTTP (CT-style endpoints + customer docs). Never touches private keys.") serve.add_argument("--log-dir", required=True) - serve.add_argument("--base-path", default="lean-transparency-log") + serve.add_argument("--base-path", default="") serve.add_argument("--host", default="127.0.0.1") serve.add_argument("--port", type=int, default=8461) serve.set_defaults(func=cmd_serve) @@ -166,7 +166,9 @@ def cmd_serve(args) -> int: from .web import serve as make_server server = make_server(args.log_dir, base_path=args.base_path, host=args.host, port=args.port) - print(f"serving read-only log on http://{args.host}:{args.port}/{args.base_path.strip('/')}/docs") + base = args.base_path.strip("/") + prefix = f"/{base}" if base else "" + print(f"serving read-only log on http://{args.host}:{args.port}{prefix}/docs") try: server.serve_forever() except KeyboardInterrupt: diff --git a/provider/src/pacta_provider/published_assets.py b/provider/src/pacta_provider/published_assets.py index 8f16aab..0a1ddab 100644 --- a/provider/src/pacta_provider/published_assets.py +++ b/provider/src/pacta_provider/published_assets.py @@ -184,7 +184,7 @@ python3 verify.py --receipt receipts/dalek-ed25519-verified.receipt.json ``` The online service (same data, live endpoints + customer documentation): -**https://zkdefi.org/lean-transparency-log** +**https://ltl.zkdefi.org** The provider tooling, agent tooling, and course materials: **https://github.com/saymrwulf/proof-aware-crypto-tooling-agent** diff --git a/provider/src/pacta_provider/web.py b/provider/src/pacta_provider/web.py index 5f5516a..5765707 100644 --- a/provider/src/pacta_provider/web.py +++ b/provider/src/pacta_provider/web.py @@ -1,6 +1,6 @@ """The online face of the transparency log: a READ-ONLY, zero-dependency HTTP service exposing CT-style endpoints under a base path (deployed at -zkdefi.org/lean-transparency-log behind a reverse proxy). +ltl.zkdefi.org behind a reverse proxy). Security posture: this process never loads a private key. Tree heads are signed OFFLINE by the provider CLI (log-append / log-sth); the service @@ -150,7 +150,7 @@ def make_handler(log: TransparencyLog, base_path: str, docs_html: str): def serve( log_dir: str, - base_path: str = "lean-transparency-log", + base_path: str = "", host: str = "127.0.0.1", port: int = 8461, docs_html: str | None = None, diff --git a/provider/src/pacta_provider/webdocs.py b/provider/src/pacta_provider/webdocs.py index 357e565..e1d772b 100644 --- a/provider/src/pacta_provider/webdocs.py +++ b/provider/src/pacta_provider/webdocs.py @@ -102,7 +102,7 @@ def _svg_tree(entries: list[LogEntry], root_hex: str, signing_backend: str) -> s def render_docs(log: TransparencyLog, base_path: str) -> str: - base = "/" + base_path.strip("/") + base = "/" + base_path.strip("/") if base_path.strip("/") else "" metadata = log.metadata() history = log.sth_history() latest: dict[str, Any] = history[-1] if history else {} diff --git a/scripts/build_curriculum_notebooks.py b/scripts/build_curriculum_notebooks.py index 39034b5..80e7bf1 100644 --- a/scripts/build_curriculum_notebooks.py +++ b/scripts/build_curriculum_notebooks.py @@ -1549,7 +1549,7 @@ COURSE = { (`pacta witness-audit` recomputes every prefix root from the published leaves; run `python3 verify.py --all` in a clone for the no-install version). The ONLINE SERVICE - (`zkdefi.org/lean-transparency-log`) adds live endpoints: fetch + (`ltl.zkdefi.org`) adds live endpoints: fetch fresh evidence (`pacta log-fetch`), advance your pin with an online consistency proof (`pacta sth-refresh`). The verification you do afterwards is IDENTICAL in all three transports - this diff --git a/src/pacta/cli.py b/src/pacta/cli.py index cc5d1a6..af4e320 100644 --- a/src/pacta/cli.py +++ b/src/pacta/cli.py @@ -143,7 +143,7 @@ def build_parser() -> argparse.ArgumentParser: receipt_verify.set_defaults(func=cmd_receipt_verify) log_fetch = sub.add_parser("log-fetch", help="Fetch attestation + inclusion proof for a component from an ONLINE log; verify locally afterwards.") - log_fetch.add_argument("--url", required=True, help="Base URL, e.g. https://zkdefi.org/lean-transparency-log") + log_fetch.add_argument("--url", required=True, help="Base URL, e.g. https://ltl.zkdefi.org") log_fetch.add_argument("--component", required=True) log_fetch.add_argument("--out-dir", default="fetched-evidence") log_fetch.set_defaults(func=cmd_log_fetch) diff --git a/tests/test_web_and_witness.py b/tests/test_web_and_witness.py index 9774519..b223cbe 100644 --- a/tests/test_web_and_witness.py +++ b/tests/test_web_and_witness.py @@ -30,11 +30,12 @@ def _make_log(tmp_path, n=3): def test_web_endpoints_and_online_proof_roundtrip(tmp_path): + # root mount: the production shape (ltl.zkdefi.org serves from /) _make_log(tmp_path) server = serve(str(tmp_path / "log"), port=0) port = server.server_address[1] threading.Thread(target=server.serve_forever, daemon=True).start() - base = f"http://127.0.0.1:{port}/lean-transparency-log" + base = f"http://127.0.0.1:{port}" try: def get(path): with urllib.request.urlopen(base + path, timeout=10) as r: @@ -60,8 +61,9 @@ def test_web_endpoints_and_online_proof_roundtrip(tmp_path): def test_logclient_fetch_and_refresh_pin(tmp_path): + # path mount still supported for anyone proxying under a prefix _make_log(tmp_path) - server = serve(str(tmp_path / "log"), port=0) + server = serve(str(tmp_path / "log"), base_path="lean-transparency-log", port=0) port = server.server_address[1] threading.Thread(target=server.serve_forever, daemon=True).start() base = f"http://127.0.0.1:{port}/lean-transparency-log"