4.1 KiB
zkac-node CLI
Install the zkac wheel from the repo root first (maturin develop or pip install .), then:
pip install -e ./cli
zkac-node --help
Quick start
# 1. Create identities (one directory per user under ~/.zkac/<userid>/)
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 <SERVER_PK_HEX>
zkac-node server pin bob localhost:9800 --key <SERVER_PK_HEX>
# 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 <REGISTRY_ID> --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:<REGISTRY_ID>:analyst
# or with explicit index:
zkac-node collect bob localhost:9800:<REGISTRY_ID>:analyst --pool-index <POOL_INDEX>
# 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/ |
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 <pk> |
Admin grant (encrypted to recipient pk) |
credentials list <id> [--server S …] |
Pending grants: tags + SimplePIR (handle row) + get_grant_blob + decrypt |
collect <id> <spec> [--pool-index N] |
Same retrieval path, then claim |
auth <id> --registry R --role X [--server S] |
Authenticated session |
Protocol & threat model
See 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 / pir_query, get_grant_blob (after decoding the PIR handle), and claim_grant. Match the CLI’s two-phase mailbox fetch unless you embed ciphertext in the PIR row yourself.
Operational scaling: The server grant pool is append-only (claimed rows are tombstones), 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/<userid>/:
identity.json issuance keypair
admin/<registry_id>.json BBS+ admin material for owned registries
credentials/<rid>_<role>.json received credentials
servers/<host_port>.json pinned server public keys
pir_cache/<server>.json PIR hint metadata (pool_version, n_records)
pir_cache/<server>.bin PIR hint data (cached, keyed by pool_version)
server/ (only if you run `serve <userid>`) server_key.json, registries/, mailbox/grants_pool.json