montana/Montana-Protocol/Montana Egress v1.0.0.md
2026-05-26 21:14:51 +03:00

17 KiB
Raw Blame History

Montana — Egress Layer Specification

Version: 1.0.0 (2026-05-26)

Layer: Application — sits above the Network layer. Consumes the mesh; defines no consensus state and contributes nothing to any state root.


Introduction

The Egress layer carries a participant's ordinary internet traffic out to the public internet (the clearnet) through a Montana node located in a chosen jurisdiction. A client selects an exit country manually, or delegates the choice to an automatic selector. The transport that carries the client to the mesh, survives per-operator filtering, and re-routes around blocked entry points is supplied entirely by the Network layer; the Egress layer adds only the egress semantics on top.

The Egress layer is an application service offered by node operators who opt in. It is not a consensus mechanism, not a protocol guarantee, and not a protocol-level anonymity system. The consensus state machine is unaware of egress; removing the entire Egress layer changes no state root and halts no clock. This separation is deliberate: anti-censorship reachability is a Network-layer property shared by all traffic (consensus, gossip, messenger, egress), whereas egress is one application built on that foundation.

Relationship to other specifications

Concern Owning specification
Post-quantum transport handshake (Noise_PQ XX), uniform framing Network — Transport obfuscation
Identity-Bound Tunnel (IBT) access levels Network — Transport obfuscation → IBT
Reachable entry discovery, transport profile ladder T0T4 Network — Reachability sensing, Transport profile ladder
Multi-hop transit Network — NAT Traversal → Circuit Relay v2
Account identity, ML-DSA-65 / ML-KEM-768 sizes Protocol — Cryptographic primitives

The Egress layer references these; it redefines none of them.

Regulatory stance

The Egress layer is an opt-in service of an individual node operator, not a property the protocol guarantees to all participants. The consensus layer neither requires, rewards, nor records egress. An operator enabling egress accepts the operational and jurisdictional consequences of forwarding third-party traffic; an operator who does not enable it participates fully in consensus and messaging regardless. This keeps general-purpose egress out of the protocol's regulatory surface.


Roles

Role Definition
Egress client A participant authenticated at IBT level 3 (account keypair) requesting clearnet egress.
Entry node Any reachable mesh node the client connects to first. Selected by reachability sensing; carries ciphertext only.
Relay A mesh node providing Circuit Relay v2 transit between entry and exit when they are not directly connected. Carries ciphertext only. Entry and relay MAY be the same node.
Exit node A mesh node that has opted into clearnet egress, advertises a jurisdiction, and forwards the client's streams to the public internet.

The entry, relay, and exit are ordinary Montana nodes. A node MAY hold several roles simultaneously. The exit role is configuration-gated and disabled by default.


Architecture

The client establishes two nested Noise_PQ XX sessions:

              outer session (Network transport, profile T0..T4)
   client ───────────────────────────────────────────────▶ entry node
                                                              │ Circuit Relay v2
                                                              ▼
   client ════════ inner end-to-end Noise_PQ XX ══════════▶ exit node
              (entry and relay carry ciphertext only)         │ clearnet
                                                              ▼
                                                          destination host
  1. The outer session is an ordinary mesh transport session (Network layer). It gets the client onto the mesh through a reachable entry, with DPI resistance and the transport profile ladder. The entry authenticates the client by IBT.
  2. The inner session is an end-to-end Noise_PQ XX session between client and exit, tunnelled through the entry (and any relay) by Circuit Relay v2. Entry and relay observe only the AEAD ciphertext of the inner session: they learn the participants' addresses, never the egress control messages or the egress payload — the same trust model as Network-layer relay.

The exit terminates the inner session, authenticates the client by IBT level 3, and forwards the client's streams to the clearnet.


Egress directory

Exit nodes advertise availability in an egress directory. The directory is advisory transport-layer metadata, propagated as a PeerRecord extension over peer exchange, under the existing peer-exchange rate limit (at most one per τ₁ per peer). It is bounded, ephemeral, and forms no consensus state.

EgressDirectoryEntry:
  exit_node_id      32B   node_id of the exit (verifiable by IBT)
  country_code       2B   ISO-3166-1 alpha-2, operator-declared
  capacity_class     1B   0 = best-effort, 1 = standard, 2 = high
  advertised_window u32   cached window_index at advertisement time

Invariants EgressDirectoryEntry:

  • exit_node_id is 32 B and resolves to a node present in the address manager; an entry for an unknown node is held unverified until an IBT handshake confirms the node.
  • country_code is two ASCII letters in the ISO-3166-1 alpha-2 set; any other value drops the entry.
  • capacity_class ∈ {0, 1, 2}; any other value drops the entry.
  • advertised_window lies within [known_window_index 7 × τ₁, known_window_index]; a staler value drops the entry, matching the mesh-IBT staleness bound.
  • A node retains at most MAX_DIRECTORY_ENTRIES = 4096 entries, evicting the least-recently-corroborated on overflow.
  • A directory entry authorizes no connection by itself; it ranks candidates only. The client confirms the exit by direct IBT handshake.

