| Internet-Draft | ZTOP | July 2026 |
| Karthik | Expires 24 January 2027 | [Page] |
This document defines the Zero Trust Transfer Orchestration Protocol (ZTOP), a novel Application Layer (OSI Layer 7) protocol for orchestrating cryptographically authenticated, continuously attested peer-to-peer file transfer in Zero Trust Architectures (ZTA).¶
ZTOP operates within a TLS 1.3 transport tunnel and introduces: a hardware-derived cryptographic Peer Identity using HKDF-SHA512 and Ed25519; a 5-layer X.509 certificate chain with custom OID-encoded Zero Trust metadata; a continuous 16-field Heartbeat attestation protocol; a 100-point Adaptive Tamper Resistance Score across six security dimensions; a dual-signed 19-field Metadata Exchange Protocol preceding any payload transfer; a 380-byte Cryptographic Execution Manifest (CEM) permanently bound to every transferred file; SHA-256 binary Merkle-tree chunk integrity with immediate per-chunk proof validation; protocol-native static pre-execution behavioral analysis; and a 7-Level non-repudiation Signature Chain. A transfer is considered complete only when all seven cryptographic signatures are present and verified.¶
A Python reference implementation is available at: https://github.com/sripad2020/ztop-research/¶
This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.¶
Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.¶
Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."¶
This Internet-Draft will expire on 2 January 2027.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License.¶
File transfer protocols have not evolved with Zero Trust security principles [RFC7296]. Protocols such as SFTP [RFC4253] and FTP [RFC959] authenticate a user once via a static credential and subsequently establish an open, trusted channel. They have no awareness of device security posture, real-time behavioral analysis of the transferred content, or cryptographic non-repudiation of the transaction itself.¶
Enterprises today solve this limitation by deploying five or more separate security products alongside a legacy file transfer protocol, resulting in fragmented, expensive, and operationally complex architectures.¶
ZTOP defines a single, self-contained Application Layer protocol that natively integrates all of the following:¶
Cryptographic Peer Identity derived from hardware attestation¶
Continuous device posture evaluation and dynamic trust scoring¶
Declarative organizational policy enforcement¶
Pre-payload metadata negotiation with dual attestation signatures¶
File-level Cryptographic Execution Manifests (CEM)¶
Per-chunk Merkle tree integrity without requiring full-file arrival¶
Protocol-native static behavioral analysis of received files¶
A 7-Level non-repudiation signature chain¶
Trust-preserving session resumption after transport disconnection¶
ZTOP does NOT replace TCP, IP, TLS, or QUIC. It operates within a TLS 1.3 tunnel and defines how endpoints behave before, during, and after a file transfer.¶
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The following terms are used in this document:¶
ZTOP is an Application Layer (OSI Layer 7) protocol. It MUST operate within an encrypted transport tunnel. Implementations MUST support TLS 1.3 [RFC8446] as the transport. Implementations MAY additionally support QUIC [RFC9000].¶
+------------------------------------------------------------+ | Layer 7 - APPLICATION | | +---------------------------------------------------------+| | | ZTOP PROTOCOL || | | TrustEngine PolicyEngine CertEngine MerkleEngine || | | CEMEngine HeartbeatEngine ExecutionAnalyzer || | | SignatureChainEngine ReconnectManager AuditEngine || | +---------------------------------------------------------+| +------------------------------------------------------------+ | Layer 6 - PRESENTATION | | TLS 1.3 Record Layer (AES-256-GCM / ChaCha20-Poly1305) | +------------------------------------------------------------+ | Layer 5 - SESSION | | TLS Session + ZTOP Session State Machine | +------------------------------------------------------------+ | Layer 4 - TRANSPORT | | TCP (Port 7890) | +------------------------------------------------------------+ | Layers 1-3 - NETWORK / DATA LINK / PHYSICAL | | IPv4 / IPv6 / Ethernet / Wi-Fi | +------------------------------------------------------------+
ZTOP consists of fifteen logical engines. Each engine MUST be instantiated per active session on the Gateway. Table 1 lists all components.¶
| Engine | Responsibility |
|---|---|
| PeerIDEngine | Derive and validate cryptographic Peer IDs |
| CertStore | Maintain root CA, org CAs, and device cert chains |
| CertEngine | Issue Session and Transfer Receipt X.509 certs |
| TrustEngine | Score device posture (0-100 points) |
| TamperScoreEngine | Compute 100-pt Adaptive Tamper Resistance Score |
| PolicyEngine | Evaluate six organizational transfer rules |
| HeartbeatEngine | Validate 16-field signed attestation packets |
| MerkleEngine | Build Merkle trees and verify per-chunk proofs |
| CEMEngine | Deserialize and verify Cryptographic Execution Manifests |
| MetadataEngine | Execute 9-step pre-transfer metadata validation |
| ExecutionAnalyzer | Perform static behavioral analysis of files |
| SignatureChainEngine | Build and verify 7-level non-repudiation chain |
| ReconnectManager | Cache session state for trust-preserving reconnect |
| IntegrityEngine | Compute and verify SHA-256/SHA3-512 file hashes |
| AuditEngine | Produce sealed ECDSA-signed audit records |
All ZTOP messages SHALL be encoded as frames in Network Byte Order (Big-Endian). Every frame consists of three fixed headers, a variable TLV payload, raw payload data, and two mandatory footers.¶
+------------------------------------------------+ | PROTOCOL HEADER (38 bytes, fixed) | +------+-------+----------+----------+------------+ |Magic |Version| MsgType | Flags | Sequence # | | "ZT" | 0x01 | (1 byte) | (2 bytes)| (4 bytes) | +------+-------+----------+----------+------------+ | Timestamp (8 bytes, uint64, microseconds) | +-------------------------------------------------+ | Session ID (16 bytes, UUID v4) | +-------------------------------------------------+ | Payload Length (4 bytes, uint32) | +-------------------------------------------------+ | SECURITY HEADER (48 bytes, fixed) | +-------------------------------------------------+ | Nonce (12 bytes, cryptographically random) | +-------------------------------------------------+ | Transfer ID (16 bytes, UUID v4) | +-------------------+-----------+--------+--------+ |Policy Version (4) |Trust Score|Enc Suite|Rsvd(8)| +-------------------+-----------+--------+--------+ | ROUTING HEADER (16 bytes, fixed) | +-------------------------------------------------+ | Device ID Hash (8 bytes, truncated SHA-256) | +-----------------------+------+------+-----------+ | Org ID Hash (4, CRC32)|Prio |Comp |Ext Count | +-----------------------+------+------+-----------+ | PAYLOAD HEADER (variable, TLV) | | [Type(2)|Length(2)|Value(N)] x ExtCount | +-------------------------------------------------+ | RAW PAYLOAD DATA (variable) | +-------------------------------------------------+ | INTEGRITY FOOTER (32 bytes) | | SHA-256(all preceding bytes) | +-------------------------------------------------+ | AUTH FOOTER (32 bytes) | | HMAC-SHA256(session_key, body || integrity) | +-------------------------------------------------+ | SIGNATURE FOOTER (96 bytes, conditional) | | ECDSA-P384 (present only when SIGNED flag set) | +-------------------------------------------------+
The 2-byte Flags field encodes eight independent Zero Trust control signals as a bitmask:¶
| Value | Name | Zero Trust Role |
|---|---|---|
| 0x0001 | PAYLOAD_ENCRYPTED | Data frames without this MUST be rejected |
| 0x0002 | PAYLOAD_COMPRESSED | Payload uses codec from Routing Header |
| 0x0004 | REQUIRES_ACK | Receiver MUST acknowledge this frame |
| 0x0008 | PRIORITY_BOOST | Gateway processes before standard frames |
| 0x0010 | SIGNED | 96-byte ECDSA-P384 footer is appended |
| 0x0020 | LAST_CHUNK | Final chunk of an active transfer |
| 0x0040 | RECOVERY_MODE | Frame is part of a reconnect handshake |
| 0x0080 | HEARTBEAT_EXPECTED | Sender mandates Heartbeat from receiver |
A receiver that observes a TRANSFER_CHUNK packet without PAYLOAD_ENCRYPTED set MUST reject the packet with error code ENCRYPTION_REQUIRED and MAY terminate the session.¶
All metadata fields are carried as Type-Length-Value (TLV) records. Each TLV consists of a 2-byte unsigned integer type, a 2-byte unsigned integer length, and a value field of that many bytes. All fields are Big-Endian encoded.¶
An implementation receiving an unknown mandatory TLV type (codes 0x0000-0x7FFF) MUST return an ERROR packet and close the session. An implementation receiving an unknown optional TLV type (codes 0x8000-0xFFFF) MUST silently ignore it.¶
| OpCode | Message Name | Direction |
|---|---|---|
| 0x01 | HELLO | Client to Server |
| 0x02 | DISCOVER | Server to Client |
| 0x03 | REGISTER | Client to Server |
| 0x04 | IDENTITY_REQUEST | Server to Client |
| 0x05 | IDENTITY_RESPONSE | Client to Server |
| 0x06 | TRUST_REQUEST | Client to Server |
| 0x07 | TRUST_RESPONSE | Server to Client |
| 0x08 | POLICY_REQUEST | Client to Server |
| 0x09 | POLICY_RESPONSE | Server to Client |
| 0x0A | CAPABILITY_NEGOTIATE | Both |
| 0x0B | SESSION_CREATE | Client to Server |
| 0x0C | SESSION_ACCEPT | Server to Client |
| 0x0E | SESSION_RECOVER | Client to Server |
| 0x0F | SESSION_CLOSE | Either |
| 0x10 | HEARTBEAT | Client to Server |
| 0x20 | TRANSFER_REQUEST | Client to Server |
| 0x21 | TRANSFER_START | Server to Client |
| 0x22 | TRANSFER_CHUNK | Client to Server |
| 0x23 | TRANSFER_ACK | Server to Client |
| 0x27 | TRANSFER_COMPLETE | Client to Server |
| 0x28 | TRANSFER_REJECT_CHUNK | Server to Client |
| 0x33 | AUDIT_COMMIT | Server to Client |
| 0xFF | ERROR | Either |
A ZTOP session MUST traverse the following states in order. Backward transitions are NOT permitted except as noted for the RECOVERING state. A Gateway MUST reject any message whose implied state transition is not permitted, and MUST respond with an ERROR packet containing code SESSION_STATE_INVALID.¶
[INIT] | <- HELLO received, magic 0x5A54 validated v [DISCOVERY] | <- REGISTER received, Peer ID parsed v [REGISTERED] | <- Ed25519 identity challenge signed and verified v [IDENTITY_VERIFIED] | <- Device posture submitted, Trust Score >= threshold v [DEVICE_TRUSTED] | <- PolicyEngine returns permitted=True (all 6 checks) v [POLICY_APPROVED] | <- Session Certificate issued, capabilities negotiated v [SESSION_ACTIVE] <------------------------------------+ | <- Transport disconnection detected | v | [RECOVERING] -- Peer ID re-validated via HB ----------+ | (7 retries exhausted) v [FAILED] (terminal) | [TERMINATED] (terminal)
Every ZTOP endpoint MUST derive a Peer ID using the following algorithm. Implementations MUST NOT use Fibonacci sequences or other deterministic mathematical sequences for Peer ID derivation or any cryptographic key generation.¶
Input:
device_uuid : Hardware device UUID string
cpu_hash : SHA-256(CPU model string), hex
os_hash : SHA-256(OS version string), hex
motherboard_hash : SHA-256(board identifier), hex
network_sig : Ed25519 signature over current IP:Port
policy_version : Active org policy version (integer)
salt : os.urandom(32) [fresh each derivation]
Step 1 - Canonical Encoding (UTF-8):
IKM_input = "uuid={device_uuid}|cpu={cpu_hash}|
os={os_hash}|mb={motherboard_hash}|
policy={policy_version}|netsig={netsig.hex()}"
Step 2 - SHA3-512 (Immutable Keying Material):
ikm = SHA3-512(IKM_input) [64 bytes]
Step 3 - HKDF-SHA512 [RFC5869]:
seed = HKDF-SHA512(
ikm = ikm,
salt = salt,
info = b"ZTOP-PeerID-v1",
length = 32
)
Step 4 - Ed25519 Keypair [RFC8032]:
private_key = Ed25519PrivateKey.from_private_bytes(seed)
public_key = private_key.public_key()
pub_raw = public_key.raw_bytes() [32 bytes]
Step 5 - Peer ID Encoding:
peer_id = "ZTOP-" || Base58(SHA3-256(pub_raw))
The salt MUST be stored in hardware-backed secure storage (TPM 2.0 or TEE) and MUST NOT be transmitted over the network.¶
ZTOP implements a five-layer X.509 [RFC5280] certificate hierarchy. All certificates use ECDSA-P384 or Ed25519. The five layers are: Root CA (10 years), Org CA (1 year), Device Certificate (30 days), Session Certificate (12 hours), and Transfer Receipt Certificate (1 year).¶
Session Certificates MUST embed the following custom OID extensions:¶
| OID | Name | Present In |
|---|---|---|
| 1.3.6.1.4.1.99999.1 | ZTOP-DeviceID | Device Certificate |
| 1.3.6.1.4.1.99999.2 | ZTOP-SessionID | Session Certificate |
| 1.3.6.1.4.1.99999.3 | ZTOP-TrustScore | Session Certificate |
| 1.3.6.1.4.1.99999.4 | ZTOP-PolicyVersion | Session Certificate |
| 1.3.6.1.4.1.99999.6 | ZTOP-NetworkInfo | Session Certificate |
| 1.3.6.1.4.1.99999.7 | ZTOP-PostureHash | Device Certificate |
| 1.3.6.1.4.1.99999.8 | ZTOP-TransferID | Receipt Certificate |
| 1.3.6.1.4.1.99999.9 | ZTOP-FileHash | Receipt Certificate |
The Client MUST submit a PostureData record. The TrustEngine assigns weighted scores summing to a maximum of 100. The default threshold is 70; implementations MAY configure a higher value. A Gateway MUST terminate any session where the score falls below the configured threshold.¶
| Signal | Weight | Condition |
|---|---|---|
| EDR Active | +30 | Endpoint Detection and Response running |
| TPM Attested | +20 | Hardware TPM 2.0 attestation present |
| Firewall Active | +15 | Host-based firewall enabled |
| OS Version Current | +15 | OS major version at or above 10 |
| Patch Level Fresh | +10 | Last patch applied within 30 days |
| VPN Connected | +5 | Network posture includes VPN |
| Antivirus OK | +5 | AV status is OK or ACTIVE |
The TamperScoreEngine computes a 100-point composite score across six security dimensions. A Gateway MUST re-evaluate this score at every Heartbeat interval and after every chunk transfer event.¶
| Dimension | Max Points | Signals |
|---|---|---|
| Device Posture | 20 | OS patch, EDR, Firewall, TPM, Disk Encryption |
| Certificate | 20 | Chain validity, Expiry, OCSP, Pinning |
| Heartbeat | 15 | Consecutive successes, Latency quality |
| Policy Compliance | 15 | Version current, org rules, DLP checked |
| File Integrity | 20 | Merkle root match, chunk success, CEM sig |
| Network Signature | 10 | VPN, Geo-fence, IP reputation |
Trust bands and required Gateway actions:¶
| Score Range | Band | Required Action |
|---|---|---|
| 95-100 | TRUSTED | Permit full transfer |
| 80-94 | LIMITED | Permit with enhanced audit logging |
| 60-79 | RESTRICTED | Permit only via proxied analysis |
| 0-59 | DISCONNECT | MUST terminate session immediately |
A Client MUST send a signed Heartbeat packet every 10 seconds while a session is in SESSION_ACTIVE or RECOVERING state. The Heartbeat packet MUST contain 16 fields including: peer_id, counter (monotonic), timestamp (microseconds), device_uuid, cert_fingerprint (SHA-256 of active session cert DER), current_ip, mac_hash (SHA-256 of MAC address), port, network_signature (Ed25519 over IP:Port), policy_version, session_token (SHA-256 of session_id), cpu_arch_hash, os_version_hash, nonce (16 random bytes), and a digital_signature (Ed25519 over all preceding 14 fields).¶
A Gateway MUST validate each Heartbeat through eight sequential checks: nonce uniqueness, timestamp freshness (30 second tolerance), policy version match, IP consistency, digital signature verification, certificate fingerprint match, counter monotonicity, and session token match.¶
Consecutive failures drive the session through the following states: 0-2 failures = HEALTHY; 3-4 failures = WARNING; 5+ failures = SLEEP with backoff delays of [2, 5, 10, 30, 60, 120, 300] seconds. After 7 failed retry attempts, the session MUST enter FAILED state.¶
Every file transferred via ZTOP MUST be prepended with a 380-byte Cryptographic Execution Manifest (CEM). The CEM gives the file a permanent cryptographic identity independent of the transport channel.¶
Offset Size Field ------ ---- ------------------------------------------------- 0 8 Magic: ASCII "ZTOP-CEM" (0x5A544F502D43454D) 8 16 File UUID (UUID v4 bytes) 24 32 File Hash (SHA-256 of raw file data) 56 32 Merkle Root (binary Merkle tree root hash) 88 8 Creation Timestamp (uint64, microseconds) 96 2 Version (uint16, currently 0x0001) 98 64 Sender Peer ID (null-padded UTF-8) 162 64 Receiver Peer ID (null-padded UTF-8) 226 32 Certificate Fingerprint (SHA-256 of sender cert) 258 16 Security Policy ID (null-padded UTF-8) 274 4 Execution Policy Flags (uint32 bitmask) 278 32 Allowed Receiver Hash (SHA-256(receiver_peer_id)) 310 6 Reserved (zeros) 316 64 Digital Signature (Ed25519 over bytes 8 to 315) ------ ---- Total: 380 bytes
Execution Policy Flags: 0x0001=ALLOW_EXEC, 0x0002=SANDBOX_ONLY, 0x0004=NO_NETWORK, 0x0008=NO_SUBPROCESS, 0x0010=IMMUTABLE, 0x0020=AUDIT_ON_EXEC.¶
Files are split into chunks of the negotiated chunk_size. A binary SHA-256 Merkle tree is constructed bottom-up. When the number of chunks is odd, the last leaf MUST be duplicated to form its parent.¶
Each TRANSFER_CHUNK packet MUST include: chunk_id, sequence number, byte offset, length, SHA-256 chunk_hash, session_id, per-chunk nonce, Merkle proof (sibling hashes bottom-up), and raw chunk data.¶
A Gateway MUST immediately verify each chunk upon receipt. Verification MUST include: SHA-256(received_data) equals chunk_hash; the Merkle proof ascent from chunk_hash reaches the pre-agreed Merkle Root; the sequence number is greater than the last accepted; and the nonce is not in the seen_nonces cache.¶
After complete file reassembly and before issuing AUDIT_COMMIT, the Gateway MUST perform static behavioral analysis. The Gateway MUST NOT deliver the file to destination storage until this analysis completes.¶
The analysis pipeline MUST include: Shannon entropy computation over the first 64 KB (entropy above 7.5 indicates packing or encryption, adding 20 risk points); for PE files, scanning for dangerous API imports including CreateProcess, VirtualAlloc, WriteProcessMemory, and CreateRemoteThread (each adding 8 risk points, maximum 50); for ELF files, scanning for dangerous syscall strings including execve, ptrace, and mprotect (each adding 6 risk points, maximum 40); for Python files, regex matching against dangerous import and call patterns (each adding 5 to 10 risk points, maximum 40).¶
The final risk_score is min(sum, 100). A score of 60 or higher MUST result in MALICIOUS verdict: the file buffer MUST be wiped and the transfer MUST be aborted. A score of 25 or higher results in SUSPICIOUS verdict and MUST be logged. A score below 25 results in CLEAN verdict and the transfer proceeds to the Signature Chain.¶
A transfer is marked SYNC_COMPLETE only when seven independent Ed25519 signatures are present and verified. The seven levels are: L1 (File Hash, Sender key), L2 (Merkle Root, Sender key), L3 (Metadata hash, Sender key), L4 (Sender Completion Assertion, Sender key), L5 (Receiver Acceptance Assertion, Receiver key), L6 (Session Digest over L1-L5, Session key), L7 (Gateway Completion Seal, Gateway key).¶
An AUDIT_COMMIT MUST NOT be issued until all seven signatures pass verification. Failure of any level MUST result in transfer rejection.¶
If a transport disconnection occurs during an active transfer, the Gateway MUST save the session state to a persistent ReconnectCache keyed by Session ID. Cache entries MUST expire after 3600 seconds.¶
Upon reconnection with RECOVERY_MODE flag set, the Client presents its cached session_key_id. The Gateway performs a fresh Heartbeat challenge. If the challenge passes and a valid cache entry exists, the transfer resumes from the last verified chunk without repeating the full handshake. The retry backoff schedule MUST be [2, 5, 10, 30, 60, 120, 300] seconds. After 7 failed attempts, a full new handshake is REQUIRED.¶
ZTOP assumes the adversary has full network access including the ability to observe, inject, delay, and replay packets, but does NOT have access to TLS session keys or endpoints' Ed25519 private keys.¶
All ZTOP packets include a 12-byte Nonce field. Receivers MUST maintain a nonce cache with a TTL of 300 seconds. Any packet whose nonce is found in the cache MUST be rejected. All packets include a Timestamp field. Receivers MUST reject packets with a timestamp deviation greater than 300 seconds from local time.¶
The 12-hour Session Certificate TTL limits the impact of key compromise. In the event of Org CA key compromise, the Gateway MUST immediately revoke all issued certificates and MUST NOT accept new session connections until new CA material is provisioned. Implementations SHOULD implement OCSP stapling [RFC6960] for real-time revocation checking.¶
ZTOP MUST operate within a TLS 1.3 tunnel [RFC8446]. Implementations MUST NOT support TLS versions earlier than 1.3.¶
The current specification uses Ed25519 [RFC8032] and ECDSA-P384 for digital signatures. These algorithms are not resistant to quantum computing attacks. Future versions of this specification SHOULD incorporate NIST-standardized post-quantum algorithms [NIST.FIPS.204] [NIST.FIPS.203] as they become widely deployed.¶
IANA is requested to assign the following port number:¶
IANA is requested to create a new registry "ZTOP OpCodes" with the initial assignments from Section 4.4. New entries require Standards Action [RFC8126].¶
IANA is requested to create a new registry "ZTOP TLV Types" with range 0x0000-0x7FFF (Standards Action) and 0x8000-0xFFFF (First Come First Served).¶
IANA is requested to register the custom X.509 OIDs listed in Section 7. Interim assignments under 1.3.6.1.4.1.99999 SHALL be replaced upon formal assignment.¶
The authors acknowledge the foundational work of the IETF TLS Working Group, the COSE Working Group, and the broader Zero Trust research community whose contributions made this work possible.¶