PCAS key custody — claims 16 & 26
This note maps the patent's key-custody claims to the code, and states what the delivered path guarantees versus what a hardware deployment adds.
Where succession keys live
On the isolated-signer succession path, a successor key is generated inside the isolated signer
through the signer's own key factory (internal/signing.Server.GenerateSuccessorKey
→ KeyFactory.GenerateSigningKeyFromProto), stored in the signer keystore under a
deterministic per-epoch handle, and used only via the in-signer DigestSigner. The
predecessor is resolved the same way. The control plane never receives private key
material; it requests a mint over the transport and receives only public material and
the opaque record (claims 1/12/49).
The signer namespaces every newly minted succession key and sealed epoch floor by
the pair (tenant ID, identity ID). Two tenants can use the same workload name and
still start at epoch zero independently. The legacy KeyHandle(identity, epoch)
helper remains for older direct signer fixtures; the control-plane outbox worker
uses TenantKeyHandle(tenant, identity, epoch) and does not claim an unscoped key
on behalf of a tenant. A pre-existing unscoped chain requires an explicit custody
migration before it can be advanced through this worker; the worker must not guess
which tenant owns a signer handle.
The signer also stores a sealed mint intent and exact public result in
pcas-mint-operations/ under the same custody directory and key wrapper. It
fsyncs the first-writer intent before key generation, then the completed record
before advancing the epoch floor or returning the RPC response. An identical
request after a lost response or a control-plane database failure returns the
record already minted. A changed request for that epoch is refused. Keep this
directory with the signer keystore and epoch floors in backup and restore; losing
only one of those three makes recovery ambiguous and must fail closed.
Claim 16 — locked, non-dumpable, zeroized buffers (DELIVERED)
The default key factory returns crypto.GenerateLockedKey, a *crypto.LockedSigner
whose private scalars live in an mlock'd, MADV_DONTDUMP, explicitly zeroized-on-
Destroy buffer (AN-8; see internal/crypto/locked.go). The signer process
additionally hardens itself with PR_SET_DUMPABLE=0 and RLIMIT_CORE=0
(internal/signing/harden_linux.go). So every succession key sits in locked memory
that is excluded from core dumps and wiped on destruction — exactly claim 16.
Pinned by internal/signing.TestINT07_SuccessorKeyIsLockedAndZeroizable: a
GenerateSuccessorKey result is held as a *crypto.LockedSigner, signs, and is
removed + zeroized via DestroyKey. The mlock/zeroize primitives themselves are
covered by internal/crypto's LockedSigner tests.
Non-release (DELIVERED)
The signer's wire contract (internal/signing/proto/signer.proto) exposes
GenerateKey, GetPublicKey, Sign, DestroyKey, Health, MintSuccessor — and
no operation that returns a key's private bytes. Private material leaves the
signer only sealed-at-rest under a KEK (the persistent-keystore SealedBytes path),
never in the clear. Pinned by TestINT07_NoSuccessorKeyExportOverTransport
(reflects the client interface; fails on any export-suggesting method) and by the
AN-4 buf breaking gate, which would flag an added export RPC.
Claim 26 — HSM / module custody boundary (SEAM DELIVERED; module test needs a module)
Claim 26's hardware embodiment is the same enforcement component (the signer,
mediating all use) with the key factory backed by a module-resident backend, so
private material never exists outside the module. This plugs in at the existing
signing.WithKeyFactory seam — the same seam the core signer uses for post-quantum
algorithms — with no change to the mint path. The PKCS#11 primitives already exist
in-tree (internal/kms/pkcs11, github.com/miekg/pkcs11), and
internal/succession/minter.SoftHSM is the software double used to exercise the module
semantics in unit tests.
The software double does not qualify a physical HSM or a provisioned PKCS#11
module. Qualification requires the module-resident KeyFactory adapter, a token,
and an integration test proving that generation, signing, restart recovery, and
destruction stay inside that module. Record the module and firmware tested;
software-locked custody alone does not prove the hardware embodiment.