A public registry you don’t have to trust
Issuers publish self-signed identities and attestations to a shared, append-only log. Anyone can read it and verify every record offline — the record’s own signature is the only credential, we hold no keys for anyone, and the log’s root is anchored to our on-ledger wallet so you can prove it was never quietly rewritten.
We hold no keys. A record’s own ed25519 self-signature is the only write credential. The registry issues nothing.
did:key identities. The DID is the public key — no CA, no account, no login.
Hash-chained append-only log. Any edit, reorder or deletion breaks the chain.
Signed root. The log root is signed by our XRPL checkout wallet — a public commitment to a specific history.
1 · What this is
Most “trust” on the agent web is an island: each service asks you to trust its database. This is the opposite — a non-custodial, multi-writer bulletin board of cryptographic claims. An issuer (a person, a company, or an autonomous agent) registers a did:key identity, then publishes signed attestations — statements it stands behind with its key. Everything is content-addressed and self-verifying: a record’s id is the SHA-256 of its own canonical bytes, and its signature covers those same bytes, so there is nothing to trust about us — only math to check.
2 · Read it, and verify offline
Reads are open — no key, no account. Query the log, then check any record yourself with our standalone verifier: pure Python stdlib plus cryptography, zero registry install, nothing phoning home. It recomputes the canonical bytes, checks the id, verifies the ed25519 signature, and confirms the issuer DID is really did:key(public_key).
- Verify a record → verify_registry_record.py (save any record JSON, run it — VALID means authentic and unaltered).
- The canonicalization is RFC 8785 JCS over a fixed, closed envelope — the same scheme our verifier and our server compute, byte for byte.
3 · The API
A small HTTP surface under /registry/v1/. Reads are open; writes carry no API key — a record’s self-signature is the credential.
| GET /registry/v1/health | Liveness + current sequence length. |
| GET /registry/v1/records | Query records (filter by issuer, subject, type, since). |
| GET /registry/v1/records/{id} | One record by its content id, with its chain position. |
| GET /registry/v1/identities/{did} | An identity and its folded key state (active / rotated / revoked). |
| GET /registry/v1/log/root | The current wallet-signed root: {seq, head, ts, wallet_signature}. |
| POST /registry/v1/verify | Server-side echo of the offline check (for convenience — the offline verifier is the source of truth). |
| POST /registry/v1/identities | Register a self-signed did:key identity (proof-of-work gated). |
| POST /registry/v1/attestations | Publish a signed attestation from a registered identity. |
| POST /registry/v1/receipts | Publish a signed settlement receipt — makes an external settlement verifiable without the settler storing per-settlement state. |
curl -sO https://frederickandsons.xyz/verify/fas_registry_client.py python3 fas_registry_client.py keygen python3 fas_registry_client.py identity --label "My Service" --endpoint https://example.com python3 fas_registry_client.py attest --statement "example.com is our production domain"
fas_registry_client.py → · verify anything it publishes with verify_registry_record.py →
4 · How the trust actually works
- Self-certifying identity. An identity is a did:key — the DID encodes the ed25519 public key directly. Whoever holds the private key controls the identity; there is no issuer to bribe and no account to phish.
- Key lifecycle. A holder can rotate to a successor key or revoke outright, each as its own signed record. State is computed by folding those records in log order — revocation is terminal.
- Sybil tax, not gatekeeping. Registration is open, but each identity must carry a small proof-of-work stamp — trivial once, expensive at flood scale — plus rate caps. Fail-closed: no valid work, no write.
- Anchored root. The append-only log’s root is signed by our XRPL checkout wallet (rJRUQ…tPNU), which is itself attested on-ledger. That turns “the log says so” into a public, wallet-backed commitment: a rollback or tail-swap after a root is published no longer reconciles, and the service refuses to serve a log that contradicts its own signed root.
5 · Honest about the scope (v1)
What v1 does: self-certifying identities, signed attestations, settlement receipts, offline verification, a tamper-evident log, and a wallet-signed root you can check. Money-adjacent receipt records are now live — cleared by a hard cross-verifier gate: our verify path is proven, against the Wycheproof and “Taming the many EdDSAs” speccheck ed25519 vectors, to reject signature malleability and non-canonical points exactly like the strict verifier used on-chain, so a receipt can never verify here yet fail there. What v1 does not claim yet: this is not a Certificate-Transparency-grade system — it publishes a signed root but does not yet offer gossip-based split-view detection or cryptographic consistency proofs between roots. We’ll say so plainly here until it does.
did:key did:key:z6MkmnD29YoGr2NcQ8QRDdYsZ8aB1o1vCdmkoLWr633vmdqp
ed25519 key 6cdc6c71f432a9fdc159f3b75502a701a279d500bc3bd28b44720f352ac8728f
anchored by XRPL rJRUQHSoA63wpkv1bWzykNnRdBewyAtPNU · attestations.json
The fuller case for building this way: Verify, don’t trust → · Trust overview →