# 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 ``` ## Quick start ```bash # 1. Create identities (one directory per user under ~/.zkac//) zkac-node user create alice zkac-node user create bob # Bob shares his issuance public key with Alice out-of-band: # zkac-node user show bob → copy issuance pk # 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 zkac-node server pin bob localhost:9800 --key # 3. Alice creates a registry and grants Bob a role (needs Bob's issuance pk hex) zkac-node registry create alice localhost:9800 --roles analyst,operator zkac-node grant alice --server localhost:9800 \ --registry --role analyst --to $BOB_PK_HEX # (prints pool_index for Bob's collect) # 4. Bob lists local creds + pending grants (single-server PIR, no second replica needed) zkac-node credentials list bob zkac-node credentials list bob --server localhost:9800 # 5. Bob collects (auto-discovers via detection tags; --pool-index is optional) zkac-node collect bob localhost:9800::analyst # or with explicit index: zkac-node collect bob localhost:9800::analyst --pool-index # 6. Bob authenticates zkac-node auth bob --registry --role analyst --server localhost:9800 ``` ## Commands | Command | Description | |---------|-------------| | `user create ` | Generate issuance keypair under `~/.zkac//` | | `user list` | List all local user ids | | `user show ` | Show issuance pk + owned registries + credentials | | `serve [--data-dir D]` | Run server; default data dir is `~/.zkac//server/` | | `server pin --key ` | Pin server public key for that user | | `registry create --roles …` | Create registry on server | | `registry update --registry R --add-roles …` | Add roles | | `registry get --registry R` | Fetch registry state | | `registry list ` | List registries this user owns locally | | `grant --server S --registry R --role X --to ` | Admin grant (encrypted to recipient pk) | | `credentials list [--server S …]` | Pending grants: tags + SimplePIR (full encrypted row) + decrypt | | `collect [--pool-index N]` | Same retrieval path, then local credential finalize | | `auth --registry R --role X [--server S]` | Authenticated session | ## Protocol & threat model See [docs/SECURITY.md](../docs/SECURITY.md) in the repo root for the full model, including PIR and detection tags. **Custom clients:** Encrypted management JSON supports `pool_tags`, `pir_hints`, and `pir_query`. Mailbox retrieval is single-hop: decode a full encrypted row from PIR and decrypt locally. **Operational scaling:** The server grant pool is append-only, so pool length grows with every grant. Large pools increase discovery traffic, PIR query size, and server work per retrieval (all linear in pool length). Treat unbounded growth as a potential DoS and capacity risk; mitigations are listed under *Known limitations* and *Future work* in `docs/SECURITY.md`. Transport, BBS+ auth, registry state updates, and issuance queues have separate scaling profiles (CPU dominated by BBS+, state size linear in role count, queue memory); see **Scaling and complexity (transport, credentials, registries)** in the same doc. ## Storage layout Per user `~/.zkac//`: ``` identity.json issuance keypair admin/.json BBS+ admin material for owned registries credentials/_.json received credentials servers/.json pinned server public keys pir_cache/.json PIR hint metadata (pool_version, n_records) pir_cache/.bin PIR hint data (cached, keyed by pool_version) server/ (only if you run `serve `) server_key.json, registries/, mailbox/grants_pool.json ```