| Internet-Draft | QUIP | June 2026 |
| Mututi | Expires 7 December 2026 | [Page] |
QUIP is a brokerless federation protocol over QUIC. It provides portable Ed25519 identities, causal consistency via Dotted Version Vectors, and queueless transport via four explicit tiers with backpressure. QUIP replaces DNSSEC-based trust with Key Transparency + Trust-On-First-Use, enabling 99% deployability while improving security against registrar compromise.¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 7 December 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
QUIP defines a federation-native protocol that ensures:¶
Unlike HTTP/3 + gRPC, QUIP provides:¶
EAGAIN contract, not hidden buffers¶
QUIP addresses five specific gaps in current federation protocols: browser-centric transport constraints that freeze QUIC behind HTTP/3, WebPKI incumbency that blocks self-sovereign identity, database causality techniques that remain internal to storage systems, infrastructure incentives that reward hidden buffering, and standards governance that resists removing HTTP from the critical path. A detailed discussion of the market, regulatory, and technical forces that make this composition viable now is provided in Appendix "Why QUIP, Why Now".¶
QUIP operates directly over QUIC [RFC9000] and eliminates reliance on HTTP-based federation layers.¶
This version represents a significant redesign based on implementation experience and community feedback:¶
announce verb into announce_key and announce_witness¶
The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, NOT RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
NodeIdKey ClaimKT+TOFUDVVKT_WITNESSheartbeat_intervalseq_reset (Section 5.3.5).¶
Upon QUIC connection establishment with ALPN "quip", peers exchange a handshake on the Control Stream (T0, stream 0) before any application streams become active.¶
Handshake format (CBOR array):¶
[
1, ; version (uint)
0b111, ; capabilities bitmask (bits 0-2: CTRL/SYNC/BULK/EVENT all supported)
"compat", ; server_trust_mode
{ ; extensions (optional)
"max_message_size": 65536,
"witness_min_age": 604800
}
]
¶
Capability Bits: Bit 0 indicates support for KT+TOFU (default), bit 1 indicates support for DANE STRICT mode, bit 2 indicates support for T3 datagrams.¶
The bitmask is interpreted as follows: bit 0 (value 0x01) indicates support for KT+TOFU identity verification; bit 1 (value 0x02) indicates support for DANE STRICT server authentication mode; bit 2 (value 0x04) indicates support for T3 unreliable datagram transport. All other bits MUST be set to zero by senders and MUST be ignored by receivers until defined by a future version of this protocol.¶
Server responds with identical structure.¶
Both peers compute the intersection of capabilities. If no common capabilities exist, the connection MUST be closed with error E_PROFILE_MISMATCH (error code 0x08).¶
Version negotiation: Future versions of QUIP MAY define new ALPN identifiers (e.g., "quip-2"). The ALPN identifier "quip" refers to version 1 of the protocol.¶
A Key Claim is a self-signed CBOR object that asserts a user's NodeId and provides a hint about reachability. It is the root of identity in QUIP v01. Unlike v00, there is no primary attestation from a domain. Identity is fully self-sovereign.¶
tagged(65536, [ "key_claim", NodeId, ; 32 bytes (Ed25519 public key) timestamp, ; Unix milliseconds (int64) domain_hint, ; string (optional, e.g., "user@example.net") signature ; 64 bytes (self-signed) ])¶
The domain_hint is advisory only. It suggests where the user
might be reachable but carries no authority. Domains become routing hints,
not identity authorities. If a domain is compromised, users simply
advertise a new hint; their NodeId remains unchanged.¶
A Dotted Version Vector (DVV) is represented as:¶
{
1: dot, ; [writer: NodeId, counter: uint]
2: deps ; {* writer: NodeId => counter: uint}
}
¶
Rules:¶
dot MUST be present for writes. Absent for reads.¶
deps MUST contain exactly one entry per writer ever seen for this resource.¶
Example: Alice (key h'alice_id') writes post #42, has seen Bob at counter 3:¶
{1: [h'alice_id', 1], 2: {h'alice_id': 0, h'bob_id': 3}}
¶
Dotted vectors scale to 100,000 concurrent writers. The deps map
grows only with distinct writers that have modified the resource.¶
Comparison: DVV A is causally after DVV B if A.dot.counter > B.deps[A.dot.writer] or there exists a writer where A.deps[writer] > B.deps[writer].¶
Merge (deterministic tie-breaking): When updates are concurrent (neither dominates), the deterministic order is:¶
dot.counter¶
dot.writer as raw bytes¶
deps map, compared bytewise¶
DVV Pruning: When the deps map exceeds 1024 entries,
implementations MAY prune the entry with the smallest counter
among all writers. The pruned writer's counter is stored as a sentinel value;
future operations from that writer MUST start from that counter + 1.
This prevents unbounded growth while maintaining causality.¶
QUIP replaces DNSSEC/DANE with a combination of Trust On First Use (TOFU) and Key Transparency (KT) gossip. This achieves 99% deployability while providing stronger security against registrar compromise than DANE.¶
The first time a peer presents a Key Claim, the receiving peer automatically pins it. No prior validation is required. This allows immediate communication without any external infrastructure.¶
TOFU behavior:¶
Peers broadcast key witness statements to the control plane (T0) to build distributed trust.¶
tagged(65536, [ "kt_witness", subject_NodeId, ; 32 bytes (the key being witnessed) domain_hint, ; string asn, ; uint (witness's ASN) prefix, ; string (witness's /24 IPv4 or /48 IPv6) timestamp, ; Unix milliseconds valid_until, ; Unix milliseconds (witness validity period, +30 days) witness_NodeId, ; 32 bytes (the witness's key) signature ; 64 bytes ])¶
Witness validity: A witness statement is valid for
30 days from timestamp. After valid_until expires,
the witness MUST be re-issued. If a key has fewer than
3 currently valid witness statements, its KT_VERIFIED status
MUST be revoked. Witnesses SHOULD re-issue
statements weekly.¶
KT_VERIFIED status lifecycle:¶
Verification threshold for KT_VERIFIED:¶
valid_until in the future¶
Witness eligibility: The 7-day age requirement prevents instant Sybil attacks. The 30-day witness validity period forces periodic re-attestation, preventing stale trust.¶
Bootstrap witnesses: New nodes use hardcoded seeds
or DNS TXT _quip-witness.domain. Seeds are exempt from the
age check but MUST have distinct ASNs. Implementations
SHOULD ship with 5 seeds and require 3 distinct seeds
for bootstrap.¶
Witness Bootstrap Rotation: When a bootstrap witness
is rotated (e.g., key update), the witness MUST publish a
witness_rotation attestation signed by its old key and verified
by the new key. Peers SHOULD accept the new key after
verifying the rotation chain.¶
Emergency Revocation: If a bootstrap witness is compromised, operators MAY publish an emergency revocation list (e.g., via HTTPS from a well-known location). Implementations SHOULD check such lists periodically (e.g., daily).¶
DNS hijack becomes a detectable denial-of-service, not a silent man-in-the-middle attack. An attacker who hijacks DNS can present a false Key Claim, but:¶
This is stronger than DANE against registrar compromise, as no single authority can silently rotate keys.¶
Only the NodeId itself can sign a key rotation. Domains cannot revoke or rotate keys on behalf of users. This is a fundamental departure from v00 where domains had attestation authority.¶
tagged(65536, [ "key_rotation", old_NodeId, ; 32 bytes new_NodeId, ; 32 bytes timestamp, ; Unix milliseconds signature ; 64 bytes (by old_NodeId) ])¶
If a user loses their private key, they cannot recover the same NodeId. This is intentional. Key loss results in a new identity. The old identity can publish a "key_compromised" attestation to warn peers, but this is advisory only.¶
Witness Requirement for Rotated Keys: A new key
MUST be witnessed by ≥1 existing witness before
KT_VERIFIED status transfers. This prevents an attacker from
rotating a compromised key and immediately gaining verified status.
The witnessing witness MUST verify that the old key
signed the key_rotation attestation and that the new key
appears in the payload.¶
If a node loses its sequence number state (e.g., after crash recovery
without persistence), it MUST publish a seq_reset
attestation before generating new messages. This informs peers that
previous sequence numbers are abandoned and new messages start from 0.¶
tagged(65536, [ "seq_reset", NodeId, ; 32 bytes last_known_seq, ; uint (last sequence number before loss) timestamp, ; Unix milliseconds signature ; 64 bytes ])¶
Peers receiving a seq_reset MUST discard all
prior sequence state for that NodeId and accept new messages starting
from sequence 0. The seq_reset itself MUST be
accepted even if its sequence number is out of order.¶
Replay protection: To prevent replay attacks, peers
SHOULD reject a seq_reset whose timestamp is more
than max(60s, heartbeat_interval * 3) behind the last seen
message from that NodeId. A legitimate node that loses state after
prolonged inactivity MAY still issue a reset, but the
receiving peer MAY require additional verification
(e.g., out-of-band confirmation) before accepting.¶
QUIP-CBOR is RFC 8949 with the following additional constraints:¶
0x00 not 0x1800.¶
{"value": 12345, "scale": 2} for 123.45).¶
All QUIP messages MUST use QUIP-CBOR. Non-canonical CBOR
MUST be rejected with error E_BAD_ENCODING.¶
QUIP uses four dedicated transport tiers to eliminate head-of-line blocking and ensure deterministic RAM usage. This is the core queueless behavior that distinguishes QUIP from HTTP/3 + CBOR.¶
| Tier | Stream ID / Transport | Purpose | Queue Policy | Reliability |
|---|---|---|---|---|
| T0 Control | stream 0 | Handshake, errors, KT witness, key_claim | Queueless (MAY block on congestion) | Reliable stream |
| T1 Sync | stream 4 | DVV exchange, anti-entropy, state reconciliation | Queueless (EAGAIN on window=0) |
Reliable stream |
| T2 Bulk | streams 8, 12, 16... | Messages, documents, reliable data transfer |
EAGAIN on window=0 |
Reliable stream |
| T3 Event | N/A — QUIC DATAGRAM (RFC 9221) | Media, telemetry, presence, ephemeral events | Drop if congested | Unreliable datagram |
Note on T3: T3 uses QUIC datagrams per [RFC9221], which have no stream ID. Datagrams are unreliable and dropped on congestion. No backpressure applies; senders MUST tolerate loss.¶
Deterministic RAM: Each tier has fixed buffer limits. No unbounded queues.¶
EAGAIN¶
Backpressure Contract:¶
EAGAIN (or equivalent) rather than
buffering the data. This ensures backpressure propagates to the
application, preventing hidden buffer bloat.¶
HOL blocking elimination: Because streams are independent, a large bulk transfer on T2 does not block control messages on T0 or sync on T1. Each tier has its own flow control.¶
T3 Congestion Control Integration: T3 datagrams SHOULD be paced based on the QUIC connection's congestion window. When the congestion window is full, T3 datagrams MUST be dropped; senders SHOULD implement adaptive rate limiting to match the congestion window.¶
T1 SYNC Stream (stream 4):¶
["get", ...] or ["sync", ...]¶
["sync", ...] with deltas¶
T2 BULK Streams (streams 8, 12, 16...):¶
When a non-fatal error occurs (e.g., E_RATE_LIMIT, E_FLOW_CONTROL_BLOCK),
the sender SHOULD use exponential backoff with randomized jitter:¶
For fatal errors (e.g., E_PROFILE_MISMATCH, E_VIOLATION), the connection
MUST be closed. The reporting peer SHOULD log the error for diagnostics.¶
Each NodeId gets a token bucket for T1 and T2 operations:¶
If peer A detects equivocation or invalid signature from peer B, A MUST broadcast a violation receipt on T0:¶
tagged(65536, [ "violation", violator_NodeId, ; 32 bytes type, ; "equivocation" | "invalid_sig" evidence, ; bytes (conflicting messages) signature ; 64 bytes (by reporter) ])¶
Witnesses receiving 3+ independent violation receipts for the same
violator MUST tombstone the violator. No consensus is
required beyond the witness threshold. Tombstoned keys lose all
KT_VERIFIED status and MUST be rejected.¶
QUIP defines four native verbs that correspond 1:1 to the transport tiers. This replaces the opaque payload approach of v00.¶
Control plane operations sent on stream 0:¶
["announce_key", key_claim] ; Publish Key Claim ["announce_witness", kt_witness] ; Publish witness statement ["query", "key", NodeId] ; Request Key Claim ["query", "witnesses", NodeId] ; Request witnesses for a key ["error", code, message_id, text] ; Error notification¶
Responses to query verbs are sent on the same stream (T0) using the corresponding announce verb. A response to ["query", "key", NodeId] is ["announce_key", key_claim]. A response to ["query", "witnesses", NodeId] is zero or more ["announce_witness", kt_witness] messages, one per known witness.¶
State synchronization operations on stream 4. EAGAIN if
receiver flow control window is zero.¶
["get", resource_id, their_dvv] ; Request resource with DVV ["set", resource_id, new_dvv, payload] ; Update resource ["sync", resource_id, their_dvv, deltas] ; Bulk sync response¶
The receiver MUST respond to a set verb with either an updated ["set", resource_id, new_dvv, payload] reflecting the accepted write, or an ["error", E_DVV_CONFLICT, ...] on T0 if the DVV is rejected as stale. A successful set response carries the merged DVV so the sender can confirm causality. If the receiver accepts the write without modification, it MAY echo the same DVV back.¶
Large data transfer on streams 8, 12, 16... EAGAIN if
receiver flow control window is zero.¶
["send_start", resource_id, total_size, hash] ; Initiate transfer ["send_chunk", resource_id, seq, offset, bytes]; Chunked data with sequence number ["send_complete", resource_id, final_hash] ; Finalize transfer¶
Integrity verification: Each chunk includes a sequence
number (seq) for ordering and the final hash is the SHA-256 of
the concatenated chunks in order. Receivers MAY compute a
running hash incrementally; if the final hash mismatches, the entire
transfer MUST be rejected. Implementations MAY
include per-chunk hashes for early corruption detection.¶
Ephemeral events sent as QUIC datagrams. Unreliable. Dropped on congestion, no retransmission.¶
["emit", "presence", NodeId, status] ; Presence update ["emit", "like", target_id, timestamp] ; Like/ack ["emit", "media", codec, payload] ; Real-time media chunk¶
QUIP replaces DANE+DNSSEC with KT+TOFU for the default COMPAT mode. STRICT mode retains DANE for environments that require it.¶
| Mode | Requirement | Use Case |
|---|---|---|
| COMPAT (default) | WebPKI for bootstrap + KT+TOFU for identity | General deployment, 99% of use cases |
| STRICT (optional) | DNSSEC + DANE + KT+TOFU | High-security, regulated environments |
| LEGACY (deprecated) | WebPKI only | Legacy transition, removal in v02 |
Why not DANE as default? DNSSEC deployment is at 1.3% globally. Requiring it would make QUIP undeployable. KT+TOFU provides equivalent security (3+ independent witnesses) without the deployment barrier. DNS hijack becomes a detectable DoS, not a silent MITM.¶
LEGACY mode deprecation timeline: LEGACY mode MAY be removed in QUIP v02, scheduled for 2027. Deployments SHOULD migrate to COMPAT mode.¶
QUIC connection with ALPN "quip".¶
T0 Control Stream (Stream 0): Designated immediately.¶
T1 Sync Stream (Stream 4): Designated immediately.¶
T2/T3: T2 streams opened on demand; T3 uses QUIC datagrams.¶
Handshake sequencing:¶
T2/T3 traffic SHALL not be processed until the initial Key Claim exchange completes.¶
+------------------+----------------------------------+ | varint length | QUIP-CBOR object | +------------------+----------------------------------+¶
The CBOR object MUST be a single complete top-level item with no trailing bytes.¶
Implementations MUST enforce the following limits:¶
| Resource | Limit | Behavior When Exceeded |
|---|---|---|
| Maximum CBOR object size | 64 KB | Reject with E_BAD_ENCODING
|
| Maximum DVV deps entries | 1024 | Prune oldest (see DVV pruning) |
| Maximum pending sequence gaps | 256 | Discard oldest |
| Witness age requirement | 7 days (configurable) | Reject witness, log warning |
Minimum witnesses for KT_VERIFIED
|
3 distinct ASN + prefix | Key remains unverified |
| Witness validity period | 30 days (configurable) | Status reverts to PENDING after expiry |
IANA is requested to register the following ALPN protocol ID:¶
IANA is requested to create a registry titled "QUIP Error Codes" with the following initial contents:¶
| Code | Name | Description |
|---|---|---|
| 0x00 |
E_OK
|
Success |
| 0x01 |
E_BAD_ENCODING
|
Invalid CBOR encoding |
| 0x02 |
E_UNKNOWN_VERB
|
Unknown verb |
| 0x03 |
E_RATE_LIMIT
|
Rate limit exceeded |
| 0x04 |
E_KT_UNVERIFIED
|
Key not KT_VERIFIED |
| 0x05 |
E_DVV_CONFLICT
|
DVV merge conflict |
| 0x06 |
E_FLOW_CONTROL_BLOCK
|
Flow control window zero (use EAGAIN) |
| 0x07 |
E_VIOLATION
|
Violation detected |
| 0x08 |
E_PROFILE_MISMATCH
|
No common capabilities |
Registration policy: IETF Review for codes 0x00-0x7F.¶
IANA is requested to create a registry titled "QUIP Verbs" with the following initial contents:¶
| Verb | Tier | Description |
|---|---|---|
announce_key
|
T0 CTRL | Publish Key Claim |
announce_witness
|
T0 CTRL | Publish witness statement |
query
|
T0 CTRL | Request key or witnesses |
error
|
T0 CTRL | Error notification |
get
|
T1 SYNC | Request resource with DVV |
set
|
T1 SYNC | Update resource |
sync
|
T1 SYNC | Bulk sync response |
send_start
|
T2 BULK | Initiate transfer |
send_chunk
|
T2 BULK | Chunked data |
send_complete
|
T2 BULK | Finalize transfer |
emit
|
T3 EVENT | Ephemeral event |
Registration policy: IETF Review for new verbs.¶
QUIP defends against:¶
QUIP does NOT defend against:¶
Sybil witnesses: An attacker spawning N witnesses in the same ASN fails ASN diversity requirement. Mitigation: ASN diversity + /24 diversity required. Cost estimate: $3k/month per distinct ASN minimum. For 3-of-N security, attacker budget must exceed $9k/month to control all witnesses.¶
Eclipse attack on KT gossip: An attacker controlling all of a peer's gossip connections could suppress witness statements. Mitigation: Witness set must include ≥1 out-of-band verified seed. Implementations SHOULD ship with 5 seeds from 3 distinct organizations.¶
Age requirement: The 7-day minimum age for witnesses prevents instant Sybil attacks. An attacker must maintain infrastructure for 7 days before their witnesses become eligible. This window aligns with certificate transparency log monitoring periods.¶
Witness expiry: The 30-day witness validity period
forces periodic re-attestation, preventing stale trust. A key that loses
all valid witnesses reverts to TOFU-only PENDING status.¶
A seq_reset with a timestamp significantly older than the last
seen message could indicate an attempted replay. The max(60s, heartbeat_interval * 3)
bound limits the replay window. An attacker who compromises a NodeId's
private key can issue a seq_reset with a fresh timestamp, but
this also allows key rotation; the witness requirement for KT_VERIFIED
status transfer provides a separate defense.¶
QUIP's design has several privacy implications that implementers and deployers MUST consider:¶
Mitigations (implementations SHOULD support):¶
Linkability through rotation chains: Key rotation preserves identity continuity for accountability. All keys in a rotation chain are cryptographically linked to the genesis NodeId. This linkage is intentional and permanent. Rotating keys does NOT provide unlinkability or anonymity.¶
This section records the status of known implementations of the QUIP protocol at the time of publication of this Internet-Draft. It is provided to aid interoperability and will be removed before publication as an RFC. See [RFC7942] for the terminology and intent of this section.¶
Reference Implementation: A reference implementation is planned but not yet available at the time of this submission. The author intends to publish a minimal implementation before the expiration of this draft. Interested parties should contact the author for updates.¶
Other Implementations: No other implementations are known at this time.¶
QUIP combines five existing primitives into a coherent federation protocol: QUIC transport, Ed25519 self-sovereign identity, Dotted Version Vectors, Key Transparency with Trust-On-First-Use, and explicit EAGAIN backpressure. None of these primitives are new. Their composition is.¶
Why this composition did not exist earlier¶
EAGAIN to JavaScript. Any federation protocol that assumed HTTP as transport inherited head-of-line blocking and hidden buffering.¶
EAGAIN instead of buffering would have been rejected as "hard to use." The operational pain of OOM kills was socialized across the industry, not attributed to the protocol.¶
Why now¶
EAGAIN contract in QUIP converts hidden memory growth into visible backpressure, shifting the optimization burden from SREs to application developers.¶
quinn, s2n-quic, msquic — are stable and support datagrams [RFC9221]. Rust and Swift now have mature Ed25519 and CBOR implementations. The engineering cost to implement QUIP dropped from "research project" to "3 months for one engineer."¶
QUIP exists now because the pain of the status quo — DMA fines, OOM kills, DNS hijacks, and merge conflicts — finally exceeds the political cost of deleting HTTP, DNSSEC, and WebPKI from the federation path.¶
The primitives were ready. The incentives were not. Now they are.¶