18. Security Considerations — MMP Specification

18. Security Considerations

MMP is designed for autonomous agents that share cognitive state. Security must address both traditional protocol threats (spoofing, eavesdropping, injection) and novel threats specific to cognitive coupling (state poisoning, drift manipulation, lineage forgery).

18.1 What Crosses the Mesh

Data type Crosses mesh Sensitivity
L0 Events (raw sensor, interaction) Never High — MUST NOT leave node
L1 CMBs (structured, 7 categories) Via cmb, gated by SVAF Medium — contains semantic category text
L2 Hidden state (h₁, h₂) Never (§2.7) N/A — strictly local; MUST NOT cross the wire
Mood (valence, arousal) Via cmb (CMB mood category), or a mood frame (text only) sealed in control-encrypted on a Core Secure session Medium — affective state, extracted from CMBs per Section 9.3; a mood frame is never stored, relayed or remixed
Messages (direct text) Via message frame High — free-form text content

Hidden state vectors (h₁, h₂) are compact, opaque neural representations encoding cognitive patterns, not raw data. Because sufficiently advanced analysis could reconstruct aspects of the input, hidden state is a privacy surface — which is precisely why it never crosses the wire (Section 2.7). It is strictly local and confidential by construction; only CMBs — deliberately scoped, signed statements — propagate.

18.2 Transport Security

MMP does not mandate transport encryption in the base specification. Implementations SHOULD apply:

Transport Encryption Notes
TCP (LAN) TLS 1.3 RECOMMENDED for production. On trusted LANs, MAY operate without TLS.
WebSocket (relay) WSS (TLS) MUST for internet relay. Plaintext WS MUST NOT be used over the internet.
IPC (local) None required Unix domain socket — OS-level process isolation is sufficient.
APNs Push (wake) Apple TLS Handled by Apple. Implementation uses APNs certificate.

18.2.1 End-to-End CMB Encryption

WSS (TLS) encrypts the transport — it protects from eavesdroppers on the wire. But the relay operator can still read the JSON payload inside the TLS tunnel. For cmb frames containing CMBs, this means the relay sees all 7 CAT7 category texts in plaintext.

In the Core Secure profile, implementations MUST encrypt CAT7 categories and application bytes end to end on every transport. A relay forwards an opaque envelope and MUST NOT learn protected content.

Layer What it protects What it doesn’t protect
WSS (TLS)Wire eavesdroppersRelay operator sees plaintext JSON
E2E CMB encryptionRelay operator, intermediariesOnly the intended peer can decrypt category text

The v2.0 Core Secure suite is X25519 key agreement, HKDF-SHA256 derivation and IETF ChaCha20-Poly1305 authenticated encryption. Ed25519 identity proofs and X25519 key confirmations bind both public keys to the authenticated handshake transcript (§5.2).

{
  "type": "cmb-encrypted",
  "protocolVersion": "2.0",
  "suite": "X25519-HKDF-SHA256-ChaCha20-Poly1305",
  "sessionId": "<32 lowercase hex>",
  "sequence": "0",
  "direction": "client-to-server",
  "metadata": { "key": "cmb-…", "assertionId": "asrt-…",
                "createdByNodeId": "<uuid>", "room": "team", "to": "<uuid>" },
  "sealed": "<unpadded base64url ciphertext || 16-byte tag>"
}

Each direction has a distinct HKDF-derived 32-byte traffic key. The first sequence is zero; the nonce is that sequence encoded as an unsigned 96-bit big-endian integer. An ordered receiver MUST require the exact next sequence and reject replay, rollback and gaps. The receive sequence advances only after the AEAD has authenticated the frame at the expected sequence: a frame that fails authentication MUST be discarded without changing any session state, so that one forged frame carrying the right sequence number cannot desynchronise the session. A sequence below the next expected value is a replay or rollback and is never processed: on every transport the receiver discards the frame and keeps the session, because a replayed frame changes nothing and closing on one would hand the session to whoever can replay frames, a relay above all. A sequence above the next expected value whose frame authenticates under its own sequence is a gap: the receiver MUST close the session, and SHOULD first send a sealed error 1010 SESSION_CLOSED, and the peers re-handshake (§5.2.2). A receiver MUST NOT stall waiting for missing frames, which a relay that dropped them never retransmits.

