Rename the CLI binary from `kez-cli` to `kez` (via a [[bin]] section in the package's Cargo.toml; package name and `-p kez-cli` invocations stay the same so the workspace build, tests, and the cross-test harness are unaffected). Then update the READMEs to recommend `cargo install --path` once at the top of Quick Start, after which every example is the much shorter `kez ...` form. Mention `cargo run -p kez-cli --` as the dev iteration alternative for anyone who doesn't want to install. - rust/README.md: 11 `cargo run -p kez-cli --` → `kez` substitutions, plus a stale "81 tests" → "99 tests" fix. - README.md (root): Quick start gains a `cargo install` line. - rust-sig-server/README.md: Quick start uses `kez-sig-server` (post-install) with `cargo run` as the dev alternative; "Try it" section rewritten to use the actual `kez sigchain` CLI (which now exists) instead of the stale "hand-build via kez-core" workaround.
136 lines
5.1 KiB
Markdown
136 lines
5.1 KiB
Markdown
# 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.
|
||
|
||
## 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.
|
||
- [**`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).
|
||
|
||
### 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).
|
||
|
||
### 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 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 [`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.
|