Skip to main content

Crate mkit_rpc

Crate mkit_rpc 

Source
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). See docs/specs/SPEC-EXTERNAL-SIGNER.md and contrib/signers/README.md.
  • SSH transport (ssh.proto) — mkit-cli ↔ a remote mkit-server over an ssh(1) child process. See docs/specs/SPEC-TRANSPORT.md.
  • Signature verification (verify.proto) — the VerifyRequest/ VerifyResponse contract mkit clone/pull/fetch check 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 remote mkit-server over an ssh(1) child process.
  • Signature verification (verify.proto, issue #692): message-only contract for the post-fetch commit/remix/tag check clone/pull/fetch run 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§

hookshooks
Public server-hook wire types and authentication (feature hooks). Public mkit.server.hooks.v1 messages and mkit-hook:v1 authentication.
mkit
transporttransport
Shared transport and health wire types and Connect service traits.

Enums§

FrameError
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 SshFrame body variant. Used for diagnostic messages in unexpected_frame and from transport tests that assert on the rejected body.
cond_to_wire
Encode a RefWriteCondition into the two on-wire fields the UpdateRef message carries: the (often empty) expected_id bytes and the RefExpectation enum. 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_LIMIT and size capped at MAX_FRAME_BYTES.
list_response_refs
The refs of a ListRefsResponse to a request for prefix, skipping every entry whose full name (the prefix plus / plus the listed name) is over MAX_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 Error reply to an update_ref request into a TransportError. Shared by mkit-transport-ssh and mkit-transport-enc so the two clients classify CAS conflicts identically and cannot drift.
read_frame
Reads a single framed protobuf message from r. Enforces the MAX_FRAME_BYTES cap; receivers MUST close the connection on any FrameError::LengthTooLarge.
ref_entry_to_ref
Validate + convert a wire-level RefEntry into a Ref. 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_refs skips 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 RpcError into a TransportError. transport is a short tag ("ssh" / "enc") baked into the catch-all RemoteError message so logs say which transport surfaced the failure.
signer_error_frame
Build a SignerFrame carrying a per-request Error. 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 SshFrame carrying a server-side Error. Mirror of signer_error_frame for the SSH wire.
unexpected_frame
Build a TransportError::RemoteError reporting an unexpected frame variant. want is the human-readable body name the caller expected, got is 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 exceeds MAX_FRAME_BYTES the call returns FrameError::LengthTooLarge without writing anything.