clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

docs: clarify isolated-origin boundaries

Dami committed 75f5ba0
commit
75f5ba02495ce75a6322a568feff8393f04ba2fb
parent
7e83e210ae270e106740f9368a24616b8a5c3039
author
Dami <dami.etoile@gmail.com>
5 files changed, +42 -38
MARCHITECTURE.md24++++++++++++------------
MREADME.md6+++---
MSECURITY.md21+++++++++++----------
Mskills/nzip/SKILL.md10++++++----
Mworker/setup.md19++++++++++---------
M ARCHITECTURE.md +12 -12
@@ -10,10 +10,10 @@ sides canonicalize and hash manifests identically.
1010 flowchart TB1111 CLI["Deno CLI"] -- "bearer API at control host" --> W["Worker"]1212 SHORT(["GET control/2a3f"]) -- "308" --> SITE["https://2a3f.site-domain/"]13- V(["visitor"]) -- "GET site hostname" --> C{"Workers Cache"}14- C -- "hit" --> RESP["public response"]15- C -- "miss" --> W16- W -- "tagged response" --> RESP13+ V(["visitor"]) -- "GET site hostname" --> C{"browser cache"}14+ C -- "fresh" --> RESP["public response"]15+ C -- "miss or revalidate" --> W16+ W --> RESP1717 W --> R2[("R2 blobs")]1818 W --> D1[("D1 state")]1919 ```
@@ -50,12 +50,13 @@ bytes. The wildcard route accepts only exact four-character lowercase
5050 hexadecimal hostnames. Management and notification routes are not dispatched on5151 artifact hosts.5252 53-Each artifact hostname is a distinct browser origin. Origin-scoped storage,54-credentials, passkey defaults, and service-worker control therefore stay within55-one site. Artifact responses also disable `document.domain` relaxation. Until56-`SITE_DOMAIN` is registered in the Public Suffix List, WebAuthn still permits a57-site to deliberately choose that parent domain as its RP ID; applications that58-require isolation must explicitly use their exact hostname.53+Each artifact hostname is a distinct browser origin. Origin-scoped storage and54+service-worker control therefore stay within one site, and nzip's `__Host-`55+unlock cookie is host-only. Artifact responses also disable `document.domain`56+relaxation. Until `SITE_DOMAIN` is registered in the Public Suffix List, an57+artifact can still set a parent-domain cookie or deliberately choose that parent58+as its WebAuthn RP ID. Applications that require isolation must use host-only59+cookies and their exact hostname as the RP ID.5960 6061 Serving normally requires one D1 read for site state and two R2 reads for the6162 manifest and file. Public responses use `ETag` revalidation and a 60-second
@@ -176,8 +177,7 @@ account-wide and Cloudflare may change them.
176177 177178 | resource | bounding strategy | usage reference |178179 | ------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |179-| Workers | short request path; cache before execution | [Workers limits](https://developers.cloudflare.com/workers/platform/limits/) |180-| Workers Cache | public content only; short TTL; mutation purge | [Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/) |180+| Workers | short path; every browser miss executes the Worker | [Workers limits](https://developers.cloudflare.com/workers/platform/limits/) |181181 | Workers Logs | invocation logs off; deterministic identity sample | [Workers Logs pricing](https://developers.cloudflare.com/workers/observability/logs/workers-logs/#pricing) |182182 | D1 | deduplicated windows, write caps, and seven-day pruning | [D1 pricing](https://developers.cloudflare.com/d1/platform/pricing/) |183183 | R2 | content deduplication, history cap, and daily GC | [R2 pricing](https://developers.cloudflare.com/r2/pricing/) |
M README.md +3 -3
M SECURITY.md +11 -10
@@ -7,8 +7,8 @@ enrollment, and observable abuse controls.
77 88 Sites execute at `https://<address>.<site-domain>/`, giving every address a99 distinct browser origin. Origin-scoped localStorage, IndexedDB, OPFS,10-CacheStorage, service workers, cookies, and passkey defaults are isolated11-between sites. The control-plane shorthand10+CacheStorage, service workers, and passkey defaults are isolated between sites.11+nzip's unlock cookies are host-only. The control-plane shorthand1212 `https://<control-origin>/<address>` is redirect-only and never serves artifact1313 bytes.1414
@@ -18,14 +18,15 @@ cross-origin network requests where a target permits them, and can deceive its
1818 visitors. Artifact responses disable `document.domain` relaxation so sibling1919 site hostnames cannot opt back into a shared origin.2020 21-WebAuthn has an additional domain rule: a subdomain may deliberately choose its22-registrable parent as its RP ID. On `2a3f.n.zip`, the safe per-site default is23-`2a3f.n.zip`, and passkey applications should explicitly set24-`rp.id = location.hostname`. Until `n.zip` is accepted into the Public Suffix25-List, an arbitrary site can still request the parent RP ID `n.zip`; it cannot26-request a sibling RP ID such as `ffff.n.zip`. Do not use passkeys on the control27-origin or claim hostile-tenant passkey isolation until that Public Suffix List28-boundary ships in target browsers.21+Cookies and WebAuthn have additional domain rules. Until `n.zip` is accepted22+into the [Public Suffix List](https://publicsuffix.org/), an arbitrary site can23+set a `Domain=n.zip` cookie, and it can request the parent RP ID `n.zip`. It24+cannot request a sibling RP ID such as `ffff.n.zip`. Applications should use25+`__Host-` or otherwise host-only cookies and explicitly set26+`rp.id = location.hostname`; on `2a3f.n.zip`, the RP ID is `2a3f.n.zip`. Do not27+use passkeys or application-defined cookies on the control origin, or claim28+hostile-tenant credential isolation, until that Public Suffix List boundary29+ships in target browsers.2930 3031 ## Reporting a vulnerability3132
M skills/nzip/SKILL.md +6 -4
M worker/setup.md +10 -9
@@ -58,7 +58,8 @@ nzip uses two public surfaces:
5858 5959 The control path permanently redirects to the artifact hostname; it never serves6060 artifact bytes. This separation gives every hosted site its own browser storage,61-credentials, service workers, and default passkey relying-party ID.61+service workers, host-only nzip unlock cookie, and default passkey relying-party62+ID.6263 6364 New site builds should use `/` as their deployment base; the address is no6465 longer part of the asset path and no reservation/rebuild/repush cycle is needed.
@@ -125,11 +126,13 @@ verify the deployment, and only then consider a one-year duration plus preload.
125126 126127 For passkey applications, use the exact artifact hostname as the RP ID—normally127128 `location.hostname`. Subdomains can deliberately select their registrable128-parent as a WebAuthn RP ID, so per-site origins alone do not make the parent129-domain safe for control-plane passkeys. Before hosting mutually untrusted130-passkey applications, register `SITE_DOMAIN` in the Public Suffix List and wait131-for the change to reach the browsers in scope. Until then, do not use passkeys132-with the parent `SITE_DOMAIN` RP ID.129+parent as a WebAuthn RP ID or set cookies for that parent domain, so per-site130+origins alone do not isolate those two credential mechanisms. Applications131+should use `__Host-` or otherwise host-only cookies and exact-host RP IDs. Before132+hosting mutually untrusted applications, register `SITE_DOMAIN` in the133+[Public Suffix List](https://publicsuffix.org/submit/) and wait for the change to134+reach the browsers in scope. Until then, do not use the parent `SITE_DOMAIN` for135+application cookies or passkeys.133136 134137 ## Free security alert email135138
@@ -289,9 +292,7 @@ or other sensitive data in them.
289292 290293 ```sh291294 # from the repo root292-deno install -g -f -n nzip \293- --allow-net --allow-read --allow-write --allow-env \294- cli/main.ts295+deno install -g -A -f --config deno.json -n nzip cli/main.ts295296 296297 nzip auth --server https://share.demo.dev --token <token-from-step-5>297298 nzip vault add personal # slot 0x0