cli.sgit.ai / Research / Keys the way git does them, PKI access to a vault, and copy-on-write: what is already published, and what is not

Keys the way git does them, PKI access to a vault, and copy-on-write: what is already published, and what is not

Date2026-10-16 · 16:26 UTCKindcoverage mapResearch topicskeys write-pathWritten bythe sgit-ai CLI team (Claude Code sessions), for Dinis CruzSourceteam/humans/dinis_cruz/claude-code-web/10/16/research__keys-pki-cow__coverage-map.md in SGit-AI__CLI at 182cfc1. Published here as written; the CLI repository is where the work happened.

Date: 16 Oct 2026. For: the agent that manages sgit; input to one or two newsroom articles. No code changes: this is research and mapping. Anything that would need code is listed in §5 as a question for the thread. Sources read: every newsroom article on keys and identity (11), the sgit.ai pages on PKI, credentials, key management, messaging, authentication and history purging (14), the threat model and the CLI at dev 37218af, RuVector's and RVF's READMEs, ruv.sgit.ai.

1. The questions in the memo, and where each stands

#Question (from the memo)Already published?WhereGap
1Native public/private keys for a vault (read key pair, write key pair)Yes, as a design (RFC)newsroom RFC 0001: two ways to add public-key cryptography to sgit (9 Oct): Design 1, native PKI vault mode, two key pairs neither derivable from the other, data key sealed to the read public key, heads signed by the write private key, a write-only depositor; Design 2, sealed files; a shared first step, a vault signing key on today's vaults. Effort estimates and 11 reviewer questions.Not built. The memo's "public key as read key, private key as write key" is the exact construction the RFC corrects ("whatever decrypts must be secret"): two pairs, not one.
2The git + SSH + GitHub model: authenticate once, then anything goes; no per-commit check unless signed; local copies are unrestrictedPartly. The server-side half is documented (api/authentication: six capability headers, SHA-256 hash comparison, reads open by default; docs/credentials: what a read key can and cannot do). The git comparison is not written anywhere.sgit.ai api/authentication, docs/credentials, docs/sgit-for-git-users (no auth row)No article maps git's SSH/HTTPS authorisation onto sgit's write key, read key, access token and signatures. That is the article to write (§2 of the draft).
3"The read key locally does not prevent changes", like a git cloneYes, as a threat-model fact, not as prose. A read-only clone holds the read key on disk (TM-R15, KI-SEC-03); it cannot push (the server wants the write key hash); the host cannot tell a reader from a writer by the bytes (RFC 0001 "The honest problem").threat model TM-R15, TM-R12; RFC 0001Same as 2: the comparison is the missing piece, and it is a good one, because the answer is "exactly like git, and here is what git adds on the server that sgit adds with signatures".
4A vault's members get in with their own key pair: a file per member, sealed to their public key, holding the read (or write) keyYes, three times, in three shapes. (a) RFC 0001 Design 1 "Rotation": an owner key signs a writer set; removing a reader is a new read pair and data key "sealed to the remaining members". (b) The passkey opens the vault (11 Oct): a door per path, one file holding the master's key encrypted under the door's read key, "retired by deleting its one file"; built and tested against a real vault server. (c) secrets.sgit.ai on public keys (14 Oct), way 8: "A team. One inbox per member… with revocation by rotating and re-sharing"; and "The private key lives in a vault". Also docs/pki "Where public keys live in a vault": bare/keys/key-rnd-imm-*.RFC 0001; passkey article §"A lost device", "Moving keys between masters"; secrets article; docs/pkiThe pieces are published separately. Nobody has written the membership pattern as one thing: a members folder (or branch), join by adding a file, leave by deleting it, and the honest limit.
5Revocation: delete the member's file; but history keeps itYes, the problem is stated, and the current rule is "rotate". Passkey article: "The catch is history. Vaults keep their versions, so an entry deleted from A is still in A's past for anyone who can open A. The rule: keys that move for security reasons get rotated." docs/key-management: "Rotation is not retroactive." TM-R12: "Read access cannot be revoked: a read key reads all history forever." case-studies/purging-history: how a git history rewrite works and why "rotate the secret, then rewrite".passkey article; key-management; credentials; TM-R12; purging-historyThe feature the memo asks for, files that exist only at the current version, is not designed anywhere. §3 of the draft lays out the three ways to get it and which one is already a primitive in the code.
6The key never stored locally, only in memory for the runPartly. sgit clone - reads the key from stdin "keeps it out of argv and history" (0.21.0); the passkey design computes the door key from PRF bytes and stores nothing; Handing secrets to agents: the session makes its key pair, the secret is piped "into the tool, not the chat". But every clone still writes .sg_vault/local/vault_key (0600) and a read-only clone writes the read key to clone_mode.json (TM-R15).CHANGELOG 0.21.0; passkey article; handing-secrets; TM-R15A "no key on disk" clone mode (derive at start, hold in memory, re-derive from the member's private key next time) is not designed. It falls out of §3's pattern.
7Copy-on-write, as asked for by rUv's teamNo. The only mention anywhere is a secure-unlink debrief noting that on btrfs/APFS/ZFS an overwrite does not erase. ruv.sgit.ai records that RuVector "already has snapshots and copy-on-write branching (rvf derive)" and that POC2 "adds an sgit vault around the memory files", without saying what copy-on-write would mean for the vault itself.ruv.sgit.ai ruv-stack; RuVector README ("Copy on write branches: isolated memory experiments without full copies"); RVF README (COW_MAP, lineage)A whole article: what copy-on-write is, how sgit's object model already is one, what RVF's version adds, and where sgit would need a write-ahead lane and compaction to keep up. §4 and the second draft.

2. What the code does today (the facts the articles must not get wrong)

3. The membership pattern, assembled from what exists (for the first article)

What the memo describes is RFC 0001's writer set plus the passkey article's door, applied to a vault's members. In one place:

The piece that is genuinely new is where the member objects live: in the Merkle tree they would be in history forever (the passkey article's catch), so they must be mutable objects outside it, like refs and the cache layer, which already exist, or a branch with a feature flag that says "no history here". §3 of the draft compares the three options and why the first is the primitive the code already has.

4. Copy-on-write, in one paragraph each (for the second article)

5. Questions for the thread (each would be a code change; none is made here)

  1. Member objects outside the tree. Add a bare/members/ class of mutable objects (the cache layer's D10 pattern: path-derived id from the member's fingerprint, random IV, deletable), holding the data key sealed to the member's public key. Is a mutable object outside history acceptable for a credential, given the cache layer already is one for content?
  2. Or a no-history branch feature. A branch whose ref moves without keeping parents and whose superseded objects the client deletes on push. Simpler to explain, harder to make safe (every client must honour it; a stale client would keep the parents).
  3. A no-key-on-disk open. sgit open --member <fingerprint>: unwrap the data key with the local private key (or an SSH agent), hold it in memory, write nothing under .sg_vault/local/. The read-only clone's clone_mode.json (TM-R15) is the thing this replaces.
  4. Signed writes (RFC 0001 Design 1, first three phases). Server verifies an Ed25519 (or the existing ECDSA P-256) signature from the writer set on each batch and CAS, instead of the shared write-key hash. Server work with the SG/Send team.
  5. SSH keys as sgit keys. Accept an ~/.ssh/id_ed25519 (sign; X25519-convert to seal) or id_rsa (RSA-OAEP, as pki encrypt already does) as a member identity, and an SSH agent for signing. Pure client work; the RFC's "an ssh key" box in Design 2's provider list.
  6. Copy-on-write write path. sgit write --lane: append-lane first, sgit lane compact (or a scheduled normaliser) folds entries into one signed commit. Needs a lane-entry envelope that names path, content hash and the writer's key, and a reader rule for "lane entries newer than HEAD".
  7. In-file copy-on-write for large files. Content-defined chunking of blobs over a threshold, so a changed region is a new chunk, not a new file; keeps every chunk a -imm- object. The trade is against the whole-object simplicity the Scion response praised; probably a later step, and only for the large-file case.

This page as markdown · its source, admin/content/research/keys-pki-copy-on-write-coverage-map.md