Specification §12

Security architecture and trust boundaries.

The properties claimed here are architectural. The encryption is not FrogNet’s. The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as described in RFC 2119.

FrogNet Specification — Draft 0.9, revision 2026-08-29. Cite a conformance claim against this revision, not against a section number alone.

1. Position

Croakus: §35, §36, §37, §38

FrogNet implements no cryptography of its own. It uses facilities the operating system and other software provide — WireGuard, TLS, OpenSSL, HMAC-SHA-256 for authentication and integrity. This is a design boundary, not an omission: it is what makes encryption a decision about bearers the operator controls rather than a change to the fabric.

The properties this section claims are architectural — the absent surface, the proximity requirement, the reference-only wire. Each rests on mechanism specified elsewhere in this document. An implementation MUST NOT present the available encryption as the primary security property, because the architectural properties hold whether or not a byte is encrypted, and the encryption is not FrogNet's.

2. Identity and authentication

Each node holds a permanent identity and a keypair set at install (§3.2). Peers authenticate by key. There is no certificate authority, no enrolment server for trust, and no third party in the authentication path.

The SAME identifier is a keyed authentication tag — HMAC-SHA-256 over a shared secret, truncated (§11.9). It proves that a party holding the secret asserted this response for this request. It conceals nothing and encrypts nothing. An implementation MUST NOT operate without a secret in place: with the compiled-in default the tag is forgeable.

3. The absent surface

A node MUST NOT expose an internet-reachable application endpoint. Fabric traffic is captured on the node and converges on one internal seam, which is the defined place for an operator to add encryption covering every bearer.

Where a process must accept input from the public internet, it SHOULD be isolated behind a one-way file spool: the public tier holds no credential and can only write a request file; a separate watcher with no network address validates against an allow-list and performs the operation. The property being bought is that the internet-facing tier has nothing worth taking and no way to act.

4. The wire carries references, not messages

After the first exchange of a structure, the wire carries verdicts against a template, and the template lives in each node's local cache — learned once from that first FULL and never re-sent (§11.8, §11.14).

A capture is therefore a stream of opcodes, sequence numbers, and changed values measured against a structure the observer does not hold:

captured mid-conversation:

    opcode RESP_DIFF   seq 42
    payload  <field 3 -> 54.6>  <field 7 -> 1719...>

without the template, held only in each node's cache:

    field 3 of WHAT?   field 7 of WHAT?
    names? units? shape?
    -> two numbers and nowhere to put them

The meaning is in the cache, not on the wire. It is the same fact that makes the wire thin, read as a security property: the wire is thin because it says so little on its own. A capture also matches no catalogued signature, because there is no envelope announcing what it carries — the envelope was agreed once and left on both machines.

4.1 The honest boundary

This is encoding, not encryption, and an implementation MUST state it as such. An observer present from the first FULL, capturing the conversation from its start, learns the template in the same act the endpoints do and can follow the differences from there.

What reference-diffing provides is precise and bounded: it raises the cost of a full capture and guts the value of a partial one. It does not by itself make traffic unreadable to a patient listener who saw the beginning, and the design does not ask it to. Traffic crossing anything the operator does not own crosses a WireGuard bearer, and a listener there gets no capture at all. Two layers: the semantic wire is why a late or partial observer learns nothing useful; the bearer is why there is nothing to observe.

5. Encryption is a dial

Because FrogNet contains no cipher, adding encryption is a decision about bearers rather than a change to the fabric. Put a WireGuard bearer under a link and that link is encrypted end to end; put one under every link and nothing crosses in the clear. In both cases the fabric above does not change by a line.

Between sites it is already present: cross-internet tunnels are WireGuard by default (§7). On a local wire the operator owns, the choice is theirs — a shared building, a hostile RF environment, or a policy requirement are all reasons to put a bearer on that wire too, or to layer a cipher on the payload. The architecture is indifferent to which, because it routes over whatever is laid beneath it (§18).

6. Trust boundaries

TrustedNot trusted
The hardwareThe broker
The node keysAny third party
The chosen federation peersAny transit path

The broker MUST NOT hold a node credential or a pond secret, MUST NOT run any of the semantic stack, and is not a member of any pond. It does, by construction, hold the tunnel credentials for both sides and terminate both tunnels (§7.1).

Compromise of the broker therefore yields the inter-site data path in plaintext at IP level, not merely ciphertext metadata: addresses, ports, timing, volumes, and the bytes. Earlier statements that it yields transit position only are superseded.

What it does not yield is the meaning of that traffic without further work, and the ability to forge the semantic layer:

An owned broker gainsAn owned broker does not gain
The inter-site bytes, in the clearThe templates those bytes are diffed against, unless it observed from the first exchange of each structure (§12.4.1)
Read, drop, delay and inject at IP levelThe ability to mint a SAME tag a member will accept — the secret is a pond member’s and the broker is not one (§12.2)
Full traffic analysis of which sites talk to whichAny tuple, role, or node identity, none of which is placed there

An implementation MUST NOT place a node credential, a tuple, or a role on the broker to simplify rendezvous; every such placement converts a transit point into a member and removes the one boundary it is still outside.

7. Remaining exposure

Stated plainly rather than minimised. Each of these is real and none is closed by anything in this specification.

ExposureRequires
Radio proximity on a plaintext bearerBeing physically near the RF
Physical or Wi-Fi access to a nodeBeing near the wire and holding a token
Path observation of a live sessionPresence from the first exchange (§12.4.1)
An owned broker on the inter-site pathNothing further — it is already inside the tunnel boundary (§12.6). Confidentiality across the seam MUST be supplied above the tunnel if it is required.
A compromised member nodeYields what that node was entitled to see, and no more

The last is a consequence of the memory model rather than a defect in it: a member reads the store, and a compromised member reads what a member reads. There is no per-value access control in FrogNet Memory (§17.5), and an implementation MUST NOT imply one exists.

8. Non-goals

FrogNet provides no confidentiality of its own — the bearer provides it, and across sites the bearer terminates at the broker rather than at the far endpoint (§7.1). No certificate authority, no key escrow, no revocation infrastructure. No per-value or per-caller authorisation in the store. No audit log: the store holds current state, not history (§2c). No claim that semantic encoding is a cipher, and no claim of a cryptographic classification that has not been issued.

9. References

Specification §2, §3.2, §7.7, §9, §11.9, §11a, §17, §18. Source: core/semcache_id.py, core/frognet_secret.py, internet_tunnels_v3/wg.py. Build manual: Croakus §35, §36, §37, §38.