122 lines
6.1 KiB
Markdown
122 lines
6.1 KiB
Markdown
# zkac-node CLI
|
||
|
||
Command-line interface for [ZKAC](../README.md) using the **Python bindings only** (`zkac` package). It runs a **registry-capable server** (management + client-managed registries + optional issuance relay) and **per-user** material under `~/.zkac/` (or `$ZKAC_HOME`).
|
||
|
||
## Prerequisites
|
||
|
||
- Python ≥ 3.9
|
||
- The **`zkac`** extension built and installed from the repository root, for example:
|
||
|
||
```bash
|
||
cd /path/to/ZKAC
|
||
maturin develop
|
||
# or: pip install -e .
|
||
```
|
||
|
||
## Installation
|
||
|
||
```bash
|
||
cd /path/to/ZKAC/cli
|
||
pip install -e .
|
||
```
|
||
|
||
This installs the **`zkac-node`** console script.
|
||
|
||
## Environment
|
||
|
||
| Variable | Meaning |
|
||
|------------|---------|
|
||
| `ZKAC_HOME` | Base directory for users (default: `~/.zkac`). Each user lives at `$ZKAC_HOME/<userid>/`. |
|
||
|
||
## Server vs client
|
||
|
||
- **Server** (`zkac-node serve`): a node that can **accept registry create/update** from an operator with the **`zkac.mgmt`** credential. It also serves **managed** sessions (BBS+ auth against stored client-managed registries) and optionally a **relay** port for blind issuance queues.
|
||
- **Client**: a **userid** with files under `$ZKAC_HOME/<userid>/` (transport key, registries, credentials).
|
||
|
||
## Ports (defaults)
|
||
|
||
| Port role | Default | Purpose |
|
||
|------------|---------|---------|
|
||
| Management | 7400 | ZKAC + static role `zkac.mgmt`; JSON commands (create/update registry, issuance peek/grant). |
|
||
| Managed | 7401 | ZKAC + `RegistryManager`; member proves a role in a client-managed registry. |
|
||
| Relay | 7402 | Optional **plaintext** JSON line protocol for enqueue/poll of issuance requests. Use `--relay-port 0` on `serve` to disable. Binds with `--relay-bind` (default `127.0.0.1`). |
|
||
|
||
## Layout on disk
|
||
|
||
**Per user** (`$ZKAC_HOME/<userid>/`):
|
||
|
||
- `transport.json` — Ristretto **client** transport keypair (`zkac.Keypair`).
|
||
- `profile.json` — `userid` and metadata.
|
||
- `registries/<slug>/` — one directory per logical registry:
|
||
- `admin.json` / `registry.json` — produced by `registry-init` (admin issuer material + public state + state cert).
|
||
- `roles/<name>.json` — member credential payloads for `connect`.
|
||
- `issued/` — files from `issue-member` (handoff).
|
||
- `pending/<request_id>.json` — saved by `issuance-request` until `issuance-poll` finalizes.
|
||
- `servers/<label>/server.json` — from `pin-server` (pinned server pubkey + host/ports).
|
||
|
||
**Server data** (`serve --data <dir>`):
|
||
|
||
- `transport.json` — server transport keypair.
|
||
- `mgmt_issuer.json` — BBS issuer secret for the static `zkac.mgmt` role only.
|
||
- `mgmt_member.json` — member credential for `zkac.mgmt` (give to operators who push registries).
|
||
- `registry_events.json` — append-only log to rebuild `RegistryManager` after restart (registry state; **not** the issuance queue).
|
||
|
||
## Commands
|
||
|
||
Run `zkac-node --help` and `zkac-node <command> --help` for full flags.
|
||
|
||
| Command | Description |
|
||
|---------|-------------|
|
||
| `serve` | Start server; `--init` creates keys and mgmt credential in `--data`. |
|
||
| `user-create` | Create a new userid directory with a client transport key. |
|
||
| `pin-server` | Save server pubkey + host/ports for a user (from server’s `transport.json`). |
|
||
| `registry-init` | Offline: build a client-managed registry (`RegistryState` + state cert) under the user’s `registries/<slug>/`. |
|
||
| `registry-push` | Push create (or `--update`) to the server over the **management** port using `mgmt_member.json` from the server data dir. |
|
||
| `registry-import-public` | Copy `registry.json` from another user (public metadata for peers). |
|
||
| `connect` | Open a **managed** ZKAC session and send a JSON command (`--command`, default `whoami`). |
|
||
| `issue-member` | Admin: blind-issue a role credential to a file under `issued/` (out-of-band handoff). |
|
||
| `import-credential` | Install a member JSON into `roles/<name>.json`. |
|
||
| `issuance-request` | Enqueue a blind commitment on the **relay** (see caveats below). |
|
||
| `issuance-grant` | Admin: list pending via mgmt peek, `issue_blind`, `grant_credential`. |
|
||
| `issuance-poll` | Poll relay for blind signature; finalize credential into `roles/<role>.json` when ready. |
|
||
|
||
## Typical flows
|
||
|
||
**Operator: first-time server**
|
||
|
||
```bash
|
||
export ZKAC_HOME=~/.zkac # optional
|
||
zkac-node serve --data ./myserver --init --mgmt-port 7400 --managed-port 7401 --relay-port 7402
|
||
```
|
||
|
||
Distribute **`myserver/transport.json`** (public key) and **`myserver/mgmt_member.json`** (sensitive) to admins who push registries.
|
||
|
||
**Admin: create registry offline and push**
|
||
|
||
```bash
|
||
zkac-node user-create alice
|
||
zkac-node registry-init --user alice --slug demo --roles analyst reader
|
||
zkac-node registry-push --user alice --slug demo --server-data ./myserver --host 127.0.0.1 --mgmt-port 7400
|
||
```
|
||
|
||
**Member: pin server, import public registry + credential, connect**
|
||
|
||
```bash
|
||
zkac-node pin-server --user bob --name prod --transport-file ./myserver/transport.json \
|
||
--host 10.0.0.1 --mgmt-port 7400 --managed-port 7401 --relay-port 7402
|
||
zkac-node registry-import-public --from-user alice --to-user bob --slug demo
|
||
# copy or issue credential file into bob/registries/demo/roles/analyst.json
|
||
zkac-node connect --user bob --slug demo --credential roles/analyst.json \
|
||
--server-file ~/.zkac/bob/servers/prod/server.json --host 10.0.0.1 --managed-port 7401
|
||
```
|
||
|
||
## Caveats
|
||
|
||
1. **Issuance relay queue is in-memory.** Pending grants are lost if `serve` restarts before `issuance-grant` / `issuance-poll` complete. Registry snapshots are persisted via `registry_events.json`; the relay queue is not.
|
||
2. **Relay is a localhost-oriented, plaintext JSON line protocol** (not the full E2E design in the Rust layer). Use `--relay-bind 127.0.0.1` and do not expose the relay port untrusted networks without additional protection.
|
||
3. **`zkac.mgmt`** is a **separate** BBS role from the client-managed registry admin; it only authorizes **management RPCs** to the server (push registry, peek/grant issuance). Registry state integrity still comes from BBS+ state certificates inside `RegistryManager`.
|
||
|
||
## Development
|
||
|
||
The CLI package name is **`zkac-node-cli`** (see `pyproject.toml`). It declares no PyPI dependency on `zkac`; install the `zkac` wheel from the parent project first.
|