pki.sgit.ai / shipped

What already ships, and the two things it doesn't do

This registry is not argued for from first principles. The keypairs, the signing, the encryption to a named recipient and the contacts list already ship — and the documentation says, in its own words, no revocation, no directory. Those two absences are precisely what a registry supplies.

The registry is the missing half of a feature that already exists.

Stating it that way does three things a general argument about key repositories cannot. It gives a concrete user: somebody already running the PKI commands who has hit exactly these two walls. It bounds the scope, because a directory and revocation are a far smaller thing to build and to explain than a general public key infrastructure. And it makes the keyserver history land harder rather than softer — because that failure explains why those two absences are hard rather than oversights. The last system that attempted both was destroyed by how it did them.

The shipped documentation, page by page. Per the v0.33.61 site access report, cross-links here point at pages, not domains: the keypair lifecycle run end to end at sgit.ai/docs/pki, the full messaging choreography at sgit.ai/docs/vault-messaging, and the shipped-versus-proposed boundary in the platform's own words at sgit.ai/docs/limitations. Every one has a markdown twin at the same path — a property agents may rely on.

The shipped surface

Where this is verified, and where it is taken on trust. The sgit pki commands below live in the SGit-AI__CLI repository and are recorded as working in the corpus's reality tree — they are not verifiable from the corpus repo itself. The append lane, by contrast, is code-verified there. This page states which is which because the site's own standard requires it.
What shipsDetail
Keypair generationsgit pki keygen makes two pairs: RSA-OAEP 4096 for encryption and ECDSA P-256 for signing, passphrase-protected
Export / importA JSON public-key bundle {v, encrypt, sign, label, fingerprint, signing_fingerprint} of PEM blocks — not a bare PEM
Sign and verifysgit pki sign / verify over files
Encrypt to a recipientencrypt --recipient <fingerprint>; decrypt --fingerprint <fingerprint> (required). Envelope v2 is base64 JSON {v,w,i,c}: RSA-OAEP wraps an AES-256-GCM content key
Contactssgit pki contacts — a local list of known public keys
The append laneThe vault-to-vault message transport, server-side and code-verified — detail on the enrolment page
A correction, including to this page. Source material circulating in this corpus describes the client sealing a payload to a recipient's X25519 key. That is wrong for that mechanism: the vault-to-vault client crypto it describes is not built. But an earlier version of this page over-generalised the correction, saying the shipped primitives were RSA-OAEP 4096 and ECDSA P-256 and that "anything naming those curves is describing a system that does not exist." That was checked against the sgit pki documentation and then applied to the whole estate, which is wrong. The accurate statement:

Recorded rather than quietly edited, because the failure is instructive: the source was right and the scope was not. Established by a Librarian cross-reference review of the corpus repo at v0.33.61 — 110 PKI documents against ~3,900 lines of PKI code. That review is not published here: it names unremediated findings against live code and a customer, which is the same judgement this site applies to itself.

The two absences

AbsenceWhat it costs todayWhat supplies it
No revocationA compromised key cannot be withdrawn. Anybody holding it stays able to act as that identity, and anybody verifying an old signature cannot tell whether the key was still good at the timeRule 2 — revocation as a signed append, so the record stays append-only and still supports withdrawal
No directoryKeys are exchanged out of band and kept in a local contacts list. There is no answer to "what is the current key for this agent, and who says so". And this is a retirement, not an absence — see belowThe registry — a published, mirrorable record with owner-only writes and every entry signed

Those are the two hardest operations a key repository performs, and they are the two the 2019 network got wrong — it could never delete, and anybody could append to anybody's record. The absences are not an oversight; they are the parts that need designing before they are built. Which is why the rules are published first.

There was a directory. It was built, and then retired

"No directory" reads like something nobody got round to. It is not. In February 2026 this project shipped a key registry: five endpoints (publish, lookup, unpublish, list, log), base-36 lookup codes, duplicate-fingerprint rejection, soft delete, and a genuinely hash-chained transparency log. It was built in a six-day burst, 29 commits and 183 tests, and it still runs behind admin authentication.