The protected plaintext contains categories and decoded application bytes. Associated data binds protocol version, session, direction, sequence, cognition key, assertion identity, author nodeId, room and recipient. After decrypting, the receiver reconstructs the logical two-section record and follows §8.8.5 verification order. Exact outputs are published in the E2E vector. The recipient in the associated data is metadata.to, entering as lp("") when it is null, exactly as in the signature payload (§8.8.4). An intermediary therefore cannot turn a room-bound record into a directed one, or redirect a directed one, without the frame failing to open; and the receiver takes the record’s binding from that authenticated field, never from the relay envelope that carried the frame (§9.2.2).

When metadata.application is null, the protected plaintext MUST omit applicationData entirely. A present application whose decoded data is zero bytes instead carries applicationData: "". The two states are distinct and MUST NOT be collapsed. Both byte shapes are pinned by the E2E vector.

Sealed control frames. Every peer-scope frame of a CONNECTED Core Secure session that is not a record and not liveness travels in a control-encrypted envelope (§7.1). It uses the same suite, session and directional traffic keys as cmb-encrypted; the plaintext is the inner frame itself, and the envelope carries no clear metadata beyond what the AEAD needs:

{
  "type": "control-encrypted",
  "protocolVersion": "2.0",
  "suite": "X25519-HKDF-SHA256-ChaCha20-Poly1305",
  "sessionId": "<32 lowercase hex>",
  "sequence": "7",
  "direction": "server-to-client",
  "sealed": "<unpadded base64url ciphertext || 16-byte tag>"
}

