Transport and Information Flow
This document describes the architecture of transport, guard chains, flow budgets, receipts, and information flow in Aura. It defines the secure channel abstraction and the enforcement mechanisms that regulate message transmission. It explains how context boundaries scope capabilities and budgets.
1. Transport Abstraction
Aura provides a transport layer that delivers payload-encrypted messages between authorities. Each transport connection is represented as a SecureChannel. A secure channel binds a pair of authorities and a context identifier. A secure channel maintains isolation across contexts.
The direct TCP/WebSocket emitters are byte-delivery mechanisms, not a substitute for payload encryption. Production direct transport rejects outbound envelopes unless the envelope either carries explicit aura-payload-encryption metadata with a non-plaintext value or uses an Aura content type that is already defined as encrypted. Test, simulation, and harness transports may bypass this send-time policy so deterministic fixtures can exercise routing without provisioning channel keys.
A secure channel exposes a send operation and a receive operation. The channel manages replay protection and handles connection teardown on epoch changes. Receipt generations, AMP generations, and AEAD nonces are owner-minted and consumed once; see Ownership Model.
#![allow(unused)] fn main() { pub struct SecureChannel { pub context: ContextId, pub peer: AuthorityId, pub channel_id: Uuid, } }
This structure identifies a single secure channel. One channel exists per (ContextId, peer) pair. Channel metadata binds the channel to a specific context epoch.
2. Guard Chain
All transport sends pass through the guard chain defined in Authorization. CapGuard evaluates Biscuit capabilities and sovereign policy. FlowGuard charges the per-context flow budget and produces a receipt. JournalCoupler records the accompanying facts atomically. Each stage must succeed before the next stage executes. Guard evaluation runs synchronously over a prepared GuardSnapshot and returns EffectCommand data. An async interpreter executes those commands so guards never perform I/O directly.
3. Flow Budget and Receipts
Flow budgets limit the amount of data that an authority may send within a context. The flow budget model defines a quota for each (ContextId, peer) pair. A reservation system protects against race conditions.
Missing budget state or budget retrieval errors do not create implicit headroom. Zero limits mean no spend is available unless a future explicit typed unlimited-budget policy says otherwise, and guard-time checks must match charge-time semantics.
An authority must reserve budget before sending. A reservation locks a portion of the available budget. The actual charge occurs during the guard chain. If the guard chain succeeds, a receipt is created.
#![allow(unused)] fn main() { /// From aura-core/src/types/flow.rs pub struct Receipt { pub ctx: ContextId, pub src: AuthorityId, pub dst: AuthorityId, pub epoch: Epoch, pub cost: FlowCost, pub nonce: FlowNonce, pub prev: Hash32, pub sig: ReceiptSig, } }
This structure defines a receipt. A receipt binds a cost to a specific context and epoch. The sender signs the receipt. The nonce provides a replay identifier when checked against retained state, and the prev field chains receipts for auditing. The recipient verifies the signature. Receipts support accountability in multi-hop routing.
Receipt transcript verification and sender authentication are separate checks. A signature verified with the public key embedded in its own receipt establishes integrity under that key; it does not bind the claimed source authority or device. An ingress owner may publish verified peer identity only after resolving an expected active key from trusted local authority/device state, checking the key and epoch against that binding, and applying replay state. LAN bootstrap frames that have only a self-certified receipt remain untrusted routing input even when their bytes are intact.
3.1 Budget Epochs, Generations and Windows
Flow budget accounting reuses the AMP ratchet model (AMP §5–§8) without its key derivation. Every quantity is derived from replicated facts in the shared relational context, so no wall clock decides which budget is in force and every device of an authority converges on the same position.
- Epoch: for each context and direction (sender → receiver), the budget epoch advances only through a committed transition fact, reduced deterministically to one canonical epoch, as AMP channel epochs are.
- Generation: the receipt
nonceis the sender's budget generation within the epoch. It is derived from reduced journal state rather than a local counter, sospentfor the epoch is the generation span consumed. - Window: a checkpoint fact anchors the epoch's
base_gen. The receiver accepts a receipt only if its generation lies inside the granted window abovebase_gen. Generations below the window (replays) or above it (sends beyond the allowance) are rejected structurally. - Dual window: at an epoch boundary the receiver keeps the previous window open alongside the successor window, as AMP's alternating windows do, so receipts the sender stamped before observing the new epoch are still accepted and nothing in flight is dropped.
- Replenishment: the receiver opens the successor epoch once it has accepted half a window of receipts in the current epoch, AMP's routine spacing rule, with
base_genset to the highest accepted generation. Counting accepted receipts rather than trusting stamped generations means a sender cannot skip generations or name an unopened epoch to send more than its allowance; it tolerates losing up to half a window per epoch. A peer that stays within its window therefore keeps sending; a receiver withholds or delays the bump to throttle a peer. - Allowance: the window size resolves in priority order from a per-peer override fact, then a context policy fact, then the default (1024), as AMP's skip window does. Adjusting a peer's allowance is committing an override; an adaptive anti-spam policy writes overrides or delays bumps without changing the protocol. The sender's effective limit is the minimum of this window and the limit it derives from its Biscuit tokens and local policy.
Before any checkpoint exists for a direction, both sides use the default window at the initial epoch with base_gen = 0.
The current runtime realizes this contract with runtime-owned state rather than replicated facts. The receiver delivers each successor checkpoint to the sender as a receipted application/aura-flow-checkpoint transport message, offers it again while the sender still stamps the previous epoch, and keeps its windows in memory; after a restart it adopts the first receipt it sees from a sender as that direction's checkpoint, which resets accounting by at most one window. Receipts outside the window are dropped without a response. The sender keeps its generation and adopted limit in its local journal budget; a sender that reaches its limit fails the send locally until the checkpoint arrives.
4. Information Flow Budgets
Information flow budgets define limits on metadata leakage. Budgets exist for external leakage, neighbor leakage, and group leakage. Each protocol message carries leakage annotations. These annotations specify the cost for each leakage dimension.
Leakage budgets determine if a message can be sent. If the leakage cost exceeds the remaining budget, the message is denied. Enforcement uses padding and batching strategies. Padding hides message size. Batching hides message frequency.
#![allow(unused)] fn main() { pub struct LeakageBudget { pub external: u32, pub neighbor: u32, pub in_group: u32, } }
This structure defines the leakage budget for a message. Leakage costs reduce the corresponding budget on successful send.
5. Context Integration
Capabilities and flow budgets are scoped to a ContextId. Each secure channel associates all guard decisions with its context. A capability is valid only for the context in which it was issued. A flow budget applies only within the same context.
Derived context keys bind communication identities to the current epoch. When the account epoch changes, all context identities must refresh. All secure channels for the context must be renegotiated.
#![allow(unused)] fn main() { pub struct ChannelContext { pub context: ContextId, pub epoch: u64, pub caps: Vec<Capability>, } }
This structure defines the active context state for a channel. All guard chain checks use these values.
Bootstrap and stale-node re-entry surfaces fit this model as discovery inputs, not as transport
exceptions. Shared bootstrap contact hints, neighborhood re-entry hints, and bounded bootstrap
introductions may advertise scoped link endpoints plus expiry and replay bounds. Runtime code can
merge those records into local bootstrap selection state, but the transport layer still uses the
same guarded Establish, Move, and Hold path objects after a candidate is chosen.
6. Failure Modes and Observability
The guard chain defines three categories of failure. A denial failure occurs when capability requirements are not met. A block failure occurs when a flow budget check fails. A commit failure occurs when journal coupling fails.
Denial failures produce no observable behavior. Block failures also produce no observable behavior. Commit failures prevent sending and produce local error logs. None of these failures result in network traffic.
This design ensures that unauthorized or over-budget sends do not produce side channels.
7. Security Properties
Aura enforces no observable behavior without charge. A message cannot be sent unless flow budget is charged first. Capability gated sends ensure that each message satisfies authorization rules. Receipts provide accountability for multi-hop forwarding.
The network layer does not reveal authority structure. Context identifiers do not reveal membership. All metadata is scoped to individual relationships.
8. Secure Channel Lifecycle
Secure channels follow a lifecycle aligned with rendezvous and epoch semantics.
Establishment begins with rendezvous per Rendezvous Architecture to exchange descriptors inside the Relational Contexts journal. Each descriptor contains transport hints, a handshake PSK derived from the context key, and a punch_nonce. Once both parties receive offer/answer envelopes, they perform Noise IKpsk2 using context-derived keys and establish a QUIC or relay-backed channel bound to (ContextId, peer).
During steady state, the guard chain enforces CapGuard, FlowGuard, and JournalCoupler for every send. FlowBudget receipts created on each hop are inserted into the Relational Contexts journal so downstream peers can audit path compliance.
Bootstrap discovery does not bypass this lifecycle. Broker-backed or board-backed discovery can surface candidates, but once a candidate is selected the resulting channel or movement setup uses the same guarded transport machinery, receipt flow, and context scoping as any other path.
When the account or context epoch changes, the channel detects the mismatch, tears down the existing Noise session, and triggers rendezvous to derive fresh keys. Existing receipts are marked invalid for the new epoch, preventing replay. Channels close explicitly when contexts end or when FlowGuard hits the configured budget limit. Receipts emitted during teardown propagate through the relational context journal so guardians or auditors can verify all hops charged their budgets. Tying establishment and teardown to relational context journals ensures receipts become part of the same fact set tracked in Distributed Maintenance Architecture.
9. Privacy-by-Design Patterns
Privacy-by-design is enforced through context isolation, fixed-size envelopes, and flow budgets as defined in sections 1-7. All messages are scoped to a ContextId or RelationshipId with no cross-context routing. Capability hints are blinded before network transmission. The guard chain ensures unauthorized and over-budget sends produce no network traffic or timing side channels.
See Effects and Handlers Guide for privacy-aware implementation patterns.
10. Sync Status and Delivery Tracking
The system exposes sync status for Category A (optimistic) operations through Propagation state (Local, Syncing, Complete, Failed) and Acknowledgment records per peer. Delivery status is derived from consistency metadata, not stored directly. Read receipts are semantic (user viewed the message) and distinct from transport-level delivery acknowledgments.
Category B operations use proposal/approval state. Category C operations use ceremony completion status. Lifecycle modes (A1/A2/A3) apply within these categories: A1/A2 updates are usable immediately but provisional until A3 consensus finalization.
See Operation Categories for the full consistency metadata type definitions. See Effects and Handlers Guide for delivery tracking patterns.
10.1 Adaptive Privacy Movement
MoveEnvelope is the shared accountable movement boundary for relay traffic, retrieval traffic, held-object deposit and retrieval, accountability replies, and cover traffic where those flows use the adaptive privacy substrate. These flows do not regain separate mailbox, retrieval, relay, or cache-specific transport families.
Movement runs over an explicit path. The path may be a direct established path in passthrough mode, or an anonymous EstablishedPath in privacy mode. Move does not smuggle route setup back into the envelope.
The runtime schedules movement through three classes. Sync-blended traffic rides anti-entropy windows when deadlines allow it. Bounded-deadline replies carry accountability and control traffic that needs shorter latency. Synthetic cover fills the remaining cover floor after application traffic and sync-blended retrieval are counted.
Accountability replies share the same movement substrate, but the first deployment measures them separately. They do not reduce the synthetic cover floor. This prevents mandatory witness traffic from being mistaken for discretionary cover.
10.2 AMP Channel Epoch Data Plane
AMP message acceptance is subordinate to reducer-derived channel epoch state. The ratchet consumes the reduced control-plane view from the relational context journal; it does not decide membership truth or choose among competing successor epochs.
A received AMP message is accepted only when all of the following hold:
- the message epoch is the stable epoch or the single reducer-exposed
A2Livesuccessor epoch - the sender is a member of that exact epoch's membership commitment
- the generation is within the configured skip window or acceptance horizon
- cryptographic validation succeeds
Dual-epoch acceptance is policy-limited. Additive and non-removal transitions may permit bounded old-epoch receive overlap. Subtractive, removal, revocation, and emergency transitions require stricter old-epoch handling so removed or suspected participants cannot keep sending indefinitely while the network is slow.
Runtime ratchet derivation follows the same rule. Sends use the stable epoch
unless the reducer exposes exactly one A2Live successor, in which case sends
cut over to that successor. Receives allow stable-plus-successor overlap for
additive and ordinary non-removal transitions, reject old-epoch traffic for
subtractive and cryptoshred transitions, and allow only minimal old-epoch grace
for quarantine transitions. Emergency suspect exclusions are enforced at AMP
send boundaries and do not imply authority-root membership changes.
10.3 Emergency AMP Policies
AMP emergency transitions are control-plane epoch transitions, not informal warning messages.
EmergencyQuarantineTransition excludes the suspect from the successor epoch
once the A2 certificate makes the successor live. New application sends cut
over to the successor epoch immediately. Old-epoch receive grace is minimal and
must be explicitly authorized by the transition policy. Implementations erase
old sender keys, receiver chain keys, skipped-message key caches, staged epoch
material, and channel-adjacent access material aggressively, subject to local
retention policy.
EmergencyCryptoshredTransition is the strongest channel-scoped emergency
mode. When its successor becomes A2Live, ordinary pre-emergency readable
state is destroyed immediately according to local cryptoshredding policy. A3
finalization later durably commits the already-live successor; it does not
delay cryptoshredding.
Emergency transitions protect future traffic and reduce future at-rest exposure on honest devices. They do not retroactively protect data already seen, decrypted, or exfiltrated before cutover.
Operator diagnostics must present emergency AMP actions with that limitation: quarantine and cryptoshred reduce future exposure and local readable remnants after the reducer exposes the emergency successor, but they are not an incident response guarantee for content already copied outside honest devices. Cooldown and accusation diagnostics are generation/evidence based; wall-clock timers are operator display metadata only and are not reducer inputs.
Channel emergency facts do not automatically remove authority-root membership or recovery/governance rights. Recovery suspension, governance suspension, and durable structural removal are separate authority-scoped governance actions with their own thresholds.
11. Anti-Entropy Sync Protocol
Anti-entropy implements journal synchronization between peers. The protocol exchanges digests, plans reconciliation, and transfers operations.
11.1 Sync Phases
A sync round begins by loading the local Journal and operation log, then computing a JournalDigest for the local state. The digest is exchanged with the peer. The two digests are compared to determine whether the states are equal, whether one side is behind, or whether they have diverged. Missing operations are then pulled or pushed in batches. Applied operations are converted to a journal delta, merged with the local journal, and persisted once per round.
11.2 Digest Format
#![allow(unused)] fn main() { pub struct JournalDigest { pub operation_count: u64, pub last_epoch: Option<u64>, pub operation_hash: Hash32, pub fact_hash: Hash32, pub caps_hash: Hash32, } }
The operation_count is the number of operations in the local op log. The last_epoch is the max parent_epoch observed, or None if the log is empty. The operation_hash is computed by streaming op fingerprints in deterministic order. The fact_hash and caps_hash use canonical serialization (DAG-CBOR) then hash.
11.3 Reconciliation Actions
| Digest Comparison | Action |
|---|---|
| Equal | No-op |
| LocalBehind | Request missing ops |
| RemoteBehind | Push ops |
| Diverged | Push + pull |
Retry behavior follows AntiEntropyConfig.retry_policy with exponential backoff. Failures are reported with structured phase context attributable to a specific phase and peer.
See Choreography Development Guide for anti-entropy implementation.
11.4 Relational-Context Sync
Anti-entropy carries only AttestedOps. Committed relational facts of home, channel and DM contexts converge through relational-context sync, a membership-checked pull between the members of one context.
A member sends each peer it counts as a member of the context a context-sync summary (content type application/aura-context-sync) holding the context id and the hashes of its committed fact digests in 16 buckets. The peer identifies differing buckets, and the requester sends those buckets as pages of at most 256 digests. Each page bounds the range of facts the peer may return. Context-sync facts are home governance facts, moderation actions, chat facts (channels, messages, delivery and read state) and AMP channel membership facts. The peer serves only a requester it counts as a member: the home roster (members and moderation targets) of a home with that context, or an authoritative participant of a channel in it (AMP membership plus accepted channel invitations). It answers with the facts the requester lacks that it may serve. A moderation or membership fact is served only by its author, because a receiver requires its actor or author to be its sender. A membership event written for another participant also needs an author with standing: a join from an admitted member (the inviter of an accepted invitation), a departure (a kick) from a moderator of the context's home with the kick capability. The receiver drops one without standing and a later sync round offers it again; AMP membership reduction counts such an event only once its author is admitted, in any order. The receiver commits a delivered fact once; a synced membership fact also enters the AMP context journal.
The runtime-owned periodic sync runs the pull on PhysicalTimeEffects, coalesced per (context, peer) by the sync manager. Commit-time sends to peers are single best-effort sends that only cut latency; they are never retried, and a failed send never turns a committed action into a reported failure. Message delivery status comes from the recipient's delivery receipt, which a recipient sends when it first commits the message whether the message arrived by send or by sync. A failed commit-time send marks the message Failed; a later receipt advances it to Delivered, and a failed send never overrides a receipt.
Relational-context sync does not establish membership. A peer that does not yet count the requester as a member ignores the request, and the requester converges through another member. Held-digest sets grow with the context's history.
12. Protocol Version Negotiation
All choreographic protocols participate in version negotiation during connection establishment.
12.1 Version Handshake Flow
sequenceDiagram
participant I as Initiator
participant R as Responder
I->>R: VersionHandshakeRequest(version, min_version, capabilities, nonce)
R->>I: VersionHandshakeResponse(Accepted/Rejected)
alt Compatible
Note over I,R: Use negotiated version
else Incompatible
Note over I,R: Disconnect
end
See Choreography Development Guide for version handshake implementation.
12.2 Handshake Outcomes
| Outcome | Response Contents |
|---|---|
| Compatible | negotiated_version (min of both peers), shared capabilities |
| Incompatible | reason, peer version, optional upgrade_url |
12.3 Protocol Capabilities
| Capability | Min Version | Description |
|---|---|---|
ceremony_supersession | 1.0.0 | Ceremony replacement tracking |
version_handshake | 1.0.0 | Protocol version negotiation |
fact_journal | 1.0.0 | Fact-based journal sync |
13. Summary
The transport, guard chain, and information flow architecture enforces strict control over message transmission. Secure channels bind communication to contexts. Guard chains enforce authorization, budget, and journal updates. Flow budgets and receipts regulate data usage. Leakage budgets reduce metadata exposure. Privacy-by-design patterns ensure minimal metadata exposure and context isolation. All operations remain private to the context and reveal no structural information.
Sync status and delivery tracking provide user visibility into Category A operation propagation. Anti-entropy provides the underlying sync mechanism with digest-based reconciliation. Version negotiation ensures protocol compatibility across peers. Delivery receipts enable message read status for enhanced UX.
Generation interval arithmetic
Receipt-generation allowance coordinates and physical-time coordinates are distinct domains. Receipt windows contain no physical timestamps and do not renew according to elapsed time. Their checked half-open intervals require a representable exclusive endpoint: base u64::MAX with extent one is invalid, and endpoint overflow is rejected rather than wrapped or truncated. Exhaustion requires an explicit domain outcome; it does not authorize implicit renewal. Empty generation allowances admit no receipts. Current/previous epoch acceptance, authenticated checkpoint admission, nonce replay protection and authorized checked epoch progression remain flow-domain contracts. Serialized arithmetic intervals do not provide admission authority. Fixed physical execution windows retain their original deadline and do not acquire generation rollover semantics.
Receive readiness
Transport receive readiness is a local observation of the original provider or canonical runtime inbox. It consumes no envelope and supplies no authentication, protocol completion or durable acknowledgment. Each provider registers its arrival event before checking its own queue; a stateless provider explicitly refuses unsupported readiness. A required receive retains its original provider inventory and fixed operation endpoint, including readiness and provider errors. An unrelated session's retained frame cannot authorize another session or cause that session to spin. Arrival notifications replace timed polling; they do not advance physical time or allocate a new execution window.