In June 2026 it was formally superseded: the vault-hosted registry design records the shipped service as prior art, and the corpus's reality tree carries the line "Replaces a prior FastAPI prototype."

The registry is not an idea this project is reaching for. It is one this project built, ran, and decided was not enough — and the design that replaced it is the one the MVP pack operationalises.

Which turns two of the four rules into checked claims. The February service enforced rule 1 by construction (publish binds to a fingerprint; duplicates are rejected) and gave rule 4 a working transparency log. It also produced the finding that matters most to the MVP's own hash chain: a hash chain with no external witness cannot detect equivocation — a known limit of the construction, and one the MVP inherits. Publishing it alongside the design is the point of publishing the design early.

Reuse the capability model, don't invent one

A registry needs an authorisation model, and one already exists in the platform with the right shape. The append lane separates four capabilities, and the server stores only hashes of the first three:

TierGrantsWhere it lives
Append tokenWrite to the lane, and nothing elseWith senders
Enumeration keyList, fetch, mark processedWith the recipient
Write keyConfigure and purge the laneWith the vault owner
Private keyDecrypt the contentsClient side only — never sent

A total compromise of the server yields hashes rather than capabilities. That is the catastrophic-failure principle implemented rather than asserted, and it is the same discipline a registry needs — the mapping is close to direct: who may append a statement to a record, who may read the record, who may configure it, and who holds the key that signs. Rule 1, that only the owner writes to their own record, is a constraint on the first of those.

Why reuse beats redesign here. This model is implemented and code-verified; the hash-only property is already in production; and a second authorisation model in the same platform is a second thing to reason about, get wrong, and document.

Who may send is already answered

A lane is not open to everybody by default. Its configuration holds registered anchors — hashes of accepted senders — and configuring it requires the write key. So the recipient decides which senders are accepted, using a credential the senders do not have. That answers a question the relay-pattern work left open about who may claim to be a given participant.

Shipped versus proposed — the boundary that must not blur

The addressing scheme is the elegant part: a lane is addressed by the hash of the recipient's public key, so an agent's own key is its address and no directory lookup is needed to find where to send. An agent that has generated a keypair already knows its own lane address without asking anybody — exactly the property the bootstrap trap requires.

HalfState
The lane, its gates, its storage and its limitsshipped and verified
The client crypto that seals to a recipient and derives the lane address from the public keyproposed
Do not code against the derivation. The intended lane address is append_token = H(recipient public key), but no shipped command emits it — today the token is agreed out of band. Both halves are needed for the worked example to run, and documenting the second as though it were the first is the specific error to avoid. The rule this site follows: if it is not code-verified, label it proposed — a page that says "not yet" is better than one an agent trusts and acts on.

Limits worth knowing before building against it

Five megabytes per payload, one thousand files per token, one hundred identifiers per batch, three megabytes of inline content, and a maximum list page of two hundred. Immutable objects are served with a one-year immutable cache directive while references and indexes are served no-store — which matters for anything client-side.

The deeper finding: the capability exists, the composition doesn't

The transport is documented in one place as a generic append mechanism that never uses the words message, send, recipient or inbox. The cryptography is documented in another as file signing and encryption, with no link to the transport. The page that joins them did not exist — so nobody searching for messaging found either half.

That is the discoverability problem one layer up: not unreachable documentation, but uncomposed documentation, where every piece is present and nothing tells a reader they combine. The acceptance test is the right one: give a fresh agent only the machine-readable index and ask how to send an encrypted message from one vault to another. It should reach a working answer — including that the recipient's public key hash is the lane address — without reading source or asking a person.

This site is part of the answer. Its own machine-readable entry point is llms.txt, and this page exists to name the combination rather than leave it implied. The general rule is worth adopting as a review check: for any two capabilities that compose into something a user would ask for, does a page exist that names the combination?