4.26.3 Token Serialization
Import :std/ensemble/ucan/util for the serialization boundary used by
capability operations and the database backend.
| Procedure | Argument | Result |
|---|---|---|
marshal-token |
Token |
Bytevector |
unmarshal-token |
Bytevector | Token |
4.26.3.1 marshal-token
Serializes the complete token with :std/serde/marshal, creating a fresh
marshal context with dag: #t for each call. Cyclic object graphs are
rejected, including cycles through chain or args. Shared subobjects
without cycles are allowed.
The result includes the nonce and signature as stored on the supplied token. This procedure does not sign, verify, clear fields, or change the token. The signing helpers explicitly construct unsigned copies before calling it.
Callers must not mutate the object graph while it is being serialized. Fresh per-call contexts prevent references or scan state from leaking between separate token messages.
4.26.3.2 unmarshal-token
Deserializes with :std/serde/unmarshal, creating a fresh unmarshal environment
with dag: #t. The deserializer resolves and untaints objects, applying the
token’s field contracts. A final checked cast requires the decoded root to
be a Token.
Cycles and non-token roots are rejected. Shared DAG references are preserved, including references to the same parent token from multiple fields. Malformed data and contract failures propagate from the underlying deserializer.
Use this procedure at network boundaries before passing received tokens to in-process capability utilities. A decoded token is structurally validated, not cryptographically verified: callers must still check signatures, expiration, delegation, and trust as appropriate.
4.26.3.3 Scope
These procedures use Gerbil’s native serialization format and inherit its supported values and size/number limits. They are not a JWT, CBOR, or general UCAN interchange codec, and they do not promise format compatibility across arbitrary Gerbil versions.
The input is a bytevector containing a serialized object, not a framed network
stream. unmarshal-token decodes one root and does not add a trailing-byte
check; transports remain responsible for framing and message-size limits.