The directory keys exit selection; it never enters a state root. country_code is operator-declared and advisory — see Threat Model → Country attestation.


Session establishment

1. Entry selection.
   The client selects a reachable entry by Network-layer reachability sensing
   and the transport profile ladder, then completes the outer Noise_PQ XX
   session and the IBT level-3 handshake with the entry.

2. Exit selection.
   The client resolves an exit from the egress directory:
     - manual: the first directory entry whose country_code equals the chosen
       country (the entry-hop transport profile is chosen independently by the Network layer);
     - auto:   the reachable entry ranked highest by the reachability map for
       the client's vantage_class, tie-broken by feeler round-trip latency.
   Exit selection is performed by the client, never dictated by the entry.

3. Relayed connection.
   The client opens a Circuit Relay v2 transit through the entry to the chosen
   exit_node_id (Network → NAT Traversal). If the client and exit are directly
   reachable, the relay hop is skipped.

4. Inner handshake.
   Over the relayed connection the client completes an end-to-end Noise_PQ XX
   session with the exit (protocol id /montana/noise-pq-xx/1.0.0) and an IBT
   level-3 proof. The exit verifies the proof and applies its egress policy.

5. Egress.
   The client multiplexes streams over the inner session (control messages
   below). The exit opens the corresponding clearnet sockets and relays bytes
   bidirectionally until close.

On loss of the entry mid-session the client re-steers to the next corroborated entry (Network → Auto-steering) and re-establishes the relayed connection to the same exit; the chosen exit, and therefore the egress IP and country, are preserved. One active entry carries a hot reserve.


Control messages

All control and data messages travel over the inner end-to-end Noise_PQ XX AEAD stream (Network → Post-handshake AEAD framing). Each is a length-prefixed application message whose first byte is the message type. Streams are multiplexed over the inner session by the libp2p stream multiplexer (Network → Yamux, transport stack TCP → Noise_PQ XX → Yamux), which supplies per-stream flow control; each stream_id corresponds to one multiplexer stream, and a client bounds its per-stream send to the multiplexer window.

msg_type  1B   0x01 EgressAuth
               0x02 EgressOpen
               0x03 EgressOpenAck
               0x04 EgressData
               0x05 EgressClose
               0x06 EgressKeepalive
EgressAuth (0x01)  client → exit
  account_proof   variable   IBT level-3 advertisement (separator "mt-tunnel-online",
                             account keypair) as defined by the Network layer.
                             The proof binds server_node_id = exit_node_id — the inner
                             session terminates at the exit — so a proof for one exit
                             is invalid at any other node.
EgressOpen (0x02)  client → exit
  stream_id        4B   u32, client-assigned, unique within the inner session
  protocol         1B   0 = TCP, 1 = UDP
  addr_type        1B   0 = IPv4 (4B), 1 = IPv6 (16B), 2 = hostname (len-prefixed)
  dest_addr        var  per addr_type; hostname is 1B length + that many bytes
  dest_port        2B   u16 big-endian
EgressOpenAck (0x03)  exit → client
  stream_id        4B   u32, echoes EgressOpen
  status           1B   0 = open, 1 = refused by policy, 2 = unreachable,
                        3 = rate-limited
EgressData (0x04)  client ⇄ exit
  stream_id        4B   u32
  payload          var  opaque bytes for the stream (≤ 65 519, the AEAD frame
                        plaintext maximum; larger payloads are fragmented by
                        the caller across successive EgressData messages)
EgressClose (0x05)  client ⇄ exit
  stream_id        4B   u32
  reason           1B   0 = normal, 1 = error, 2 = policy
EgressKeepalive (0x06)  client ⇄ exit
  (no body) — resets the idle timer; permits uniform-framing cover on idle streams

Invariants (egress control):

  • msg_type ∈ {0x01..0x06}; any other value closes the inner session.
  • EgressAuth is the first message of the inner session; an EgressOpen before a verified EgressAuth closes the session.
  • stream_id in EgressData / EgressClose references a stream opened by a prior EgressOpen and acknowledged status = 0; an unknown stream_id drops the message.
  • protocol ∈ {0, 1}, addr_type ∈ {0, 1, 2}, status ∈ {0, 1, 2, 3}, reason ∈ {0, 1, 2}; any other value drops the message.
  • The exit honours at most MAX_STREAMS_PER_SESSION concurrent open streams; an EgressOpen beyond the cap is answered status = 3.

Exit node

