Skip to content

Teams and recipients

Per-person keys, so access can be withdrawn one person at a time.

Passphrase mode has one secret and everyone holds it. That is fine alone and awkward the moment someone leaves: removing their access means changing the secret and re-encrypting everything, for everyone.

Recipient mode removes the shared secret entirely.

How it works

Every protected file gets its own fresh random AES-256-GCM key. That key is then wrapped — encrypted — separately to each authorised person's age X25519 public key, and the wrapped copies live in .sgit/stanzas/.

So one file has one body of ciphertext and several small headers, one per person who may open it.

The consequence is the useful part: adding or removing someone rewrites stanzas, not blobs. On a large repository that is the difference between an instant operation and re-encrypting everything.

Starting in recipient mode

terminal
sgit init --mode recipient -s src/secrets

This generates an admin keypair.

Joining

The person joining runs:

terminal
sgit onboard

That generates their keypair locally, writes the identity to $CODESEAL/<alias>/ with mode 0600, and prints the public key. The private half never leaves their machine — what they send you is the public key.

With a Portal configured, this submits an onboarding request and waits for an admin to approve. Without one, they send you the public key and you add it.

The four operations

Add someone

terminal
sgit rekey add-recipient alice age1xxxxxxxxxxxxxxxxx developer

Header-only. Every stanza file gains a copy of the file key wrapped to Alice. The blobs do not move.

Remove someone

terminal
sgit rekey remove-recipient alice          # soft
sgit rekey remove-recipient alice --full   # hard

These are genuinely different, and the difference matters more than it looks:

what it doeswhat it costs
softdrops their stanza — they cannot decrypt anything newinstant, header-only
--fullre-encrypts every blob with fresh keysslow, rewrites the repository

Soft removal does not un-tell them what they already know. If Alice cloned the repository while authorised, she holds blobs and a key that opens them. Soft removal stops her decrypting future changes; it cannot reach the copy on her disk.

Use --full when the departure is the kind where that matters.

Rotate a key

terminal
sgit rekey rotate-recipient alice age1NEW…

Replaces one public key with another everywhere. This is the lost-laptop command, and the routine-hygiene one. Header-only.

Full rekey

terminal
sgit rekey full

Fresh file keys for every blob, everything re-encrypted, every stanza rewritten. For periodic hygiene — or to recover from a lost admin key, which any remaining recipient can run.

Choosing

Passphrase mode when you are alone, or when the team is small enough that "change the secret and tell everyone" is a real option.

Recipient mode the moment more than one person needs access that you might later want to withdraw. The setup cost is one extra flag and backing up a key; everything after that is cheaper.

You can switch later. It re-encrypts, so it is not free — but it does not require starting the repository again.

See also