Internet-Draft | Erik Synchronization Protocol for RPKI | July 2025 |
Snijders, et al. | Expires 8 January 2026 | [Page] |
This document specifies the Erik Synchronization Protocol for use with the Resource Public Key Infrastructure (RPKI). Erik Synchronization can be characterized as a data replication system using Merkle trees, a content-addressable naming scheme, concurrency control using monotonically increasing sequence numbers, and HTTP transport. Relying Parties can combine information retrieved via Erik Synchronization with other RPKI transport protocols. The protocol's design is intended to be efficient, fast, and easy to implement.¶
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 8 January 2026.¶
Copyright (c) 2025 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.¶
This document specifies the Erik Synchronization Protocol for use with the Resource Public Key Infrastructure (RPKI) [RFC6480]. Erik Synchronization can be characterized as a data replication system using Merkle Trees [M1987], a content-addressable naming scheme [RFC6920], concurrency control using monotonically increasing sequence numbers [RFC0677], and HTTP transport [RFC9110]. Relying Parties can combine information retrieved via Erik Synchronization with other RPKI transport protocols ([RFC5781] and [RFC8182]). The protocol's design is intended to be efficient, fast, and easy to implement [RFC1925].¶
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 reader is assumed to be familiar with the terms and concepts described in "Maintenance of duplicate databases" [RFC0677], "An Infrastructure to Support Secure Internet Routing" [RFC6480], "The RPKI Repository Delta Protocol (RRDP)" [RFC8182], "Manifests for the Resource Public Key Infrastructure (RPKI)" [RFC9286], and "A Digital Signature Based on a Conventional Encryption Function" [M1987].¶
This section describes the terminology and abbreviations used in this document. Though the definitions might not be clear on a first read, later on the terms will be introduce with more detail.¶
In this synchronization protocol Merkle trees are used to determine whether differences exist between client and relay. Merkle trees are hierarchical data structures: the hash value of each node is computed recursively by hashing the concatenated hash values of the node's children. The tree head hash represents the entire dataset. If the tree head hash is not the same between two replicas, the relay provides the client with hashes of smaller and smaller portions of the to-be-replicated dataset until the exact list of out-of-sync or missing objects is identified. Sequence numbers are then used to determine whether these differences are relevant enough for the client to fetch. All data is fetched using addresses derived from hashes (except for the hash tree heads). This approach reduces unnecessary data transfer between caches which contain mostly similar data.¶
The client starts by querying an Erik relay for its current tree head for a given FQDN. If the tree head is different compared to the previous run (or compared to the tree head calculated from the locally cached objects), the client can fetch the ErikIndex object using the tree head hash. With the ErikIndex in hand, the client can determine which ErikParitions changed or are missing and fetch accordingly. The client then can compare the manifestNumber sequence number for each Manifest listed in the ErikPartition, and proceed to fetch (purportedly) newer versions of Manifests of interest. Whenever a relay offers a Manifest with a lower sequence number the client can ignore it. With the information contained within Manifests, clients can fetch addressed by content and store by name. The client now has sufficient information to proceed to fetch any missing Certificates, Signed objects, and CRLs.¶
In this synchronization protocol the signal layer makes use of DER-encoded messages [X.690].¶
Design note: DER encoding was selected for its canonical properities and because RPKI cache implementations already support ASN.1 encoding.¶
An ErikIndex represents all current Manifest objects available under a given FQDN and thus the complete state of the repository as it is known to the relay.¶
RpkiErikIndex-2025 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) mod(0) id-mod-rpkiErikIndex-2025(TBD) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS Digest, DigestAlgorithmIdentifier FROM CryptographicMessageSyntax-2010 -- in [RFC6268] { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) modules(0) id-mod-cms-2009(58) } ErikIndex ::= SEQUENCE { version [0] INTEGER DEFAULT 0, indexScope IA5String, indexTime GeneralizedTime, hashAlg DigestAlgorithmIdentifier, previousIndex Digest OPTIONAL, partitionList SEQUENCE SIZE (1..ub-Partitions) OF PartitionListEntry } ub-Partitions INTEGER ::= 1024 PartitionListEntry ::= SEQUENCE { partitionIdentifier INTEGER (1..ub-Partitions), hash Digest } END¶
The version number of the ErikIndex object MUST be 0.¶
The indexScope
field contains the fully qualified domain name of the Signed Object location of the Manifests referenced through this particular ErikIndex.
The FQDN MUST be in the "preferred name syntax", as specified by Section 3.5 of [RFC1034] and modified by Section 2.1 of [RFC1123].¶
The indexTime
is the most recent partitionTime
value among the ErikPartitions referenced from this ErikIndex.
The field's value roughly indicates when the ErikIndex was generated.
The field exists for troubleshooting or measurement purposes.¶
For the purposes of this profile, GeneralizedTime
values MUST be expressed UTC (Zulu) and MUST include seconds (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds is zero.
GeneralizedTime values MUST NOT include fractional seconds.
See Section 4.1.2.5.2 of [RFC5280].¶
Design note: using the most recent partitionTime
(rather than "now") helps reduce churn in distributed systems.
¶
This field contains the OID of the hash algorithm used to hash the ErikPartitions. The hash algorithm used MUST conform to the RPKI Algorithms and Key Size Profile specification [RFC7935].¶
This field is a sequence of ErikIndexEntry
instances.
There is one ErikIndexEntry
for each current partition.
Each ErikIndexEntry
is a pair consisting of the partition identifier and the hash of the partition object.¶
Information elements are unique with respect to one another and sorted in ascending order of the partition identifier.¶
An ErikPartition represents a subset of Manifest objects available under a given FQDN. Each ErikPartition is a sorted listing of the Manifest objects' hashes, manifestNumbers, and their end-entity certificates' SIA extension values.¶
RpkiErikPartition-2025 { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) mod(0) id-mod-rpkiErikPartition-2025(TBD) } DEFINITIONS EXPLICIT TAGS ::= BEGIN IMPORTS SubjectInfoAccessSyntax FROM PKIX1Explicit88 -- in [RFC5280] { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) } Digest, DigestAlgorithmIdentifier FROM CryptographicMessageSyntax-2010 -- in [RFC6268] { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) modules(0) id-mod-cms-2009(58) } ErikPartition ::= SEQUENCE { version [0] INTEGER DEFAULT 0, partitionTime GeneralizedTime, hashAlg DigestAlgorithmIdentifier, manifestList SEQUENCE SIZE (1..MAX) OF ManifestListEntry } ManifestListEntry ::= SEQUENCE { hash Digest, manifestNumber INTEGER (0..MAX), location OCTET STRING } -- subjectInfoAccess extnValue END¶
The version number of the ErikPartition object MUST be 0.¶
The partitionTime
is the most recent thisUpdate
value among the Manifests contained within this ErikPartition.
The field's value roughly indicates when the ErikPartition was generated.
The field exists for troubleshooting or measurement purposes.¶
For the purposes of this profile, GeneralizedTime
values MUST be expressed UTC (Zulu) and MUST include seconds (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds is zero.
GeneralizedTime values MUST NOT include fractional seconds.
See Section 4.1.2.5.2 of [RFC5280].¶
Design note: using the most recent Manifest thisUpdate
value (instead of "now") helps reduce churn in distributed systems.
¶
This field contains the OID of the hash algorithm used to hash the Manifest objects referenced in this ErikPartition. The hash algorithm used MUST conform to the RPKI Algorithms and Key Size Profile specification [RFC7935].¶
This field is a sequence of ManifestListEntry
instances.
There is one ManifestListEntry
for each current Manifest.
A Manifest is nominally current until the time specified in nextUpdate or until a Manifest is issued with a greater manifestNumber, whichever comes first (see Section 4.2.1 of [RFC9286]).¶
A ManifestListEntry
is a 3-tuple consisting of the hash of the Manifest object, the manifestNumber contained within the object, and an OCTET STRING containing the Manifest's End-Entity certificate's Subject Information Access extension value.¶
Information elements are unique with respect to one another and sorted in ascending order of the hash.¶
Clients can bootstrap initial state by fetching a snapshot. A snapshot contains all RPKI objects a relay associated with a given FQDN as of the time of the snapshot's production. Snapshots do not contain ErikIndex or ErikPartition objects. Because snapshots are not produced in lockstep with updates to the merkle trees, clients MUST perform a tree comparison after fetching a snapshot.¶
Snapshots are encoded using the POSIX [ustar] format and compressed using GZIP ([RFC1951], [RFC1952]).¶
Differences between snapshots will be specified at a later time.¶
Design notes:
The ustar format was selected because it is 'streamable', widely available, and an open standard.
A compressed form is mandated because opportunistic compression in the transport layer (e.g. HTTP compressed content-encoding) is not universally available.
On the flip side, .tar.gz
objects likely wont be produced in a deterministic fashion across different implementations, warranting a choice of some other archive format.
¶
A client can decide whether or not to fetch ErikIndex and ErikPartition objects, by comparing the hash to previous fetches.¶
A client can decide whether or not to fetch a given Manifest object, by comparing the manifestNumber
with what's locally cached and what's offered by the remote relay.¶
A client can compute which products listed in the Manifest's fileList need to be fetched from the relay.¶
As there is no concept of 'sessions' (like in RRDP), clients can interchangably use different Erik relay. When one Erik relay generates a HTTP error, the client can try fetching the requested object from another Erik relay.¶
The client MUST calculate the hash of fetched objects and verify it is the same as the expected hash (which is embedded in the name through which the object was retrieved). If there is a hash mismatch, the client may try fetching the object from a different Erik relay or treat this as a failed fetch (see Section 6.6 of [RFC9286]).¶
Erik relays can be operated by third parties, without permission from or coordination with publication point operators or CAs.¶
Relays generate ErikIndexes and ErikPartitions derived from their current validation state, the client then cherry-picks which objects (if any) it wishes to fetch. Relays fetch fresh data from other relays or from CA-designated publication points.¶
Design notes: a decision must be made a deterministic "manifest-to-partition" assignment scheme. Job's proof-of-concept relay uses the first few octets of the SHA-256 hash of the Manifest for produce as a stable assignment strategy. Other strategies could be to assign Manifests to ErikPartitions based on the "hour-of-day" of the CMS signing timestamp or the Authority Key Identifier. ¶
Ignoring obvious "on the wire format" differences between Erik, Rsync, and RRDP; there are a number of key design differences between the protocols. Rsync and RRDP can be described as "general purpose" synchronisation protocols, while the Erik protocol design is RPKI-specific. In the Erik protocol, Manifest objects (which RPs require for validation anyway) are an integral part of the signaling layer.¶
In Rsync, the server and the client construct and transfer a full listing of all available objects, and then transfer objects as necessary. In effect, this allows clients to 'jump' to the latest repository state, regardless of the state of the local cache.¶
A major downside of Rsync is that the list of files itself can become a burden to transfer.
As of June 2025, in order to merely establish whether a client is synchronized or not with the RIPE NCC repository at rpki.ripe.net
, as much as 5.8 megabytes of data are exchanged without exchanging any RPKI data.¶
When synchronizing once an hour, Rsync generally consumes less network traffic than RRDP.¶
The key concept in RRDP is that the client downloads a "journal", containing all add/update/delete operations and replays this journal to arrive at the current repository state.¶
A major downside of RRDP is that (depending on the RRDP polling interval) clients end up downloading data which has become outdated. Imagine a hypothetical CA which issues and revokes a ROA every 10 minutes and a client that synchronizes every 60 minutes; in effect the client must fetch 5 outdated states, wasting bandwidth.¶
When synchronizing every 15 minutes, RRDP generally consumes less network traffic than Rsync.¶
In contrast to RRDP, the Erik protocol has no concept of server-specific "stateful" sessions that persist across polling attempts, obviating the need for withdraw
instructions.
Clients can simply delete objects that are no longer referenced from their current validation state.¶
This section is to be removed before publishing as an RFC.¶
previous hash
field so clients can observe gaps in chains?¶
As of July 2025, the global Internet's RPKI churn rate appears to be 2 new objects per second. The ecosystem is estimated to be composed of ~ 5000 RPKI cache instances and ~ 50 repository servers. Assuming 10 minute fetching intervals and 150 metadata requests per synchronization run (for exchange of Merkle tree data), an Erik relay serving all the Internet's RPKI cache instances would probably need to be able to sustain serving an average of at least 11,000 HTTP requests per second. This order of magnitude in terms of scaling requirements can easily be handled by a single commodity server.¶
This document makes no changes to RPKI certificate validation procedures.¶
See Section 5 of [RFC8182] for applicable security considerations.¶
The IANA is requested to add an item to the "SMI Security for S/MIME Module Identifier" registry as follows:¶
Decimal Description References -------------------------------------------------------------- TDB id-mod-rpkiErikIndex-2025 [this-draft] TDB id-mod-rpkiErikPartition-2025 [this-draft]¶
The authors wish to thank George Michaelson, Theo de Raadt, Bob Beck, and Theo Buehler for the lovely conversations that led to this proposal.¶
This protocol is named after Erik Bais, who passed away in 2024, as a small token of appreciation for his friendship.¶