specs/003-key-trust-allowlist/contracts/cli-commands.md
Ref: Size: 3.7 KiB
# CLI Command Contracts: Key Trust Allowlist **Date**: 2026-03-21 | **Feature**: 003-key-trust-allowlist ## `collab key add` ### Synopsis ``` collab key add [OPTIONS] [PUBKEY] ``` ### Arguments | Argument | Required | Description | |----------|----------|-------------| | `PUBKEY` | No (required unless `--self`) | Base64-encoded Ed25519 public key | ### Options | Option | Description | |--------|-------------| | `--self` | Read public key from `~/.config/git-collab/signing-key.pub` | | `--label <LABEL>` | Human-readable label for the key | ### Behavior 1. If `--self` is set, read pubkey from `~/.config/git-collab/signing-key.pub`. If `PUBKEY` is also provided, error. 2. Validate the key: base64 decode, check 32 bytes, check valid Ed25519 point. 3. Load existing trusted keys file (create `.git/collab/` directory and file if needed). 4. Check for duplicate (key already in file). If duplicate, print message and exit 0. 5. Append key (with optional label) to file. 6. Print confirmation. ### Exit Codes | Code | Condition | |------|-----------| | 0 | Key added successfully, or key already trusted | | 1 | Invalid key, missing argument, or I/O error | ### Output Examples ``` # Success Trusted key added: dGhpcyBp...NDU= (Alice) # Already trusted Key dGhpcyBp...NDU= is already trusted. # Invalid key error: invalid public key: base64 decode failed # --self without signing key error: no signing key found — run 'collab init-key' to generate one # --self and PUBKEY both provided error: cannot specify both --self and a public key argument ``` --- ## `collab key list` ### Synopsis ``` collab key list ``` ### Behavior 1. Load and parse trusted keys file. 2. Print each entry, one per line. 3. If no trusted keys file exists or file is empty, print a message. ### Exit Codes | Code | Condition | |------|-----------| | 0 | Always (even if no keys) | ### Output Examples ``` # With keys dGhpcyBpcyBhIHRlc3Qga2V5IGJ5dGVzMTIzNDU= Alice YW5vdGhlciB0ZXN0IGtleSBieXRlczEyMzQ1Njc= Bob (laptop) c29tZSBvdGhlciBrZXkgYnl0ZXMxMjM0NTY3ODA= # No keys No trusted keys configured. ``` --- ## `collab key remove` ### Synopsis ``` collab key remove <PUBKEY> ``` ### Arguments | Argument | Required | Description | |----------|----------|-------------| | `PUBKEY` | Yes | Base64-encoded public key to remove | ### Behavior 1. Load trusted keys file. 2. Find matching entry by pubkey string. 3. Rewrite file without the entry. 4. Print removed key and its label (so user can verify). ### Exit Codes | Code | Condition | |------|-----------| | 0 | Key removed successfully | | 1 | Key not found in trusted list, or I/O error | ### Output Examples ``` # Success Removed trusted key: dGhpcyBp...NDU= (Alice) # Not found error: key dGhpcyBp...NDU= is not in the trusted keys list ``` --- ## Sync Behavior Changes ### When Trusted Keys Are Configured During `collab sync`, after cryptographic signature verification passes, each commit's signing pubkey is checked against the trusted keys set. If any commit on a ref is signed by an untrusted key, the entire ref is rejected: ``` Rejecting issues abc12345: commit def67890 — untrusted key: dGhpcyBp...NDU= ``` The untrusted key's full base64 value is printed so the user can copy-paste it into `collab key add` if desired. ### When No Trusted Keys File Exists Sync proceeds as before (any valid signature accepted). A warning is printed once: ``` warning: no trusted keys configured — all valid signatures accepted. Run 'collab key add --self' to start. ``` ### Interaction with Unsigned Events Unsigned events (no `pubkey` field) are already rejected by `verify_ref()` with `VerifyStatus::Missing`. The trust layer does not change this behavior. Per FR-002b, trust policy only applies to signed commits.