Skip to main content

Crate whipplescript_custody

Crate whipplescript_custody 

Source
Expand description

Credential custody protocol (DR-0053).

whip holds handles; a custodian in a separate security principal holds material and performs operations. This crate is the seam between them: the handle/sentinel types, the operation vocabulary, and the transport trait. It contains no backend and no cryptography — those live in whipplescript-custodian.

The vocabulary is deliberately closed and there is no get(handle) at any layer (DR-0053 §2): the only power the custodian offers is substitute / sign / verify / derive / wrap / unwrap / mint under policy. One caller with a legitimate reason to fetch plaintext would re-establish extractability for all, so the operation does not exist to be called. models/maude/credential-no-eliminator.maude proves the language side of this; the -REVEAL sibling carries the rejected get design.

The custodian stays semantically dumb (§3): whip constructs entire requests with a typed Sentinel exactly where material belongs, and the custodian’s whole power is substitution at the marked slot if policy permits. It does not parse payloads, choose endpoints, or know what an API is.

Modules§

canon
Built-in canonicalizers (DR-0053 §7).
client
whip’s client transport to a custodian daemon on this box: one newline-delimited JSON call per connection over a Unix domain socket (the server half lives in whipplescript-custodian::serve). Unix-only, so the protocol crate stays wasm-clean; a wasm host supplies its own CustodyTransport.

Structs§

CredentialName
A credential’s stable name. Resource identity is credential:<name> — deliberately not backend-qualified (vault:, kms:), so identity survives backend migration and grants keep working (DR-0053 §5).
CustodyCall
One call over the transport.
CustodyReply
The custodian’s reply. Every reply — refusals included — carries the use id it was recorded under and the rung the credential’s evidence derives, with degraded set when the resolution is a compatibility shim (legacy env: refs resolve at r0 degraded; DR-0053 Migration).
EgressRequest
An outbound HTTP request whip constructed in full, with sentinels at the marked slots. The custodian substitutes and egresses; it never chooses any part of this.
EgressResponse
Envelope
A label-carrying envelope (DR-0053 §13). The envelope records the caller’s IFC label and unwrap restores it, so the wrap → store → unwrap roundtrip cannot launder; AEAD associated data binds the ciphertext to (credential, context, label) so envelopes are not swappable between contexts even with every label intact (models/maude/credential-wrap-carriage.maude, -UNBOUND sibling).
MintExtraction
How the custodian extracts the minted material from an exchange response (DR-0053 Open, OAuth response capture): whip declares the path, the custodian applies it — a dumb instruction, not protocol semantics. Only simple dotted paths (access_token, data.token) are supported; extraction is not a query language.
Sentinel
A typed placeholder marking exactly where material belongs in a request whip constructs. The custodian substitutes at marked slots and nowhere else. The textual form is {{whipplescript-credential:<name>:<form>}}.
UseAttribution
Who is using the credential, recorded with every use — §1 claims every use is attributable, and UsesAreRecorded in CredentialCustody.tla exists so the rung floor cannot be satisfied by an unrecorded use.

Enums§

CredentialKind
The declared kind of a credential. kind exists so the checker can statically reject sign … with stripe_api (DR-0053 §5); the custodian’s registered kind is authoritative and mismatch is a check error.
CredentialRef
One parsed operator-config credential reference (DR-0053 Migration).
CustodyError
Typed refusals. Refused reasons are closed so callers can route them; backend faults carry a message.
CustodyOk
Success payloads, one per operation. None yields sealed material: Derived and Minted return handles; Unwrapped returns application data that was whip’s to begin with.
CustodyOp
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.
Operation
The closed operation vocabulary (DR-0053 §2). There is no Get variant and never will be; a wire message naming an unknown operation fails to deserialize.
PresentationForm
Presentation form for material at a marked slot (DR-0053 §5): usable in any string position, lowering the handle to a sentinel.
Rung
Sealing rung, ordered (DR-0053 §4). Derived from evidence by the custodian, never asserted in configuration — require credential <rung> in the signed policy compares against what the custodian derived (models/maude/credential-rung-evidence.maude: configuration is not evidence).
SignatureAlg
Signature algorithm for sign/verify. Distinct from CredentialKind: the kind is what the credential is, the alg is what this call asks it to do, and the custodian refuses mismatches.
TransportError
Transport faults, distinct from custody refusals: a refusal is the custodian speaking; a transport error means it never did.

Constants§

CUSTODIAN_SOCKET_ENV
The conventional environment variable naming the custodian socket.
CUSTODY_PROTOCOL
Wire protocol identifier, carried on every call so a custodian can refuse a caller from a different protocol generation.

Traits§

CustodyTransport
The transport seam (DR-0053 §2, tracker slice 1). r0 may run in-process, but it still speaks CustodyCall/CustodyReply through this trait — wiring r0 as direct function calls would leave the principal-separation seam unexercised and make r1+ a rewrite rather than a backend swap.