From a5c32c51845d7c7fc23609291f56d1eeab05bad4 Mon Sep 17 00:00:00 2001 From: zzstoatzz Date: Fri, 7 Aug 2026 23:38:50 -0500 Subject: [PATCH] document the attested-payments broker write-delegation gap survey of the spaces interop landscape (zds, atpint, pds.js, garazyk, rsky, stratos, happyview), why space commits cannot carry financial evidence, how attested.network/badge.blue move non-repudiation to the attestation layer, and the three candidate models for the broker write-delegation primitive nobody has designed yet. Co-Authored-By: Claude Fable 5 --- README.md | 1 + .../attested-payments-and-write-delegation.md | 156 ++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 docs/attested-payments-and-write-delegation.md diff --git a/README.md b/README.md index 7aedb6e..1b82478 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ decision rules. - [invite codes](docs/invite-codes.md) - [passkeys](docs/passkeys.md) - [permissioned data](docs/permissioned-data.md) +- [attested payments and write delegation](docs/attested-payments-and-write-delegation.md) - [references](docs/references.md) - [benchmarks](bench/README.md) - [benchmark comparison notes](docs/benchmarking.md) diff --git a/docs/attested-payments-and-write-delegation.md b/docs/attested-payments-and-write-delegation.md new file mode 100644 index 0000000..32c20ef --- /dev/null +++ b/docs/attested-payments-and-write-delegation.md @@ -0,0 +1,156 @@ +# attested payments and the broker write-delegation gap + +Notes from a 2026-08-07 survey of the permissioned-data ("spaces") interop +landscape, the attested.network payment proposal, and what a payment broker +would need from ZDS that no PDS implementation currently provides. This is a +design note, not a plan of record. Nothing here is implemented and nothing +should be implemented unilaterally — see "recommendation" at the end. + +## context + +Interop testing with Bulleted (Nick Gerakines' atpint stack) surfaced two ZDS +OAuth bugs (space scopes rejected at PAR; `read_self` unable to authorize +null-collection repo-state reads), both fixed. The larger question that testing +raised: is the spaces surface a sound foundation for future financial +transaction records and an expanded rights/copyright model? Answering it +required surveying every known implementation. + +## the implementation landscape + +PDS-hosted spaces (proposal 0016 shape — multi-writer space as a set of +single-writer per-member repos, LtHash set commitment, deniable commits): + +- **ZDS** (this repo) +- **atpint** (Nick Gerakines; sandbox network, closed source; also the origin + of `com.atproto.space.getRepoState` and `community.lexicon.service.describe`, + neither of which any other implementation has) +- **pds.js** (Chad Miller, — + `packages/spaces/`; scope grammar and policy model closely match ZDS) +- **garazyk** (Jack Valinsky, — + spec-native, good interop docs, monotonic writer-head rollback protection) +- **rsky** (blacksky; PDS endpoints plus a standalone `rsky-space-host` crate) + +Standalone non-PDS space hosts (the "arbiter" pattern — the term itself is +Zicklag's, from the Roomy/Muni Town "Arbiter" group-management design): + +- **Stratos** (Evelyn Osman, — + keeps private records off the PDS entirely; clients reuse the PDS OAuth + DPoP session cross-origin; the only implementation with non-deniable ECDSA + commits, but no commit chain (`prev: null`) and the weakest history + retention) +- **HappyView** (Trezy, + — AppView that is + itself the space host; commit "signature" is pure HMAC; best-in-class + credential revocation: member removal actively revokes outstanding + credentials, checked per request) + +Properties that matter for financial-grade records, across all of the above: + +- **Deniable commits are the norm and the intent.** Signatures cover + `(space, author, rev, ikm)` context, never content. A space commit is + useless as third-party evidence of what was written. This is a privacy + feature of proposal 0016, not a bug. +- **No implementation has a two-party acknowledgment or counter-signature + pattern.** None. +- **The host holds the signing key everywhere**, so a host can forge or + silently drop records absent an external observer. +- **The oplog is contractually droppable** (ZDS docs say so explicitly; + Stratos returns `OplogTruncated`; garazyk prunes to last-N). It is a sync + shortcut, not an audit log. +- **Credential revocation leaks** ~2h everywhere except HappyView. + +Conclusion from the survey: spaces provide confidentiality, not evidence. +Financial truth cannot rest on space commits in any current implementation. + +## attested.network resolves the evidence problem at a different layer + +attested.network (, draft spec, discussion at the +atprotocol community forum) is a proof-of-payment spec built on badge.blue +attestations. Three-party model: + +- payment record (`network.attested.payment.oneTime|recurring|scheduled`) in + the **payer's** repo, carrying a `signatures` array of strongRefs +- `network.attested.payment.proof` records in the **recipient's** and + **broker's** repos, attesting via CID +- entitlements linked by strongRef to any lexicon; trust models (strict / + creator-trusted / federated) are app policy + +badge.blue () mechanics: strip `signatures`, inject `$sig` +metadata containing the **repository DID**, DAG-CBOR canonicalize, SHA-256, +CIDv1; ECDSA (P-256/K-256, low-S normalized) over the CID bytes. Repository +binding makes cross-repo replay fail verification structurally. Remote proofs +are unsigned — their authority is residence in the attestor's authenticated +repo. Key discovery is deliberately open (any DID verification method, not +pinned to `#atproto`). Reference implementation: +`atproto-attestation` in +(v0.15.0-rc.2 at time of writing; known gaps: no P-384; remote-proof +verification does not check the strongRef's own `cid` field against the +fetched proof). + +Consequence: **integrity and non-repudiation ride on the attestation layer, +not on space commits.** Private payments per the spec use identical +attestation mechanics with the payment record living in a permissioned space. +Spaces do the one thing they are good at (confidentiality); badge.blue does +the evidence. The deniable-commit objection dissolves. + +## the actual gap: broker write delegation + +The spec requires the broker to: + +1. write payment records into the **payer's** repository ("via inter-service + auth" — undesigned in the spec) +2. for private payments, **create and manage a permissioned space** in the + payer's repository and grant read access to recipient and broker +3. for recurring/scheduled payments, keep writing proofs and records + **monthly, indefinitely** + +What exists today, nowhere sufficient: + +- **ZDS**: `com.atproto.server.getServiceAuth` mints user-signed lxm-scoped + JWTs capped at 1 hour (60s method-less). The only write endpoint accepting + inbound service auth is `uploadBlob`. All space and simplespace writes are + bearer/DPoP-only with `repo == authenticated user`. +- **Nick's workspace** (atproto-crates): space service auth is 60s + `notifyWrite`-style with jti replay tracking; the 0016 + delegation-token → space-credential flow is read delegation; the word + "broker" appears nowhere. +- **All five surveyed implementations** enforce self-repo-only space writes. +- **Tranquil** (Lewis, ) has + the closest prior art, for accounts rather than spaces: durable + "controller" delegation grants with scope intersection, an audit log, + TOTP-gated consent, and revocation + (`crates/tranquil-pds/src/delegation/`). + +## three candidate models + +1. **Ephemeral user-minted service tokens** (extend the existing primitive). + Payer's client mints an lxm+collection-scoped service JWT at + payment-initiate time; the PDS accepts service auth on `createRecord` and + space writes, narrowly scoped. Cheap, no new consent surface, single-use + jti for replay safety. Covers one-time payments only: recurring dies at + the 1h cap and minting requires the payer online. +2. **Durable PDS-side delegation grants** (Tranquil-controller-shaped). A + stored, revocable grant: grantee DID, method set, collection set, optional + space, expiry, audit log. The broker authenticates as itself; the PDS + checks the grant. The only model that honestly covers recurring payments + and broker-managed spaces. Cost: genuinely new protocol surface needing a + lexicon and cross-implementation agreement. +3. **Write-capable space credentials** (stay inside the 0016 idiom). Extend + the credential exchange so credentials carry collection-scoped write + actions. Elegant for the private-payment case but inherits model 1's + liveness problem (delegation tokens are 60s and user-minted) unless + refresh semantics are added — at which point it converges on model 2. + +## recommendation + +Model 2 is where this converges, and it must not be invented unilaterally: it +is a consent/trust primitive that only matters if brokers and multiple PDS +implementations agree. The attested.network spec hand-waves exactly this step, +meaning the gap is undesigned upstream. Next action when this is picked up: +write the gap analysis (the three models, the Tranquil precedent, the +recurring-payment forcing function) into the attested.network forum thread and +to Nick directly, before any ZDS code. + +Related reading order for whoever picks this up: this file, then +[permissioned-data.md](permissioned-data.md), then +[permissioned-data-proposal-94.md](permissioned-data-proposal-94.md). -- 2.51.2