pub enum CustodyOp {
Request {
credential: CredentialName,
request: EgressRequest,
slots: usize,
},
Sign {
credential: CredentialName,
alg: SignatureAlg,
derivation: Vec<String>,
payload_b64: String,
},
Verify {
credential: CredentialName,
alg: SignatureAlg,
payload_b64: String,
signature_b64: String,
},
Derive {
credential: CredentialName,
context: String,
},
Wrap {
credential: CredentialName,
plaintext_b64: String,
label: Value,
context: String,
},
Unwrap {
credential: CredentialName,
envelope: Envelope,
context: String,
},
Mint {
credential: CredentialName,
scope: Vec<String>,
ttl_secs: u64,
exchange: EgressRequest,
extraction: MintExtraction,
exchange_slots: usize,
},
}Expand description
One custody operation. Externally tagged by op, and the vocabulary is
closed: a message with "op": "get" — or any name outside this list —
fails to deserialize.
Variants§
Request
Substitute at marked slots, egress, return the response.
Fields
credential: CredentialNamerequest: EgressRequestslots: usizeHow many sentinel slots the CONSTRUCTING program placed, declared
out of band from the request text itself. The custodian finds
sentinels by scanning finished text, which cannot tell a slot the
author wrote from one that arrived inside interpolated data; if a
value could carry a sentinel into a header, URL or body, the
custodian would fill it with real material at a position the author
never designated — and the raw form would put the bare secret
there. Declaring the count out of band makes any such injection a
refusal rather than a substitution: data can add an occurrence but
cannot remove the author’s, so the totals disagree.
Sign
Keyed signature, optionally through a derivation chain (§7): the
custodian folds HMAC over the chain from the sealed material, then
signs the payload with the final key. For AWS SigV4 the chain is
[date, region, service, "aws4_request"] and whip never holds
kSigning, which is itself a credential.
Verify
Constant-time verification (§6) — in the custodian, since a timing oracle in whip leaks the key.
Derive
HKDF subkey; returns a handle, never material.
Wrap
Envelope-encrypt application data whip may persist but not read back without the custodian (§13).
Unwrap
Open an envelope. Legitimately returns plaintext to whip — wrapped data is application data, not credential material — so unwrap is scoped, budgeted, and audited like any other use (§13).
Mint
Credential exchange, custodian-executed so whip never sees the token in the response body. Returns a handle plus the non-secret half.
Fields
credential: CredentialNameexchange: EgressRequestextraction: MintExtractionexchange_slots: usizeSlots the constructing program placed in exchange, declared out of
band for the same reason as CustodyOp::Request::slots: the
exchange is whip-constructed text carrying the PARENT credential’s
sentinels, so an injected slot here would present the parent to a
position the author never designated.