IETF DTN Working Group · for discussion

Signed custody receipts in a BPv7 extension block

Who can prove they held a bundle, and when: evidence that travels with the bundle and anyone can check later, offline. Written up as an individual Internet-Draft, with an open reference implementation tested through four independent BPv7 stacks.

The problem

When a bundle crosses operators, each one holds only its own logs

Late, lost or altered

Ground stations, relays and lunar networks run by different parties hold data for minutes to hours.

Logs are not evidence

Another party cannot verify an operator’s log without trusting the operator that wrote it.

A different question

Custody transfer asks who must retransmit now. Receipts answer who can prove they held it, and when.

How it works

Custodians append a receipt; plain forwarders do nothing new

Nodes that choose to act as custodians each append one signed receipt to an extension block carried in the bundle. Forwarders that do not implement the draft keep the block unchanged: it is replicated in every fragment and never asks a node to delete the bundle or discard the block. A verifier checks every receipt against the custodian’s key and reports any stretch of the route that nobody signed, using the Previous Node block.

The receipts are notInstead
Custody transferThey complement BIBE and carry no retransmission duty
Administrative recordsSigned objects in an extension block
A reason to parse payloadsNo custodian interprets the ADU; it hashes the bytes it holds
Required of every nodeOpt-in per node; forwarders need not implement the draft
Proof the claims are trueEach custodian is bound to its signed claims; gaps are reported, never inferred

The receipt (version 2)

A COSE_Sign1 over a small CBOR map, about 156 bytes

Signed

EdDSA (Ed25519) in the protected header; the key is pinned by the custodian’s node ID.

Bound to the bundle

Bundle identity and a SHA-256 of the payload bytes held, so any verifier checks the binding with no application knowledge.

Fragment-aware

A whole-bundle receipt covers each fragment; a custodian holding a fragment signs for that fragment.

Evidence

Carried byte-identical by four stacks that do not know it

Path, held across a scheduled gapBlock on arrivalPayload BIBGap audit
µD3TN, two nodesbyte-identicalverifieswith Previous Node option on
NASA HDTNbyte-identicalverifiesnames the unsigned node
JPL IONbyte-identicalverifiesnames the unsigned node
Hardybyte-identicalverifiesnames the unsigned node
µD3TN then HDTN, one pathbyte-identicalverifiesnames the unsigned node
Two JPL ION nodes over LTP, Earth-Moon light time on the linkbyte-identicalverifiesnames the unsigned node

A second implementation that signs

Aalyria's Hardy, built with a prototype custody-receipt filter (a Rust Egress Rewriter), now signs receipts itself. Its receipts verify with our reference code, our receipts pass through it byte-identical and gain a second valid one, and the Rust and JavaScript encoders agree byte for byte on shared test vectors. It also signs each fragment of a fragmented bundle for exactly the bytes it holds, leaves encrypted payloads unsigned rather than sign bytes it cannot see, and can be set to sign only bundles that already carry receipts: 31 of 31 live checks (RESULTS.md section 7). The filter is local and not yet proposed upstream.

Along the way, interop testing found that JPL ION builds its BIB input differently from RFC 9173 §3.7 (reported as ION-DTN #130), and our implementation independently reproduces the corrected Appendix A.3 vector of RFC 9173 erratum 9192. Commands and outputs: transport/bpv7/RESULTS.md.

Lunar and laser links

Measured on the links operators will actually run

LunaNet

Mapped onto NASA's LunaNet Interoperability Specification v5: BPv7, LTP and IP convergence layers, BPSec. A three-provider lunar relay run checks every receipt against the Moon's actual distance at the moment of contact, so a backdated receipt is caught even when its signature is genuine (profile).

Optical crosslinks

Modeled on public optical inter-satellite link parameters at 2.5, 10 and 100 Gbps, with fades, pointing and acquisition outages and cross-plane handoffs. An unsigned relay is reported as a gap and a tampered bundle is caught. Across a 4,032-satellite constellation with laser crosslinks, 10,000 of 10,000 bundles verify, including with 30% of crosslinks failing (results).

Cost at line rate

Signing every bundle at every hop does not scale to laser rates; signing once per contact does, with nothing added to the forwarding path. Per-bundle stamping now adds 0.13 to 0.16 ms per hop for a 1 MiB bundle, down from 10 ms. Batch carriage is proposed for -02 (proposals).

New, 2026-10-21

Keys without an online authority

BPSec leaves key management out of scope. For custody receipts it is now built, tested through all four stacks, and in the npm package (0.5.0).

Keys travel in the bundle

Key and revocation records, COSE_Sign1 like the receipts, chain to each operator's root key and ride in a Key Record Block (type 225). A destination holding only the root key verified the chain through µD3TN, HDTN, ION, Hardy and the mixed path (spec).

A stolen key cannot fake the past

Receipt field 9 commits each receipt to the ones before it, so a later custodian witnesses that they existed. A backdated signature from a revoked key is refused unless an honest node or the verifier saw it in time. Self-revocation needs no operator.

Gaps get a size

Receipt field 8 records the Hop Count block. All four stacks add exactly one per node, so an unsigned stretch is reported as a number of forwarders, including on uD3TN, which leaves no Previous Node (results, sections 8 and 9).

Onboard, the same rules run in C with no heap, about 3 KB on an ARM Cortex-M4. Both fields are optional; receipts without them are unchanged. Proposed for -02 as proposals 4 and 5 (proposals).

Where it fits

The signed, accountable piece next to work already in the group

WorkRelation to custody receipts
BIBE custody transferWho must retransmit; receipts record who held it
Traceroute Extension BlockUnsigned hop records for diagnostics; a proposed optional signature would make them evidence (sketch)
SBAMAudits dropped security operations; receipts evidence custody that did happen
DTN Peering ProtocolRoutes between domains; receipts are the accounting between them, with custodian keys endorsed by a domain’s peering key
BPSec COSE contextSame COSE building blocks

How these fit together is set out in a discussion draft, accountability between administrative domains, and the block is offered as a case for the per-hop block discussion in a short case study.

For the group

Questions we would value your view on

  1. Is this in scope for the DTN WG, or better placed elsewhere?
  2. EdDSA as the baseline: should a second algorithm (ES256) be required for flight hardware?
  3. Fragments: is “whole-bundle receipts cover each fragment” the right model?
  4. Hop Count in receipts to size gaps: useful, and do implementations increment it reliably?
  5. Should receipts share a hop-record shape with the Traceroute Extension Block?
  6. Does an append-only, multi-signer block fit the per-hop block lifecycle under discussion?

Get involved

Reviewers, a second implementation, co-authors

Comments are welcome on the dtn@ietf.org list or directly. We will run any stack’s build against the interoperability suite.