plaintext = UTF8(minified JSON of the inner frame, e.g. { "type": "mood", ... })
aad       = UTF8("mmp-aead-control-v2
") || lp("2.0") || lp(sessionId) ||
            lp(direction) || lp(sequence)
key, nonce: the session's traffic key for direction; sequence as for cmb-encrypted
  • —One sequence per direction. cmb-encrypted and control-encrypted frames sent in one direction of one session draw their sequence numbers from one counter, so that no traffic key ever seals two frames under one nonce. The receiver applies the ordering rules above to the merged stream.
  • —Domain separation. The associated data of the two envelopes begins with different labels (mmp-aead-aad-v2 for records, mmp-aead-control-v2 here), so neither can be opened as the other. Exact outputs for four inner frames, and an authentic envelope whose inner frame is refused, are published in the control-encrypted vector, on the session of the handshake vector.
  • —After opening. A frame that opens has taken its place in the sequence: the receiver advances its direction’s counter first. It then parses the plaintext as one JSON frame, under the same size limits as a frame in clear, refuses an inner type that §7.1 forbids, validates the inner frame against its schema, and handles it as if it had arrived on the session in clear — attributed to the session’s proven peer. Refusing the inner frame changes nothing else: the session stays up and the next frame is judged at the next position. The same holds for a cmb-encrypted frame whose record is then refused.
  • —Records stay in their own envelope. No control frame carries a record. A record returned for a cmb-fetch travels as its own cmb-encrypted frame, so its associated data binds that record’s cognition key, assertion identity, author, room and recipient, exactly as for any record. The sealed cmb-fetch-result carries only the request’s correlation id and the lists of keys returned and keys not found (below).
  • —Seal only what the session may carry. A sender MUST NOT seal into a session a record whose signed room differs from the session’s room, or whose metadata.to names a node other than the session’s peer, whatever path offered it: a fetch answer, a replay, a queued or forwarded frame, or the sender’s own publishing. The receiver would refuse it (§8.8.5 step 7, §5.8, §9.2.2), but only after its content was disclosed.

Fetch results. A node answering a cmb-fetch on a Core Secure session MUST send each record it returns as its own cmb-encrypted frame, and then one cmb-fetch-result inside control-encrypted:

{
  "type": "cmb-fetch-result",
  "reqId": "<the request's reqId>",
  "returned": ["cmb-<64 lowercase hex>"],
  "missing": []
}
  • —reqId echoes the request. Every key the request asked for appears exactly once, in returned or in missing.
  • —The records come first. A responder MUST send every record a result lists as returned before the result itself. Both envelopes draw on the session’s one sequence per direction, so when the result arrives the requester has already received, in order, every record it lists; a listed record that did not arrive was not sent.
  • —A responder MUST NOT return a record whose signed room differs from the session’s room, or whose metadata.to names a node other than the requester. It lists such a key as missing, as it does a key it does not hold or declines to disclose.
  • —A per-session byte budget. A responder MUST bound the record bytes it holds queued for fetch answers on one session (RECOMMENDED: 4 MiB), and never less than MAX_RECORD_BYTES (§8.8.6), so that one maximal record can always be served. A key whose record would exceed the budget is listed in missing, never queued; the requester may ask for it again later. A responder SHOULD also bound the total across sessions. Without such a budget, one 900 KB record requested 150 times was measured to hold 99 MiB in the sender’s buffers.
  • —The requester MUST recompute each returned record’s cognition key (§8.2.1) and match it to its request by that key and the responder. A content address binds the categories only, not the author or the metadata (§8.8.2), so a match proves only the categories: the requester MAY use them to check lineage (§15.8), but it MUST pass every check of §8.8.5 before it attributes the record to an author, delivers it to its application or admits it. A record whose author key it cannot resolve stays unattributed. Whether it admits the record is its own decision (§9.2).

18.3 Node Identity & Authentication

Node identity is a UUID bound to an Ed25519 key through the authenticated transcript in §5.2. An X25519 session key is separately generated but proven in the same transcript.

  • —Each node MUST generate an Ed25519 keypair at first launch and persist it alongside the nodeId.
  • —Discovery records are untrusted hints. A peer MUST NOT pin their identity or E2E key from DNS-SD, relay discovery or an unproven hello.
  • —Both nonces, nodeIds, keys, room, protocol version, implementation identifiers and extension negotiation MUST enter the signed transcript.
  • —Core Secure MUST require both the Ed25519 transcript proof and X25519/HKDF key confirmation. Network isolation is not identity authentication.
  • —A nodeId stays bound to the first key a receiver binds it to (§3.4). A different key, however well proven, is an identity conflict that the receiver refuses and reports; it is never a re-binding. First contact with no anchor, grant or out-of-band pin is therefore trust on first proven use, and an operator who needs more pins the key out of band.

18.3.1 CMB Signature Verification

Transport identity (above) authenticates the connection; CMB signatures authenticate each record assertion end-to-end. Every Core Secure CMB MUST be signed by its author using the Ed25519 identity proven in the handshake or a verifiable author key-binding chain.

  • —The byte-exact mmp-sig-v2.0 payload is specified only in §8.8.4. It binds the cognition address, address scheme, author nodeId and label, signed author time, room, recipient, lineage commitments and application commitment.
  • —The receiver MUST resolve the author key by createdByNodeId, never createdBy.
  • —Before admission or application exposure, the receiver follows all checks in §8.8.5, including record address, assertion identity, signature and audience.
  • —An unsigned, legacy-suite or unverifiable record MUST NOT enter Core Secure. It may be quarantined under an explicitly selected Legacy Import profile; no automatic downgrade is permitted.

18.3.2 Authority Statement Signatures

Grants, revokes and endorsements (§6.6) are not CMBs and do not use mmp-sig-v2.0. Each is signed with pure Ed25519 over its own mmp-authority-v1 payload (§6.6.3), and is identified by the SHA-256 of that payload, never by its signature.

One verification rule. RFC 8032 lets verifiers differ: in the equation they check, and in whether they accept non-canonical encodings and points of small order. Two nodes that verify differently hold different valid sets from the same statements, so they resolve different authority and never converge. Every node MUST therefore verify an authority statement’s signatures by this rule alone. A signature, 64 bytes R ‖ S, by a public key A of 32 bytes over a message M is valid if and only if all five hold:

  1. A is a canonical encoding of a curve point: its y is less than p = 2255 − 19, it decodes to a point, and when x = 0 the sign bit is clear (RFC 8032 §5.1.3).
  2. A has prime order: [L]A is the identity and A is not, where L = 2252 + 27742317777372353535851937790883648493. This excludes the identity, the other points of small order and every point of mixed order.
  3. R is likewise a canonical encoding of a point of prime order.
  4. S, read little-endian, is less than L.
  5. [S]B = R + [k]A as points, where k = SHA-512(R ‖ A ‖ M) mod L, hashed over the bytes as given. This is the cofactorless equation of RFC 8032 §5.1.7.

With A and R of prime order, [8]([S]B − R − [k]A) is the identity exactly when [S]B − R − [k]A is. The cofactored equation therefore gives the same answer, and a library that uses either equation agrees once rules 1 to 4 are checked. Those four rules are where libraries differ. The Ed25519 edge-case vector holds the twelve cases of Taming the many EdDSAs (Chalkias, Garillot and Nikolaenko, 2020). It adds the identity key, a mixed-order key, and, under a prime-order key, an identity R, a pure small-order R (of order 8 and of order 2), a mixed-order R and a non-canonical R, as well as an unreduced S and an honest case. It also shows, for each case, what the two equations give when the pre-checks are skipped. Only the honest case is valid.

On a cofactorless library (informative). A cofactorless verifier that compares R by its bytes, as OpenSSL does behind Node’s crypto.verify, needs rules 1, 2 and 4 checked first. It also needs one more check: that R is not the identity’s encoding, 01 followed by 31 zero bytes. If such a library then accepts, R’s bytes are the canonical encoding of [S]B − [k]A. That point lies in the prime-order subgroup, because B and A do, and it is not the identity, so R meets rule 3. Rules 1 and 2 cost one scalar multiplication per key, and a node can cache the result per key. The reference construction (scripts/mmp/lib.mjs) works this way, and the verifier checks it against the rule computed directly on every edge case.

  • —The verifying key of a non-anchor statement is the subject key of the grant it names in authorisedBy. A receiver MUST NOT take it from its key registry, from the delivering session or from the statement’s own signature entry alone.
  • —An anchor-level statement needs valid signatures by the pinned threshold of distinct anchor keys (§6.6.1). The keys are pinned out of band and never learned from the wire. No two entries of one statement share a key: a repeated key makes the statement malformed, refused as shape before any signature is checked (§6.6.3, rule 1), so one copy cannot buy repeated checks under a pinned key.
  • —A grant whose subject key fails rule 1 or 2 is not well formed (§6.6.3). No grant can therefore name a key, such as the identity, under which anyone could sign anything.
  • —Because the id excludes the signature, a hedged signer’s different valid signature over the same payload is the same statement (§17.4). The authority vector pins payloads, ids and roots; its signatures are for verification only.

18.4 Cognitive Threats

MMP introduces threats unique to cognitive coupling that traditional protocol security does not address:

Cognitive poisoning

A malicious node sends crafted CMBs designed to skew the receiver’s cognitive state toward a desired outcome. (Hidden vectors cannot be injected — they never cross the wire, §2.7 — so the only attack surface is CMB content.)

MITIGATION SVAF per-category evaluation (Layer 4) judges each CMB on content before it is admitted. Drift-bounded influence (Section 10) limits any peer to α < 1, so a peer influences but never overrides. Peer-level disconnection at Layer 2 provides immediate escape.

Lineage forgery

A node claims false lineage — listing ancestors it never actually remixed — to inflate its remix count or inject itself into chains.

MITIGATION CMB keys are cmb- content addresses (§8.8.2). The corrected signature (§8.8.4) binds createdByNodeId, audience, lineage commitments and application bytes. A receiver resolves the author key by nodeId and rejects a forged or tampered assertion.

Fake outcome attestation (grounding abuse)

A node emits intent="ground" CMBs (§6.7) with fabricated "verified:" outcomes against its own cognition to steer receivers’ evidence-based validation — or griefs with "failed:" attestations to un-ground cognition a node with validator role or above verified (latest-observation-wins, §6.7).

MITIGATION An outcome is an attestation, never a fact (§6.7): it advances no lifecycle by itself, and elevation is an explicit act under validator-or-above authority that SHOULD weigh the grounding author’s resolved authority (§6.5–§6.6). Groundedness is receiver-relative — only attestations the receiver’s own SVAF admitted count — and ordering uses receiver-local stored time, so a backdated createdTimestamp cannot game latest-wins. A below-validator "failed:" MUST NOT un-ground a validator-or-above "verified:" (§6.7 hard-gate reading) — a tier gate, not a soft weighted vote, since sheer low-authority volume defeats a weighted vote but not the gate; within a tier, latest-wins still surfaces a genuine same-authority regression.

Authority backdating, flooding and blow-up

A compromised or removed authority holder signs revokes or attestations dated inside the time it was trusted, floods statements to push honest ones out of a store, or crafts revoke patterns that are expensive to resolve.

MITIGATION Authority carries no time (§6.6): a statement counts only while its signer’s grant is in force, whatever time it claims, and a removed signer’s dependents are dead. Quotas are per signer and per grant, keep removals first, and never let one signer displace another (§6.6.6). Resolution is linear in the statements held and never recurses (§6.6.4). A rescue never reconnects what a quota dropped, and the rescuer keeps what it rescues against its own quotas, so a compromised holder cannot escape the bound of §6.6.6. Every node verifies by one Ed25519 rule (§18.3.2), so no signer can craft a statement that some nodes count and others reject. Agreed outcomes are decided once by their environment and bound to an authority root (§6.6.10).

Drift manipulation

A node gradually sends benign, redundant CMBs to lower its peer drift with a target, then suddenly sends adversarial content once coupling is accepted.

MITIGATION SVAF per-category evaluation (Layer 4) operates on content, not just drift. Even with low peer drift, adversarial CMB content is evaluated per category and rejected if category drift is high.

Sybil attack

An attacker creates multiple fake nodes to amplify influence in peer-influence weighting.

MITIGATION Keypairs are free to generate, so identity alone does not limit Sybil creation. Receiver-local drift/recency weighting reduces but does not prove Sybil resistance. Authority-bearing actions require an in-force grant under the pinned anchor (§6.5–§6.6), and a grant holder can only add authority holders within its quota and the depth cap (§6.6.6); operators SHOULD rate-limit new identities and seed trusted anchors. Quantitative Sybil bounds are an open research claim unless demonstrated by a named profile.

Cold-start capture

An attacker floods a freshly joined node before it forms category anchors. Category drift is then unevaluable, so content cannot yet be trimmed against local memory.

MITIGATION The baseline performs temporal-gated bootstrap: category verdicts are silent, but a stale signal can still be refused by signed author time. Operators SHOULD seed trusted anchors before open traffic, surface bootstrap state, and defer authority-bearing use of early anchors. Honest anchoring remains an open problem.

18.5 Privacy & Deployment Recommendations

Metadata exposure. The Core Secure envelope leaves only the routing and verification metadata required by its schema in cleartext and authenticates it as AEAD associated data. CAT7 categories, including mood text, valence and arousal, and application bytes are encrypted. A relay can still observe endpoints, room/routing identifiers, record and assertion identifiers, sizes, timing and traffic volume. MMP v2.0 does not provide traffic-analysis resistance.

MMP is designed for privacy by default — L0 data never leaves the node, hidden states are opaque, and SVAF gates what enters. For domains with heightened privacy or IP concerns, the following deployment model is RECOMMENDED:

LAN Mesh with Controlled LLM

For enterprise, healthcare, legal, or any domain where data sovereignty matters: deploy the mesh on a local network with no relay to the internet. Run a controlled, in-house LLM (self-hosted or on-premise) for the Mesh Cognition reasoning step (Layer 7). No data leaves the LAN. No cloud LLM sees the remix subgraph.

  • •Discovery via Bonjour on the local network — no DNS queries leave the LAN
  • •TCP transport with optional TLS — all traffic stays on-premise
  • •In-house LLM (e.g., self-hosted Llama, Mistral, or Claude via API with data residency) for Layer 7 reasoning
  • •No relay node needed — all agents on the same network
  • •CMBs, hidden states, and remix subgraphs never leave the controlled environment

Additional privacy considerations:

  • —Error frames MUST NOT contain sensitive information. The ancestors field is for debugging, not for conveying user data.
  • —Wake channels expose push tokens to peers. Implementations SHOULD restrict wake channel gossip to trusted relays only.
  • —Implementations targeting GDPR, HIPAA, or similar regulatory frameworks SHOULD treat CMB category text as personal data and apply appropriate retention and deletion policies at the application layer.

18.6 Regulatory Compliance & Audit Trail

CMB immutability and lineage create a tamper-evident audit trail within the signed, retained graph — tamper-evident, not tamper-proof: modification of any retained block is detectable via content addressing and signatures; completeness of the underlying store is not itself checkpointed (retention §6.3 may purge, and unsigned blocks weaken the guarantee, §18.3.1). Every observation, every remix, every decision is traceable through the DAG:

  • —Who — metadata.createdBy names the agent, while metadata.createdByNodeId binds it to the signing identity.
  • —When — metadata.createdTimestamp records the author-asserted millisecond timestamp.
  • —What — the 7 CAT7 categories capture the full semantic content of the observation.
  • —Why — metadata.lineage.parents shows what was directly remixed. Following the signed parent links traces the full decision chain.
  • —How — metadata.lineage.method records the evaluation method (e.g., SVAF-v2).

Because CMBs are immutable, the audit trail cannot be retroactively altered. A CMB once created is never modified — any action produces a new CMB with lineage pointing back. The complete history is the graph itself.

Financial & Regulated Domains

For financial services, healthcare, and other regulated industries, the CMB remix chain provides the traceability that regulators require:

  • •Every trading signal, risk assessment, or compliance decision is a CMB with full provenance
  • •Regulators can trace any decision backward through the remix chain to its originating observations
  • •The detail field provides the complete chain without requiring graph traversal — O(1) lookup
  • •Immutability guarantees that the audit trail was not modified after the fact
  • •Combined with the LAN + in-house LLM deployment (Section 18.5), all data stays on-premise and under organisational control

18.7 Data Quality & Encoding Trade-offs

CMB quality depends on category extraction accuracy. The protocol does not extract categories — agents do. Each agent’s LLM (or structured-data mapper) decomposes observations into CAT7 categories. If extraction is poor, downstream evaluation inherits that error. MMP provides three layers of defense, but none eliminates the need for quality extraction at the source.

Layer Defense Limitation
Context Encoder Maps category text to vectors for drift comparison. Quality directly bounds SVAF quality. N-gram hashing: paraphrases score 0.31 cosine similarity (poor). Semantic embeddings: 0.69 (good). Implementations SHOULD use semantic embeddings for production deployment.
SVAF heuristic Per-category cosine drift against local memory anchors with temporal decay — misaligned categories are rejected Catches drift from the agent’s own state, not absolute quality. A consistently poor extractor will pass its own drift checks
Neural SVAF (research variant) A trained evaluator studied in the SVAF paper (§21) learned per-category gate values — mood highest (0.50), perspective lowest (0.06) Not deployed — the heuristic above is the production evaluator; the research result informs its design

Per-category evaluation quality is bounded by encoder quality, not model capacity. Production deployment revealed that n-gram encoding (character trigrams + word bigrams) produces 0.31 cosine similarity for paraphrases — SVAF cannot distinguish “submit IETF draft today” from “IETF submission, zero blockers, execute now” because the encoder represents them as distant vectors. Replacing n-gram with semantic embeddings (all-MiniLM-L6-v2, 384-dim) raises paraphrase similarity to 0.69 — a 2.2× improvement — while preserving topic separation (different topics: 0.03). Implementations SHOULD use semantic embeddings for SVAF evaluation. N-gram encoding is suitable only for prototyping or resource-constrained environments where the quality trade-off is acceptable.

Implementations targeting domains where category extraction quality is critical (healthcare, legal, finance) SHOULD validate extraction output before calling remember(). Strategies include:

  • —Schema validation — reject CMBs with empty or defaulted categories before they enter the mesh
  • —Confidence thresholds — the LLM can assign a confidence score to its extraction; low-confidence CMBs can be withheld
  • —Lineage feedback — CMBs that get remixed by other agents (have descendants in the DAG) signal high quality; CMBs that expire without children signal noise. This feedback loop lets the mesh itself shape extraction quality over time
  • —Semantic embedding encoder — implementations SHOULD use a semantic embedding model (e.g. all-MiniLM-L6-v2) for SVAF drift computation. The evaluation pipeline is encoder-agnostic — any function that maps text to unit-normalised vectors works. N-gram encoding MAY be used as a zero-dependency fallback.