-
Notifications
You must be signed in to change notification settings - Fork 1
Wire Format Reference
The original VIRP wire format. Signs the payload and core metadata.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Version | Type | Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Node ID |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Channel | Tier | Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Timestamp (nanoseconds) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| HMAC-SHA256 (32 bytes) |
| |
| |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Trust guarantee (v1): Payload authentic — the AI cannot fabricate what it saw.
Version 2 extends the HMAC boundary to include session context, device identity, and command identity.
typedef struct {
uint8_t version; /* VIRP_VERSION_2 = 2 */
uint8_t channel; /* VIRP_CHANNEL_OBS / INTENT */
uint8_t tier; /* GREEN / YELLOW / RED / BLACK */
uint8_t _reserved; /* must be zero */
uint64_t node_id; /* stable O-Node identity */
uint64_t timestamp_ns; /* nanoseconds since Unix epoch */
uint64_t seq_num; /* monotonically increasing */
uint8_t session_id[16]; /* from SESSION_BIND */
uint64_t device_id; /* stable device UUID */
uint8_t command_hash[32]; /* SHA-256 of canonical command */
uint32_t payload_len; /* bytes of observation payload */
} virp_obs_header_v2_t;Trust guarantee (v2): Payload + context authentic — the AI cannot fabricate the source, session, or command.
| Version | What Is Signed | What Can Be Proven |
|---|---|---|
| v1 | payload + core header | This payload is authentic |
| v2 | payload + core header + session_id + device_id + command_hash | This exact device, in this exact session, responding to this exact command, produced this payload |
A valid v2 HMAC is a cryptographic commitment to all of the following simultaneously:
node_id — which O-Node collected it
session_id — which negotiated session it belongs to
device_id — which device was queried
command_hash — which exact command was executed
timestamp_ns — when it was collected
seq_num — its position in the chain (gaps detectable)
payload — what the device returned
If any field is altered after signing, HMAC verification fails. There is no way to reassign a valid observation to a different device, command, or session.
HMAC_SHA256(
session_key, /* derived per-session key */
(uint8_t *)&hdr, /* sizeof(virp_obs_header_v2_t) */
payload, /* raw device output */
payload_len,
signature_out /* 32 bytes */
);Note: session_key is used — not the master observation key. The master key derives the session key at handshake time via HKDF and never directly signs a runtime observation.
command_hash = SHA-256(canonical_command_string)
Canonicalization rules (applied in order):
| Step | Rule |
|---|---|
| 1 | Trim leading and trailing whitespace |
| 2 | Collapse repeated internal spaces to single space |
| 3 | Normalize line endings to \n
|
| 4 | Strip CLI prompts and transport-specific wrappers |
Example:
Input: " show ip bgp summary\r\n"
Output: "show ip bgp summary"
Hash: SHA-256("show ip bgp summary") = 7c2b4d3a...
The same logical command always produces the same hash regardless of how whitespace or line endings vary between vendors or transport layers.
device_id is a stable uint64_t UUID assigned at device onboarding and stored in devices.json.
Rules:
- Device display names and hostnames MUST NOT be used as
device_id - Renaming a device MUST NOT change its
device_id -
device_idis assigned once at onboarding and never changes
This ensures the cryptographic record remains stable across configuration changes, hostname updates, and IP address changes.
| Value | Name | Purpose |
|---|---|---|
0x01 |
OBSERVATION | Read-only device state collection |
0x02 |
INTENT | Proposed configuration changes |
| Value | Name | Meaning |
|---|---|---|
0x01 |
GREEN | No approval required — read-only |
0x02 |
YELLOW | Flagged for review |
0x03 |
RED | Human approval required |
0xFF |
BLACK | Blocked at C level — never reaches device |
Nodes SHOULD accept both v1 and v2 during transition periods. The negotiated session version (from HELLO/HELLO_ACK) determines which format is used for the session.
A v1 node connecting to a v2 O-Node will negotiate down to v1 during the handshake. A v2 node connecting to a v1 O-Node will do the same.
See VIRP-WIRE-FORMAT.md and VIRP-SPEC-RFC-v2.md in the repository root.