An exit node is configuration-gated. When enabled, the operator declares:

  • country_code advertised in the directory;
  • an egress policy — the set of destination hosts/ports the exit forwards (default-allow or default-deny, operator's choice), and the set of accounts permitted (default: any IBT level-3 account);
  • a bandwidth tier — egress is a distinct, high-bandwidth resource class, separate from the Network-layer consensus relay (which is capped at the baseline frame rate). The exit forwards egress traffic up to an operator-configured cap per session and per node.

The exit applies its policy on each EgressOpen: a destination outside policy is answered status = 1; an account outside policy fails the IBT check at step 4 and the inner session is closed. Egress is opt-in volunteer service; the Egress layer defines no protocol-level reward to the exit operator. An incentive mechanism, if introduced, is specified separately in the monetary layer and is out of scope here.


Transport and reachability

The entry hop uses the Network-layer transport profile ladder (T0 direct, T1 TLS mimicry, T2 CDN, T3 pluggable transport, T4 mesh radio); the inner end-to-end session rides inside whichever profile the entry hop negotiated. Entry selection, auto-steering, and the hot reserve are Network-layer mechanisms (Reachability sensing and auto-steering); the Egress layer consumes them unchanged. The exit's own reachability from the entry is established by the same sensing, so the path is built only over corroborated-reachable hops.


Parameters

Parameter Value Rationale
MAX_STREAMS_PER_SESSION 256 bounds exit per-session bookkeeping; matches the per-key nonce-set bound of the Network layer
EGRESS_SESSION_IDLE_TIMEOUT 4 × τ₁ an inner session with no EgressData or EgressKeepalive within the window is closed by the exit
EGRESS_OPEN_TIMEOUT τ₁ / 2 an EgressOpen unanswered within the window is treated by the client as status = 2
MAX_DIRECTORY_ENTRIES 4096 bounds the advisory egress directory held by a node; least-recently-corroborated eviction on overflow
EGRESS_BANDWIDTH_CAP_PER_SESSION operator-configured egress high-bandwidth tier; not a consensus parameter

τ₁ is the Network-layer window unit. These parameters are local network-stack behaviour on the node's own clock and are outside the scope of consensus state.


Threat model

The trust boundary follows directly from the two-session architecture:

Party Learns Does not learn
Entry / relay the addresses of the hops it connects; that egress-class traffic flows egress control messages, destinations, payload (inner session is end-to-end)
Exit the destination hosts and payload it forwards; the client's account identity (IBT) the client's source IP (the client reaches the exit through the entry/relay)
Passive observer at the client a transport-ladder cover session to the entry destinations, payload, exit identity
Destination host the exit's egress IP the client's identity and IP

This is the trust boundary of any honest VPN exit and is stated, not eliminated.

Exit attribution (Sabotage / abuse). Traffic forwarded by an exit appears on the clearnet under the exit's egress address; abusive third-party traffic is attributable to the exit operator and may trigger blocklisting of the exit address. Closure is operational, not cryptographic: the exit's egress policy (destination allow/deny, per-account rate limits) and the operator's opt-in acceptance of jurisdictional exposure. The Egress layer does not claim to remove this risk; it confines it to operators who deliberately enable the exit role.

Auto-steering eclipse (Censor / Sybil). A hostile entry could attempt to steer an auto-selecting client toward a logging or hostile exit. Closure: exit selection is performed by the client from the corroborated reachability map (Network → Quorum and diversity, REACHABILITY_QUORUM = 3 distinct /16), and the client verifies the exit by its node_id through the end-to-end IBT handshake before any egress. A hostile entry cannot substitute an exit identity it does not hold the key for.

Country attestation (Censor / misrepresentation). country_code in the directory is operator-declared; an exit could advertise jurisdiction A while egressing from jurisdiction B. The directory value is advisory. A client requiring assurance verifies the apparent egress jurisdiction out of band — for example by retrieving its observed egress address through the established exit session and checking its geolocation — before relying on the country. The Egress layer does not bind country_code to a verifiable proof; it is a routing hint corroborated by directory quorum, not a guarantee.

Correlation at a global observer. A global passive observer correlating entry-side timing with exit-side egress is the same open metadata-correlation problem acknowledged in the Network layer; the Egress layer inherits the Network-layer mitigations (uniform framing, transport randomness) and adds no new claim.


Privacy scope

The Egress layer hides the client's source address from the destination and the destination from the entry/relay. It does not hide, from the exit, the destinations the client visits — an exit is a trusted forwarding point exactly as in any VPN. A participant requiring no trusted forwarder runs an exit on their own infrastructure; the architecture permits a participant's own node to be entry, relay, and exit simultaneously, in which case no third party forwards the traffic. The Egress layer makes no anonymity claim against an adversary controlling the chosen exit.


Conformance

A conforming implementation provides byte-exact encodings of EgressDirectoryEntry and the six control messages, the two-session establishment sequence, client-side exit selection (manual and auto), and the exit egress policy gate. Reference test vectors fix the control-message encodings and the directory-entry encoding for cross-implementation verification; the inner and outer Noise_PQ XX sessions reuse the Network-layer conformance vectors unchanged.