136 lines
4.9 KiB
Markdown
136 lines
4.9 KiB
Markdown
# zkac-node CLI
|
|
|
|
Install the `zkac` wheel from the repo root first (`maturin develop` or `pip install .`), then:
|
|
|
|
```bash
|
|
pip install -e ./cli
|
|
zkac-node --help
|
|
zkac-node-i2p-server --help
|
|
```
|
|
|
|
## Quick start
|
|
|
|
```bash
|
|
# 1. Create identities (one directory per user under ~/.zkac/<userid>/)
|
|
zkac-node user create alice
|
|
zkac-node user create bob
|
|
|
|
# Bob shares one contact string with Alice out-of-band:
|
|
# zkac-node user show bob --peer 127.0.0.1:9810
|
|
|
|
# 2. Alice runs a server; pin its public key for clients
|
|
zkac-node serve alice --port 9800 &
|
|
zkac-node server pin alice localhost:9800 --key <SERVER_PK_HEX>
|
|
zkac-node server pin bob localhost:9800 --key <SERVER_PK_HEX>
|
|
|
|
# 3. Alice creates a registry and grants Bob a role directly (needs Bob's contact string)
|
|
zkac-node registry create alice localhost:9800 --roles analyst,operator
|
|
zkac-node grant alice --server localhost:9800 \
|
|
--registry <REGISTRY_ID> --role analyst --to "$BOB_CONTACT"
|
|
|
|
# 4. Bob listens for direct p2p delivery
|
|
zkac-node p2p-listen bob --host 127.0.0.1 --port 9810
|
|
|
|
# 5. Bob lists local creds
|
|
zkac-node credentials list bob
|
|
|
|
# 6. Bob authenticates
|
|
zkac-node auth bob --registry <REGISTRY_ID> --role analyst --server localhost:9800
|
|
```
|
|
|
|
## Commands
|
|
|
|
| Command | Description |
|
|
|---------|-------------|
|
|
| `user create <id>` | Generate issuance keypair under `~/.zkac/<id>/` |
|
|
| `user list` | List all local user ids |
|
|
| `user show <id>` | Show issuance pk + owned registries + credentials |
|
|
| `serve <id> [--data-dir D]` | Run server; default data dir is `~/.zkac/<id>/server/` (loopback-only unless `--allow-non-loopback`) |
|
|
| `zkac-node-i2p-server <id> [--host H --port P]` | Same as `serve`, for I2P server-tunnel exposure (see below) |
|
|
| `server pin <id> <host:port> --key <hex>` | Pin server public key for that user |
|
|
| `registry create <id> <server> --roles …` | Create registry on server |
|
|
| `registry update <id> <server> --registry R --add-roles …` | Add roles |
|
|
| `registry get <id> <server> --registry R` | Fetch registry state |
|
|
| `registry list <id>` | List registries this user owns locally |
|
|
| `grant <id> --server S --registry R --role X --to <blob>` | Admin direct p2p grant (recipient contact bundle must include peer endpoint) |
|
|
| `p2p-listen <id> [--host H --port P]` | Receive one direct p2p grant and store credential (loopback-only unless `--allow-non-loopback`) |
|
|
| `credentials list <id>` | List local credentials |
|
|
| `auth <id> --registry R --role X [--server S]` | Authenticated session |
|
|
|
|
## Protocol & threat model
|
|
|
|
See [docs/SECURITY.md](../docs/SECURITY.md) in the repo root for the direct p2p grant model.
|
|
|
|
## Admin debug web UI (demo)
|
|
|
|
For a **fully transparent** HTTP dashboard (registry rows, live TCP sessions, data-dir
|
|
listing), run **`demo/zkac_admin_serve.py`** from the repo with **`uv sync --extra demo`**.
|
|
See [demo/README.md](../demo/README.md).
|
|
|
|
## Running over I2P
|
|
|
|
### Inbound: `zkac-node-i2p-server`
|
|
|
|
Run the node on a loopback TCP port and forward it from an **I2P server tunnel**
|
|
(I2P or i2pd). Clients use your published **`*.b32.i2p:port`** as the server
|
|
string in all `zkac-node` commands.
|
|
|
|
```bash
|
|
zkac-node-i2p-server alice --host 127.0.0.1 --port 9800
|
|
```
|
|
|
|
They should **pin** that same `host:port` string (the `.b32.i2p` form), not `localhost`.
|
|
|
|
### Outbound clients
|
|
|
|
Outbound client connections can be proxied through an I2P SOCKS tunnel.
|
|
|
|
1. Start I2P/i2pd SOCKS proxy (commonly `127.0.0.1:4447`).
|
|
2. Export:
|
|
|
|
```bash
|
|
export ZKAC_SOCKS5_PROXY=127.0.0.1:4447
|
|
```
|
|
|
|
If the destination ends in `.i2p` and `ZKAC_SOCKS5_PROXY` is not set, `zkac-node` fails fast instead of attempting a direct clearnet connect.
|
|
|
|
3. Use `.b32.i2p:port` endpoints with normal commands:
|
|
|
|
```bash
|
|
zkac-node registry get alice exampledestination.b32.i2p:9800 --registry <REGISTRY_ID>
|
|
zkac-node auth bob --registry <REGISTRY_ID> --role analyst --server exampledestination.b32.i2p:9800
|
|
```
|
|
|
|
For inbound direct grants, run `p2p-listen` on a local port and expose it via an I2P inbound tunnel. Peers dial your published I2P destination/port; your tunnel forwards to local `host:port`.
|
|
|
|
`p2p-listen` now refuses non-loopback binds by default (use `--allow-non-loopback` only when intentional).
|
|
|
|
Connectivity sanity check:
|
|
|
|
```bash
|
|
zkac-node net check exampledestination.b32.i2p:9800
|
|
zkac-node net check exampledestination.b32.i2p:9800 --handshake --key <SERVER_PK_HEX>
|
|
# or use an existing pin:
|
|
zkac-node net check exampledestination.b32.i2p:9800 --handshake --userid alice
|
|
```
|
|
|
|
With proxy:
|
|
|
|
```bash
|
|
export ZKAC_SOCKS5_PROXY=127.0.0.1:4447
|
|
zkac-node net check exampledestination.b32.i2p:9800
|
|
```
|
|
|
|
## Storage layout
|
|
|
|
Per user `~/.zkac/<userid>/`:
|
|
|
|
```
|
|
identity.json issuance keypair
|
|
p2p transport keypair
|
|
admin/<registry_id>.json BBS+ admin material for owned registries
|
|
credentials/<rid>_<role>.json received credentials
|
|
servers/sha256_<...>.json pinned server public keys (includes original server string)
|
|
server/ (only if you run `serve <userid>`) server_key.json, registries/
|
|
```
|