# 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) ├── python/ ← Python 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) ``` Three parallel implementations. **Wire-compatible**: a claim signed in Rust verifies in Node and Python and vice versa, in every direction. 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. ## Documentation Start here: - [**`SPEC.md`**](SPEC.md) — the language-agnostic protocol spec (v0.2). Normative for every implementation. - [**`rust/README.md`**](rust/README.md) — Rust implementation guide: crate layout (`kez-core` / `kez-channels` / `kez-cli`), full CLI reference, channel plugin model, library examples, and the gap list. - [**`nodejs/README.md`**](nodejs/README.md) — Node/TypeScript port: same shape as Rust, npm workspaces layout, crypto stack rationale, CLI reference. - [**`python/README.md`**](python/README.md) — Python port: single `kez` package, virtualenv setup, crypto stack rationale (pure-Python BIP-340 Schnorr + `cryptography` for Ed25519), CLI reference. - [**`rust-sig-server/README.md`**](rust-sig-server/README.md) — the optional storage server: API reference, no-auth design + threat model, deployment recipes (bare-metal, Docker, PaaS), and how channel-based publishing remains the fallback if the server is down. ## Quick start ### Rust ```sh cd rust cargo build cargo test # 99 tests cargo install --path crates/kez-cli # → `kez` on PATH kez verify id github:jason ``` Full guide: [`rust/README.md`](rust/README.md) (reference) · [`rust/TUTORIAL.md`](rust/TUTORIAL.md) (step-by-step, recommended for newcomers). ### Node.js ```sh cd nodejs npm install npm test # 91 tests npm run cli -- verify id github:jason ``` Full guide: [`nodejs/README.md`](nodejs/README.md) (reference) · [`nodejs/TUTORIAL.md`](nodejs/TUTORIAL.md) (step-by-step). ### Python ```sh cd python python3 -m venv .venv .venv/bin/pip install -r requirements.txt .venv/bin/python kez_cli.py identity new ``` Full guide: [`python/README.md`](python/README.md) (reference) · [`python/TUTORIAL.md`](python/TUTORIAL.md) (step-by-step). ### Sigchain storage server (optional) ```sh cd rust-sig-server cargo build --release ./target/release/kez-sig-server # listens on :7878 ``` Full guide: [`rust-sig-server/README.md`](rust-sig-server/README.md). ## Cross-testing ```sh ./crosstest.sh ``` Runs 55 scenarios that swap implementations at the artifact boundary: | # | Scenarios | |---|---| | 1–14 | Rust ↔ Node: JSON / compact / markdown / DNS claims, nostr + ed25519 | | 15–20 | Rust ↔ Node sigchains: build in one, parse + show in the other; JSONL byte parity | | 21–44 | **Python ↔ Rust and Python ↔ Node** claims: every format × key type, both directions | | — | Python ↔ both peers DNS zone form, both directions | | — | Python ↔ both peers sigchains: build/show both ways, JSONL byte parity, ed25519 | If all 55 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 all three 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 [`rust/README.md`](rust/README.md#whats-not-done-yet) and the spec: - **`verify id` consulting the sigchain.** Sigchain types, CLI commands (`kez sigchain add/revoke/show/export/publish`), and the storage server all exist. But proof verification doesn't yet fetch the chain to check for revocations — every `verify` is still a single one-shot proof check. - `rotate` and `add_device` sigchain ops. - `expires_at` enforcement during claim verify. - Typed `VerificationStatus.status` reflecting the five failure modes (`valid` / `revoked` / `expired` / `unreachable` / `fork`). - Auth-required publishers (GitHub gist, Bluesky, ActivityPub). ## License Dual-licensed under MIT or Apache-2.0.