Expand description
§mkit-rpc
Versioned wire protocols for mkit cross-system speech: external signers
(signer.proto), the SSH transport frames (ssh.proto), the object-
signature verification contract (verify.proto), and shared types
(common.proto). Schemas are defined in protobuf via buffa, with
length-prefixed framing.
mkit-rpc owns the schemas mkit uses to talk to processes outside its own
address space:
- External signers (
signer.proto) —mkit-cli↔ a subprocess signer (file,FIDO2, TPM, future hardware backends). Seedocs/specs/SPEC-EXTERNAL-SIGNER.mdandcontrib/signers/README.md. - SSH transport (
ssh.proto) —mkit-cli↔ a remotemkit-serverover anssh(1)child process. Seedocs/specs/SPEC-TRANSPORT.md. - Signature verification (
verify.proto) — theVerifyRequest/VerifyResponsecontractmkit clone/pull/fetchcheck every newly-fetched commit/remix/tag against (issue #692). Message-only today (no bound RPC method):mkit-cli’s local dispatch (rust/crates/mkit-cli/src/remote_dispatch/packmap.rs) calls the Rust implementation directly (mkit_core::sign::{verify_commit,verify_remix,verify_tag}); the schema is published so a future ConnectRPC-based transport (apps/repo-worker) can bind the identical check to a service method instead of reimplementing it.
Shared vocabulary (common.proto) — algorithms, key forms, error codes,
protocol-version negotiation — is re-exported at the crate root for
convenience.
§Wire framing
Both protocols use the same length-prefixed framing:
[u32 LE length][N bytes protobuf-encoded Frame]Generated code is vendored (not built fresh from .proto on every build);
regenerate it with scripts/regen-rpc-proto.sh after editing a schema.
§Shared Connect transport bindings
The opt-in transport feature owns the canonical mkit.transport.v1 and
grpc.health.v1 messages and Connect service traits in mkit_rpc::transport.
Both mkit-server and mkit-transport-connect re-export these shared types at
their existing public paths. The feature uses ConnectRPC without its native
client or server runtime features and builds for wasm32. Default RPC consumers
do not enable it. Refresh generated/transport/ with
scripts/regen-transport-proto.sh; ordinary builds require no protoc.
Versioned wire protocols for mkit cross-system speech.
mkit-rpc owns the schemas mkit uses to talk to processes outside its address space:
- External signers (
signer.proto): mkit-cli ↔ a subprocess signer (file, FIDO2, TPM, future hardware backends). - SSH transport (
ssh.proto): mkit-cli ↔ a remotemkit-serverover anssh(1)child process. - Signature verification (
verify.proto, issue #692): message-only contract for the post-fetch commit/remix/tag checkclone/pull/fetchrun by default. No bound RPC method yet — mkit-cli’s local dispatch calls the Rust implementation (mkit_core::sign::verify_commit/verify_remix/verify_tag) directly; the schema exists so a future ConnectRPC transport can bind the identical check instead of reimplementing it.
Shared vocabulary (common.proto) — algorithms, key forms, error
codes, protocol-version negotiation — is re-exported at the crate
root for convenience.
§Wire framing
Both protocols use the same length-prefixed framing:
[u32 LE length][N bytes protobuf-encoded Frame]MAX_FRAME_BYTES caps the length at 1 MiB. Larger frames are
a protocol error and the connection MUST be closed.
§Stability
The schemas are frozen at protocol version 1 across the 0.x line.
Wire-compatible additions (new enum values, new optional fields,
new oneof variants) ship as patches. Breaking changes bump the
protocol-version integer in common.proto and introduce sibling
signer2.proto / ssh2.proto files rather than mutating v1.
Modules§
- hooks
hooks - Public server-hook wire types and authentication (feature
hooks). Publicmkit.server.hooks.v1messages andmkit-hook:v1authentication. - mkit
- transport
transport - Shared transport and health wire types and Connect service traits.
Enums§
- Frame
Error - Errors emitted by the framing layer. Wire-protocol errors (a frame
longer than
MAX_FRAME_BYTES, a truncated read) are distinct from decode errors so callers can decide whether to close the connection or just surface a parse failure.
Constants§
- CHUNK_
DATA_ MAX - Per-frame pack-data segment cap. Pack uploads chunk the body into frames this size so the framing layer’s 1 MiB length cap accommodates protobuf overhead on top of the data segment.
- FRAME_
RECURSION_ LIMIT - Recursion limit applied when decoding frame bodies. The deepest message in signer.proto / ssh.proto nests four levels (frame → oneof body → response → repeated entry); 16 leaves generous headroom for schema evolution while staying far below buffa’s default of 100.
- MAX_
FRAME_ BYTES - Maximum length of a single framed protobuf message in bytes. Both directions of both protocols enforce this cap; receivers MUST close the connection on a longer frame.
- MAX_
REF_ NAME - Maximum ref / prefix name length, in bytes, accepted by client-side
validation before sending a frame: SPEC-REFS §3’s ref-name bound,
mkit_core::refs::MAX_REF_NAME_BYTES, which servers enforce, so the client fails fast without a round-trip. - PROTOCOL_
VERSION - The protocol version mkit v0.1.x speaks. Aliased here so callers don’t need to chase the generated module path.
Functions§
- body_
name - Stringify an
SshFramebody variant. Used for diagnostic messages inunexpected_frameand from transport tests that assert on the rejected body. - cond_
to_ wire - Encode a
RefWriteConditioninto the two on-wire fields theUpdateRefmessage carries: the (often empty)expected_idbytes and theRefExpectationenum. Production and test paths share this so the test cannot drift from the production encoding. See SPEC-TRANSPORT §4.2.1. - frame_
decode_ options - Decode options for a single frame body: recursion capped at
FRAME_RECURSION_LIMITand size capped atMAX_FRAME_BYTES. - list_
response_ refs - The refs of a
ListRefsResponseto a request forprefix, skipping every entry whose full name (the prefix plus/plus the listed name) is overMAX_REF_NAME, as the file, memory, s3 and http clients skip such names: a server from before SPEC-REFS §3’s bound may still hold one, and the client could never read or write it. - map_
update_ ref_ error - Map a server
Errorreply to anupdate_refrequest into aTransportError. Shared bymkit-transport-sshandmkit-transport-encso the two clients classify CAS conflicts identically and cannot drift. - read_
frame - Reads a single framed protobuf message from
r. Enforces theMAX_FRAME_BYTEScap; receivers MUST close the connection on anyFrameError::LengthTooLarge. - ref_
entry_ to_ ref - Validate + convert a wire-level
RefEntryinto aRef. Fails the response if the name violates the SPEC-REFS §3 grammar or the object id isn’t exactly 32 bytes. The §3 length bound is not checked here:list_response_refsskips a listed name over it, so one ref a pre-bound server still holds cannot fail a whole listing. - rpc_
error_ to_ transport - Map a wire-level
RpcErrorinto aTransportError.transportis a short tag ("ssh"/"enc") baked into the catch-allRemoteErrormessage so logs say which transport surfaced the failure. - signer_
error_ frame - Build a
SignerFramecarrying a per-requestError. All three reference signers (file / tpm / ctap) share this shape; factored here so it stays in lockstep with the proto schema. - ssh_
error_ frame - Build an
SshFramecarrying a server-sideError. Mirror ofsigner_error_framefor the SSH wire. - unexpected_
frame - Build a
TransportError::RemoteErrorreporting an unexpected frame variant.wantis the human-readable body name the caller expected,gotis whatever it actually received. - write_
frame - Writes a single framed protobuf message to
w. The encoded length is prepended as a little-endian u32; if it exceedsMAX_FRAME_BYTESthe call returnsFrameError::LengthTooLargewithout writing anything.