# KEZ KEZ is a portable, decentralized identity graph. It lets a person say: > "These accounts, keys, domains, and identities are all me." …without depending on any central authority. Every connection is proven by a cryptographic signature against a key the user already controls (a nostr key, an Ed25519 key, etc.), and the proofs are published in places only the claimed account itself can publish to (their gist, their DNS, their nostr relay event). Anyone can verify the graph without trusting a server. ## Repository layout ``` . ├── SPEC.md ← The protocol. Language-agnostic, normative. ├── rust/ ← Rust implementation (kez-core, kez-channels, kez-cli) ├── nodejs/ ← TypeScript/Node implementation (same shape, same CLI) ├── rust-sig-server/ ← Optional HTTP store for sigchains (axum + SQLite) ├── crosstest.sh ← Interop test: artifacts move between implementations └── README.md ← (this file) ``` Two parallel implementations. **Wire-compatible**: a claim signed in Rust verifies in Node and vice versa. The cross-test harness proves it. A separate [`rust-sig-server/`](rust-sig-server/) crate provides an optional HTTP storage tier for sigchains — useful when a user doesn't want to set up DNS/hosting/nostr, but **never required**; the protocol stays decentralized. ## Quick start ### Rust ```sh cd rust cargo build cargo test # 81 tests cargo run -p kez-cli -- verify id github:jason ``` Full guide: [`rust/README.md`](rust/README.md). ### Node.js ```sh cd nodejs npm install npm test # 72 tests npm run cli -- verify id github:jason ``` Full guide: [`nodejs/README.md`](nodejs/README.md). ## Cross-testing ```sh ./crosstest.sh ``` Runs 19 scenarios that swap implementations at the artifact boundary: | # | Scenario | |---|---| | 1–2 | nostr-signed JSON claim, both directions | | 3–4 | nostr-signed compact claim, both directions | | 5–6 | nostr-signed markdown claim, both directions | | 7–8 | nostr-signed DNS zone form, both directions | | 9–10 | ed25519-signed JSON claim, both directions | | 11–12 | ed25519-signed compact claim, both directions | | 13–14 | ed25519-signed markdown claim, both directions | | 15 | rust builds 3-event nostr sigchain → node parses + shows | | 16 | rust-exported sigchain JSONL == node-exported JSONL (byte-identical) | | 17 | node builds 3-event nostr sigchain → rust parses + shows | | 18 | rust builds ed25519 sigchain → node parses + shows | | 19 | node builds ed25519 sigchain → rust parses + shows | If all 19 pass: JCS canonicalization, both signature suites (BIP-340 Schnorr and Ed25519), the compact `kez:z1:` zstd+base64url encoding, the Markdown fence, the DNS TXT shape, and the sigchain JSONL bundle format are all byte-compatible across implementations. Pass `-v` for verbose output (echoes intermediate commands and proofs). ## What ships in v0.2 - **Five channel plugins** in each implementation: `dns:`, `github:`, `nostr:`, `bluesky:`, `ap:` (alias `mastodon:`). - **Four wire encodings**: JSON, compact, Markdown fence, DNS TXT. - **Two primary-key algorithms**: nostr/secp256k1 Schnorr (BIP-340) and Ed25519 (RFC 8032). - **JCS (RFC 8785)** canonicalization for everything signed. - **No API keys required for any channel.** ## What's not done yet Tracked in both [`rust/README.md`](rust/README.md#whats-not-done-yet) and the spec: - Sigchain walker (types exist; no append/walk/revoke flow yet). - `expires_at` enforcement during verify. - Typed `VerificationStatus.status` reflecting the five failure modes. ## License Dual-licensed under MIT or Apache-2.0.