<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.5 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ramseyer-grow-peering-api-03" category="info" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.19.1 -->
  <front>
    <title>Peering API</title>
    <seriesInfo name="Internet-Draft" value="draft-ramseyer-grow-peering-api-03"/>
    <author fullname="Carlos Aguado">
      <organization>AWS</organization>
      <address>
        <email>crlsa@amazon.com</email>
      </address>
    </author>
    <author fullname="Matt Griswold">
      <organization>FullCtl</organization>
      <address>
        <email>grizz@20c.com</email>
      </address>
    </author>
    <author fullname="Jenny Ramseyer">
      <organization>Meta</organization>
      <address>
        <email>ramseyer@meta.com</email>
      </address>
    </author>
    <author fullname="Arturo Servin">
      <organization>Google</organization>
      <address>
        <email>arturolev@google.com</email>
      </address>
    </author>
    <author fullname="Tom Strickx">
      <organization>Cloudflare</organization>
      <address>
        <email>tstrickx@cloudflare.com</email>
      </address>
    </author>
    <date year="2024" month="January" day="29"/>
    <keyword>BGP</keyword>
    <keyword>peering</keyword>
    <keyword>configuration</keyword>
    <abstract>
      <?line 67?>

<t>We propose an API standard for BGP Peering, also known as interdomain interconnection through global Internet Routing.
This API offers a standard way to request public (settlement-free) peering, verify the status of a request or BGP session, and list potential connection locations.
The API is backed by PeeringDB OIDC, the industry standard for peering authentication.
We also propose future work to cover private peering, and alternative authentication methods.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://bgp.github.io/draft-ietf-peering-api/draft-peering-api-ramseyer-protocol.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ramseyer-grow-peering-api/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/bgp/draft-ietf-peering-api"/>.</t>
    </note>
  </front>
  <middle>
    <?line 74?>

<section anchor="problems">
      <name>Introduction</name>
      <t>The Peering API is a mechanism that allows networks to automate interdomain interconnection  between two Autonomous Systems (AS) through the Border Gateway Protocol 4 (<xref target="RFC4271"/>).
Using the API, networks will be able to automatically request and accept peering interconnections between Autonomous Systems in public or private scenarios in a time faster than it would take to configure sessions manually.
By speeding up the peering turn-up process and removing the need for manual involvement in peering, the API and automation will ensure that networks can get interconnected as fast, reliably, cost-effectively, and efficiently as possible.
As a result, this improves end-user performance for all applications using networks interconnection supporting the Peering API.</t>
      <section anchor="justification">
        <name>Business Justification</name>
        <t>By using the Peering API, entities requesting and accepting peering can significantly improve the process to turn up interconnections by:</t>
        <ul spacing="normal">
          <li>
            <t>Reducing in person-hours spent configuring peering</t>
          </li>
          <li>
            <t>Reducing configuration mistakes by reducing human interaction</t>
          </li>
          <li>
            <t>And by peering, reducing network latency through expansion of interconnection relationships</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="conventions">
      <name>Conventions and Definitions</name>
      <t>All terms used in this document will be defined here:</t>
      <ul spacing="normal">
        <li>
          <t>Initiator: Network that wants to peer</t>
        </li>
        <li>
          <t>Receiver: Network that is receiving communications about peering</t>
        </li>
        <li>
          <t>Configured: peering session that is set up on one side</t>
        </li>
        <li>
          <t>Established: session is already defined as per BGP-4 specification  <xref section="8.2.2" sectionFormat="of" target="RFC4271"/></t>
        </li>
      </ul>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>As peering connections exchange real Internet traffic, this API requires a security component to verify that the requestor is authorized to operate the interconnection on behalf of such AS.
In this initial proposal, the API follows an authorization model based on OpenID Connect <xref target="oidc"/> and OAuth 2.0 (<xref target="RFC6749"/>) where the Authorization Server is PeeringDB. The choice of OpenID Connect is to use the standardized token exchange format based on JSON Web Tokens (<xref target="RFC7519"/>) which allows interoperation with existing web-based application flows. JWT tokens also supply sufficient claims to implement receiver-side authorization decisions when used as bearer access tokens (<xref target="RFC9068"/>) and for which best common practices also exist (<xref target="RFC8725"/>).
After further discussion, the authors decided to offer alternate authentication options to accommodate the security concerns of different parties.
As peers may require varying security standards, this document proposes to support PeeringDB OIDC as the base requirement, with optional security extensions in addition (RPKI (<xref target="RFC6480"/>) or alternative OIDC Authorization Servers, for example).
This document hopes that, through the RFC process, the Working Group can come to a consensus on a base "authorization standard," to ease adoption for peering participants.</t>
      <t>Of particular interest is RPKI.
PeeringDB OIDC allows the API to identify who the requesting party is, while RPKI-signing allows such requesting party to prove that they own some of the Internet-assigned resources referenced in the request.
This combination provides a low entry barrier to create an identity federation across the participating ASs' API with a stronger guarantee of resource ownership against potential for misattribution and repudiation.
The authors recognize that not all partners have the time or engineering resources to support all authorization standards, so the API reference implementations will offer an extensible security mechanism to meet varying identity and security requirements.
For RPKI-based authentication, this document refers to RPKI Signed Checklists (RSCs) (<xref target="RFC9323"/>).</t>
    </section>
    <section anchor="protocol">
      <name>Protocol</name>
      <t>The Peering API follows the Representational State Transfer (<xref target="rest"/>) architecture where sessions, locations, and maintenance events are the resources the API represents and is modeled after the OpenAPI standard <xref target="openapi"/>.
Using the token bearer model (<xref target="RFC6750"/>), a client application can request to add or remove peering sessions, list potential interconnection locations, and query for upcoming maintenance events on behalf of the AS resource owner.</t>
      <section anchor="example-request-flow">
        <name>Example Request Flow</name>
        <t>The diagram below outlines the proposed API flow.</t>
        <artwork><![CDATA[
OIDC Authentication

+-----------+                 +-------+                    +-----------+
| Initiator |                 | Peer  |                    | PeeringDB |
+-----------+                 +-------+                    +-----------+
      |                           |                              |
      | OIDC Authentication       |                              |
      |--------------------------------------------------------->|
      |                           |                              |
      |                                        Provide auth code |
      |<---------------------------------------------------------|
      |                           |                              |
      | Send auth code to Peer    |                              |
      |--------------------------------------------------------->|
      |                           |                              |
      |                           | Exchange auth code for token |
      |                           |----------------------------->|
      |                           |                              |
      |                           |                 Return token |
      |                           |<-----------------------------|
      |                           |
      | Peer determines permissions based on token
      |                           |
      | Send OK back to Initiator |
      |<--------------------------|

Operations, loop until peering is complete.

List Locations

+-----------+                                                  +-------+
| Initiator |                                                  | Peer  |
+-----------+                                                  +-------+
      |                                                            |
      | QUERY peering locations (peer type, ASN, auth code)        |
      |----------------------------------------------------------->|
      |                                                            |
      |                               Reply with peering locations |
      |                            or errors (401, 406, 451, etc.) |
      |<-----------------------------------------------------------|


Request session status

+-----------+                                                  +-------+
| Initiator |                                                  | Peer  |
+-----------+                                                  +-------+
      |                                                            |
      | QUERY request status using request ID & auth code          |
      |----------------------------------------------------------->|
      |                                                            |
      |                                  Reply with session status |
      |                                      (200, 404, 202, etc.) |
      |<-----------------------------------------------------------|
]]></artwork>
      </section>
      <section anchor="auth">
        <name>AUTH</name>
        <t>First, the initiating OAuth2 Client is also the Resource Owner (RO) so it can follow the OAuth2 client credentials grant <xref section="4.4" sectionFormat="of" target="RFC6749"/>.
In this example, the client will use PeeringDB OIDC credentials to acquire a JWT access token that is scoped for use with the receiving API.
On successful authentication, PeeringDB provides the Resource Server (RS) with the client's email (for potential manual discussion), along with the client's usage entitlements (known as OAuth2 scopes), to confirm the client is permitted to make API requests on behalf of the initiating AS.</t>
      </section>
      <section anchor="request">
        <name>REQUEST</name>
        <ol spacing="normal" type="1"><li>
            <t>ADD SESSION (CLIENT BATCHED REQUEST)</t>
          </li>
        </ol>
        <ul spacing="normal">
          <li>
            <t>The initiator's client provides a set of:
            </t>
            <ul spacing="normal">
              <li>
                <t>Structure:
                </t>
                <ol spacing="normal" type="1"><li>
                    <t>Local ASN (receiver)</t>
                  </li>
                  <li>
                    <t>Local IP</t>
                  </li>
                  <li>
                    <t>Peer ASN (initiator)</t>
                  </li>
                  <li>
                    <t>Peer IP</t>
                  </li>
                  <li>
                    <t>Peer Type (public or private)</t>
                  </li>
                  <li>
                    <t>MD5 (optional with encoding agreed outside of this specification)</t>
                  </li>
                  <li>
                    <t>Location (Commonly agreed identifier of the BGP speaker, e.g. PeeringDB IX lan ID)</t>
                  </li>
                  <li>
                    <t>Item ID (identifies the session within the set requested)</t>
                  </li>
                </ol>
              </li>
            </ul>
          </li>
          <li>
            <t>The receiver's expected actions:
            </t>
            <ul spacing="normal">
              <li>
                <t>The server confirms requested clientASN in list of authorized ASNs.</t>
              </li>
              <li>
                <t>Optional: checks traffic levels, prefix limit counters, other desired internal checks.</t>
              </li>
            </ul>
          </li>
        </ul>
        <ol spacing="normal" type="1"><li>
            <t>ADD SESSIONS (SERVER BATCHED RESPONSE)</t>
          </li>
        </ol>
        <ul spacing="normal">
          <li>
            <t>APPROVAL CASE
            </t>
            <ul spacing="normal">
              <li>
                <t>Server returns a list with the structure for each of the acceptable peering sessions. Note: this structure may also contain additional attributes such as the server generated session ID.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>PARTIAL APPROVAL CASE
            </t>
            <ul spacing="normal">
              <li>
                <t>Server returns a list with the structure for each of the acceptable peering sessions as in the approval case. The server also returns a list of sessions that have not deemed as validated or acceptable to be created. The set of sessions accepted and rejected is disjoint and the join of both sets matches the cardinality of the requested sessions. The sessions on each set are associated to the client request by the Item ID specified for each session.</t>
              </li>
            </ul>
          </li>
          <li>
            <t>REJECTION CASE
            </t>
            <ul spacing="normal">
              <li>
                <t>Server returns an error message which indicates that all of the sessions requested have been rejected and the reason for it.</t>
              </li>
            </ul>
          </li>
        </ul>
      </section>
      <section anchor="clientconfig">
        <name>CLIENT CONFIGURATION</name>
        <t>The client then configures the chosen peering sessions asynchronously using their internal mechanisms.
For every session that the server rejected, the client removes that session from the list to be configured.</t>
      </section>
      <section anchor="serverconfig">
        <name>SERVER CONFIGURATION</name>
        <t>The server configures all sessions that are in its list of approved peering sessions from its reply to the client.</t>
      </section>
      <section anchor="monitoring">
        <name>MONITORING</name>
        <t>Both client and server wait for sessions to establish.
At any point, client may send a "GET STATUS" request to the server, to request the status of the session (by session ID).
The client will send a structure along with the request, as follows:</t>
        <ul spacing="normal">
          <li>
            <t>structure:
            </t>
            <ul spacing="normal">
              <li>
                <t>Session ID</t>
              </li>
              <li>
                <t>Local ASN (server)</t>
              </li>
              <li>
                <t>Local IP</t>
              </li>
              <li>
                <t>Peer ASN (client)</t>
              </li>
              <li>
                <t>Peer IP</t>
              </li>
              <li>
                <t>Peer Type</t>
              </li>
              <li>
                <t>MD5 (optional, as defined above)</t>
              </li>
              <li>
                <t>Location</t>
              </li>
              <li>
                <t>Status</t>
              </li>
            </ul>
          </li>
        </ul>
        <t>The server then responds with the same structure, with the information that it understands (status, etc).</t>
      </section>
      <section anchor="completion">
        <name>COMPLETION</name>
        <t>If both sides report that the session is established, then peering is complete.
If one side does not configure sessions within the server's acceptable configuration window (TimeWindow), then the server is entitled to remove the configured sessions and report "Unestablished" to the client.</t>
      </section>
    </section>
    <section anchor="endpoints_and_specs">
      <name>API Endpoints and Specifications</name>
      <t>Each peer needs a public API endpoint that will implement the API protocol.
This API should be publicly listed in peeringDB and also as a potential expansion of <xref target="RFC9092"/> which could provide endpoint integration to WHOIS (<xref target="RFC3912"/>).
Each API endpoint should be fuzz-tested and protected against abuse.  Attackers should not be able to access internal systems using the API.
Every single request should come in with a unique GUID called RequestID that maps to a peering request for later reference.
This GUID format should be standardized across all requests.
This GUID should be provided by the receiver once it receives the request and must be embedded in all communication.
If there is no RequestID present then that should be interpreted as a new request and the process starts again.
An email address is needed for communication if the API fails or is not implemented properly (can be obtained through PeeringDB).</t>
      <t>For a programmatic specification of the API, please see the public Github here: <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref></t>
      <t>This initial draft fully specifies the Public Peering endpoints. Private Peering and Maintenance are under discussion, and the authors invite collaboration and discussion from interested parties.</t>
      <section anchor="datatypes">
        <name>DATA TYPES</name>
        <t>As defined in <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref>.
Please see specification for OpenAPI format.</t>
        <t>Peering Location</t>
        <t>Contains string field listing the desired peering location in format <tt>pdb:ix:$IX_ID</tt>, and an enum specifying peering type (public or private).</t>
        <t>Session Status</t>
        <t>Status of BGP Session, both as connection status and approval status (Established, Pending, Approved, Rejected, Down, Unestablished, etc)</t>
        <t>Session Array</t>
        <t>Array of potential BGP sessions, with request UUID.
  Request UUID is optional for client, and required for server.
  Client may provide initial UUID for client-side tracking, but the server UUID will be the final definitive ID.  RequestID will not change across the request.</t>
        <t>BGP Session</t>
        <t>A structure that describes a BGP session and contains the following elements:</t>
        <ul spacing="normal">
          <li>
            <t>local_asn (ASN of requestor)</t>
          </li>
          <li>
            <t>local_ip (IP of requestor, v4 or v6)</t>
          </li>
          <li>
            <t>peer_asn (server ASN)</t>
          </li>
          <li>
            <t>peer_ip (server-side IP)</t>
          </li>
          <li>
            <t>peer_type (public or private)</t>
          </li>
          <li>
            <t>md5 (optional, as defined above)</t>
          </li>
          <li>
            <t>location (Peering Location, as defined above)</t>
          </li>
          <li>
            <t>status (Session Status, as defined above)</t>
          </li>
          <li>
            <t>session_id (of individual session generated by the server. Client provides a item ID to track the session within the request, but the server's session ID will be the final definitive ID)</t>
          </li>
        </ul>
        <t>Error</t>
        <t>API Errors, for field validation errors in requests, and request-level errors.</t>
        <t>The above is sourced largely from the linked OpenAPI specification.</t>
      </section>
      <section anchor="endpoints">
        <name>Endpoints</name>
        <t>(As defined in <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref>)
On each call, there should be rate limits, allowed senders, and other optional restrictions.</t>
        <section anchor="public_peering_ix">
          <name>Public Peering over an Internet Exchange (IX)</name>
          <ul spacing="normal">
            <li>
              <t><tt>/sessions</tt>: ADD/RETRIEVE sessions visible to the calling PEER
              </t>
              <ul spacing="normal">
                <li>
                  <t>Batch create new session resources
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Establish new BGP sessions between peers, at the desired exchange.</t>
                    </li>
                    <li>
                      <t>Below is based on OpenAPI specification: <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref></t>
                    </li>
                    <li>
                      <t><tt>POST /sessions</tt>
                      </t>
                      <ul spacing="normal">
                        <li>
                          <t>Request body: Session Array</t>
                        </li>
                        <li>
                          <t>Responses:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>200 OK:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: Session Array (all sessions in request accepted for configuration).</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>300:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: Modified Session Array, with rejected or additional sessions.</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>400:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Error</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>403:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Unauthorized to perform the operation</t>
                                </li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>List all session resources. The response is paginated.
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Given a request ID, query for the status of that request.</t>
                    </li>
                    <li>
                      <t>Given an ASN without request ID, query for status of all connections between client and server.</t>
                    </li>
                    <li>
                      <t>Below is based on OpenAPI specification: <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref></t>
                    </li>
                    <li>
                      <t><tt>GET /sessions</tt>
                      </t>
                      <ul spacing="normal">
                        <li>
                          <t>Request parameters:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>asn (requesting client's asn)</t>
                            </li>
                            <li>
                              <t>request_id (optional, UUID of request)</t>
                            </li>
                            <li>
                              <t>max_results (integer to indicate an upper bound for a given response page)</t>
                            </li>
                            <li>
                              <t>next_token (opaque string to hint the query and last result returned when fetching a new page)</t>
                            </li>
                          </ul>
                        </li>
                        <li>
                          <t>Response:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>200: OK
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: Session Array of sessions in request_id, if provided. Else, all existing and in-progress sessions between client ASN and server.
                                  </t>
                                  <ul spacing="normal">
                                    <li>
                                      <t>next_token (opaque string for clients to use when retrieving a new page)</t>
                                    </li>
                                  </ul>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>400:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Error (example: request_id is invalid)</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>403:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Unauthorized to perform the operation</t>
                                </li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>
            <li>
              <t><tt>/sessions/{session_id}</tt>: Operate on individual sessions
              </t>
              <ul spacing="normal">
                <li>
                  <t>Retrieve an existing session resource
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Below is based on OpenAPI specification: <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref></t>
                    </li>
                    <li>
                      <t><tt>GET /sessions/{session_id}</tt>
                      </t>
                      <ul spacing="normal">
                        <li>
                          <t>Request parameters:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>session_id returned by the server on creation or through the session list operation.</t>
                            </li>
                          </ul>
                        </li>
                        <li>
                          <t>Responses:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>200 OK:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: Session structure with current attributes</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>400:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Error (example: session_id is invalid)</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>403:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Unauthorized to perform the operation</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>404:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>The session referred by the specified session_id does not exist or is not visible to the caller</t>
                                </li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>Delete a session.
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Given a session ID, delete it which effectively triggers an depeering from the initiator.</t>
                    </li>
                    <li>
                      <t>Below is based on OpenAPI specification: <eref target="https://github.com/bgp/autopeer/blob/main/api/openapi.yaml">https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</eref></t>
                    </li>
                    <li>
                      <t><tt>DELETE /sessions/{session_id}</tt>
                      </t>
                      <ul spacing="normal">
                        <li>
                          <t>Request parameters:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>session_id returned by the server on creation or through the session list operation.</t>
                            </li>
                          </ul>
                        </li>
                        <li>
                          <t>Response:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>204: OK
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: empty response as the session is processed and hard deleted</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>400:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Error (example: session_id is invalid)</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>403:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Unauthorized to perform the operation</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>404:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>The session referred by the specified session_id does not exist or is not visible to the caller</t>
                                </li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>
          </ul>
        </section>
        <section anchor="utility_api">
          <name>UTILITY API CALLS</name>
          <t>Endpoints which provide useful information for potential interconnections.</t>
          <ul spacing="normal">
            <li>
              <t><tt>/locations</tt>: LIST POTENTIAL PEERING LOCATIONS
              </t>
              <ul spacing="normal">
                <li>
                  <t>List potential peering locations, both public and private. The response is paginated.
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Below is based on OpenAPI specification: https://github.com/bgp/autopeer/blob/main/api/openapi.yaml</t>
                    </li>
                    <li>
                      <t><tt>GET /locations</tt>
                      </t>
                      <ul spacing="normal">
                        <li>
                          <t>Request parameters:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>asn (Server ASN, with which to list potential connections)</t>
                            </li>
                            <li>
                              <t>location_type (Optional: Peering Location)</t>
                            </li>
                            <li>
                              <t>max_results (integer to indicate an upper bound for a given response page)</t>
                            </li>
                            <li>
                              <t>next_token (opaque string to hint the query and last result returned when fetching a new page)</t>
                            </li>
                          </ul>
                        </li>
                        <li>
                          <t>Response:
                          </t>
                          <ul spacing="normal">
                            <li>
                              <t>200: OK
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Contents: List of Peering Locations.
                                  </t>
                                  <ul spacing="normal">
                                    <li>
                                      <t>next_token (opaque string for clients to use when retrieving a new page)</t>
                                    </li>
                                  </ul>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>400:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Error</t>
                                </li>
                              </ul>
                            </li>
                            <li>
                              <t>403:
                              </t>
                              <ul spacing="normal">
                                <li>
                                  <t>Unauthorized to perform the operation</t>
                                </li>
                              </ul>
                            </li>
                          </ul>
                        </li>
                      </ul>
                    </li>
                  </ul>
                </li>
              </ul>
            </li>
          </ul>
        </section>
        <section anchor="private-peering-draft">
          <name>Private Peering (DRAFT)</name>
          <ul spacing="normal">
            <li>
              <t>ADD/AUGMENT PNI</t>
            </li>
            <li>
              <t>Parameters:
              </t>
              <ul spacing="normal">
                <li>
                  <t>Peer ASN</t>
                </li>
                <li>
                  <t>Facility</t>
                </li>
                <li>
                  <t>email address (contact)</t>
                </li>
                <li>
                  <t>Action type: add/augment</t>
                </li>
                <li>
                  <t>LAG struct:
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>IPv4</t>
                    </li>
                    <li>
                      <t>IPv6</t>
                    </li>
                    <li>
                      <t>Circuit ID</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>Who provides LOA? (and where to provide it).</t>
                </li>
              </ul>
            </li>
            <li>
              <t>Response:
              </t>
              <ul spacing="normal">
                <li>
                  <t>200:
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>LAG struct, with server data populated</t>
                    </li>
                    <li>
                      <t>LOA or way to receive it</t>
                    </li>
                    <li>
                      <t>Request ID</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>300:
                  </t>
                  <ul spacing="normal">
                    <li>
                      <t>Proposed Modification: LAG struct, LOA, email address for further discussion</t>
                    </li>
                  </ul>
                </li>
                <li>
                  <t>40x: rejections</t>
                </li>
              </ul>
            </li>
            <li>
              <t>REMOVE PNI
              </t>
              <ul spacing="normal">
                <li>
                  <t>As ADD/AUGMENT in parameters. Responses will include a requestID and status.</t>
                </li>
              </ul>
            </li>
          </ul>
        </section>
      </section>
    </section>
    <section anchor="session_negotiation">
      <name>Public Peering Session Negotiation</name>
      <t>As part of public peering configuration, this draft must consider how the client and server should handshake at which sessions to configure peering.
At first, a client will request sessions A, B, and C.
The server may choose to accept all sessions A, B, and C.
At this point, configuration proceeds as normal.
However, the server may choose to reject session B.
At that point, the server will reply back with A and C marked as "Accepted," and B as "Rejected."
The server will then configure A and C, and wait for the client to configure A and C.
If the client configured B as well, it will not come up.</t>
      <t>This draft encourages peers to set up garbage collection for unconfigured or down peering sessions, to remove stale configuration and maintain good router hygiene.</t>
      <t>Related to rejection, if the server would like to configure additional sessions with the client, the server may either reject all the session that do not meet the criteria caused by such absence in the client's request or approve the client's request and issue a separate request to the client's server requesting those additional peering sessions D and E.
The server will configure D and E on their side, and D and E will become part of the sessions requested in the UUID.
The client may choose whether or not to accept those additional sessions.
If they do, the client should configure D and E as well.
If they do not, the client will not configure D and E, and the server should garbage-collect those pending sessions.</t>
      <t>As part of the IETF discussion, the authors would like to discuss how to coordinate which side unfilters first.
Perhaps this information could be conveyed over a preferences vector.</t>
    </section>
    <section anchor="private_peering">
      <name>Private Peering</name>
      <t>Through future discussion with the IETF, the specification for private peering will be solidified.
Of interest for discussion includes Letter of Authorization (LOA) negotiation, and how to coordinate unfiltering and configuration checks.</t>
    </section>
    <section anchor="maintenance">
      <name>Maintenance</name>
      <t>This draft does not want to invent a new ticketing system.
However, there is an opportunity in this API to provide maintenance notifications to peering partners.
If there is interest, this draft would extend to propose a maintenance endpoint, where the server could broadcast upcoming and current maintenance windows.</t>
      <t>A maintenance message would follow a format like:</t>
      <ul spacing="normal">
        <li>
          <t>Title: string</t>
        </li>
        <li>
          <t>Start Date: date maintenance start(s/ed): UTC</t>
        </li>
        <li>
          <t>End Date: date maintenance ends: UTC</t>
        </li>
        <li>
          <t>Area: string or enum</t>
        </li>
        <li>
          <t>Details: freeform string</t>
        </li>
      </ul>
      <t>The "Area" field could be a freeform string, or could be a parseable ENUM, like (BGP, PublicPeering, PrivatePeering, Configuration, Caching, DNS, etc).</t>
      <t>Past maintenances will not be advertised.</t>
    </section>
    <section anchor="extensions">
      <name>Possible Extensions</name>
      <t>The authors acknowledge that route-server configuration may also be of interest for this proposed API, and look forward to future discussions in this area.</t>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="autopeer" target="https://github.com/bgp/autopeer/">
          <front>
            <title>Github respository with the API specification and diagrams</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="oidc" target="https://openid.net/specs/openid-connect-core-1_0.html">
          <front>
            <title>OpenID.Core</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="rest" target="http://roy.gbiv.com/pubs/dissertation/top.htm">
          <front>
            <title>Architectural Styles and the Design of Network-based Software Architectures</title>
            <author initials="R. T." surname="Fielding" fullname="Roy Thomas Fielding">
              <organization/>
            </author>
            <date year="2000"/>
          </front>
        </reference>
        <reference anchor="openapi" target="https://spec.openapis.org/oas/v3.1.0">
          <front>
            <title>OpenAPI-v3.1.0</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="RFC6749">
          <front>
            <title>The OAuth 2.0 Authorization Framework</title>
            <author fullname="D. Hardt" initials="D." role="editor" surname="Hardt"/>
            <date month="October" year="2012"/>
            <abstract>
              <t>The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification replaces and obsoletes the OAuth 1.0 protocol described in RFC 5849. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6749"/>
          <seriesInfo name="DOI" value="10.17487/RFC6749"/>
        </reference>
        <reference anchor="RFC7519">
          <front>
            <title>JSON Web Token (JWT)</title>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <author fullname="J. Bradley" initials="J." surname="Bradley"/>
            <author fullname="N. Sakimura" initials="N." surname="Sakimura"/>
            <date month="May" year="2015"/>
            <abstract>
              <t>JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7519"/>
          <seriesInfo name="DOI" value="10.17487/RFC7519"/>
        </reference>
        <reference anchor="RFC9068">
          <front>
            <title>JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens</title>
            <author fullname="V. Bertocci" initials="V." surname="Bertocci"/>
            <date month="October" year="2021"/>
            <abstract>
              <t>This specification defines a profile for issuing OAuth 2.0 access tokens in JSON Web Token (JWT) format. Authorization servers and resource servers from different vendors can leverage this profile to issue and consume access tokens in an interoperable manner.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9068"/>
          <seriesInfo name="DOI" value="10.17487/RFC9068"/>
        </reference>
        <reference anchor="RFC8725">
          <front>
            <title>JSON Web Token Best Current Practices</title>
            <author fullname="Y. Sheffer" initials="Y." surname="Sheffer"/>
            <author fullname="D. Hardt" initials="D." surname="Hardt"/>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <date month="February" year="2020"/>
            <abstract>
              <t>JSON Web Tokens, also known as JWTs, are URL-safe JSON-based security tokens that contain a set of claims that can be signed and/or encrypted. JWTs are being widely used and deployed as a simple security token format in numerous protocols and applications, both in the area of digital identity and in other application areas. This Best Current Practices document updates RFC 7519 to provide actionable guidance leading to secure implementation and deployment of JWTs.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="225"/>
          <seriesInfo name="RFC" value="8725"/>
          <seriesInfo name="DOI" value="10.17487/RFC8725"/>
        </reference>
        <reference anchor="RFC6750">
          <front>
            <title>The OAuth 2.0 Authorization Framework: Bearer Token Usage</title>
            <author fullname="M. Jones" initials="M." surname="Jones"/>
            <author fullname="D. Hardt" initials="D." surname="Hardt"/>
            <date month="October" year="2012"/>
            <abstract>
              <t>This specification describes how to use bearer tokens in HTTP requests to access OAuth 2.0 protected resources. Any party in possession of a bearer token (a "bearer") can use it to get access to the associated resources (without demonstrating possession of a cryptographic key). To prevent misuse, bearer tokens need to be protected from disclosure in storage and in transport. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6750"/>
          <seriesInfo name="DOI" value="10.17487/RFC6750"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="RFC4271">
          <front>
            <title>A Border Gateway Protocol 4 (BGP-4)</title>
            <author fullname="Y. Rekhter" initials="Y." role="editor" surname="Rekhter"/>
            <author fullname="T. Li" initials="T." role="editor" surname="Li"/>
            <author fullname="S. Hares" initials="S." role="editor" surname="Hares"/>
            <date month="January" year="2006"/>
            <abstract>
              <t>This document discusses the Border Gateway Protocol (BGP), which is an inter-Autonomous System routing protocol.</t>
              <t>The primary function of a BGP speaking system is to exchange network reachability information with other BGP systems. This network reachability information includes information on the list of Autonomous Systems (ASes) that reachability information traverses. This information is sufficient for constructing a graph of AS connectivity for this reachability from which routing loops may be pruned, and, at the AS level, some policy decisions may be enforced.</t>
              <t>BGP-4 provides a set of mechanisms for supporting Classless Inter-Domain Routing (CIDR). These mechanisms include support for advertising a set of destinations as an IP prefix, and eliminating the concept of network "class" within BGP. BGP-4 also introduces mechanisms that allow aggregation of routes, including aggregation of AS paths.</t>
              <t>This document obsoletes RFC 1771. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4271"/>
          <seriesInfo name="DOI" value="10.17487/RFC4271"/>
        </reference>
        <reference anchor="RFC6480">
          <front>
            <title>An Infrastructure to Support Secure Internet Routing</title>
            <author fullname="M. Lepinski" initials="M." surname="Lepinski"/>
            <author fullname="S. Kent" initials="S." surname="Kent"/>
            <date month="February" year="2012"/>
            <abstract>
              <t>This document describes an architecture for an infrastructure to support improved security of Internet routing. The foundation of this architecture is a Resource Public Key Infrastructure (RPKI) that represents the allocation hierarchy of IP address space and Autonomous System (AS) numbers; and a distributed repository system for storing and disseminating the data objects that comprise the RPKI, as well as other signed objects necessary for improved routing security. As an initial application of this architecture, the document describes how a legitimate holder of IP address space can explicitly and verifiably authorize one or more ASes to originate routes to that address space. Such verifiable authorizations could be used, for example, to more securely construct BGP route filters. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6480"/>
          <seriesInfo name="DOI" value="10.17487/RFC6480"/>
        </reference>
        <reference anchor="RFC9323">
          <front>
            <title>A Profile for RPKI Signed Checklists (RSCs)</title>
            <author fullname="J. Snijders" initials="J." surname="Snijders"/>
            <author fullname="T. Harrison" initials="T." surname="Harrison"/>
            <author fullname="B. Maddison" initials="B." surname="Maddison"/>
            <date month="November" year="2022"/>
            <abstract>
              <t>This document defines a Cryptographic Message Syntax (CMS) protected content type for use with the Resource Public Key Infrastructure (RPKI) to carry a general-purpose listing of checksums (a 'checklist'). The objective is to allow for the creation of an attestation, termed an "RPKI Signed Checklist (RSC)", which contains one or more checksums of arbitrary digital objects (files) that are signed with a specific set of Internet Number Resources. When validated, an RSC confirms that the respective Internet resource holder produced the RSC.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9323"/>
          <seriesInfo name="DOI" value="10.17487/RFC9323"/>
        </reference>
        <reference anchor="RFC9092">
          <front>
            <title>Finding and Using Geofeed Data</title>
            <author fullname="R. Bush" initials="R." surname="Bush"/>
            <author fullname="M. Candela" initials="M." surname="Candela"/>
            <author fullname="W. Kumari" initials="W." surname="Kumari"/>
            <author fullname="R. Housley" initials="R." surname="Housley"/>
            <date month="July" year="2021"/>
            <abstract>
              <t>This document specifies how to augment the Routing Policy Specification Language inetnum: class to refer specifically to geofeed data comma-separated values (CSV) files and describes an optional scheme that uses the Routing Public Key Infrastructure to authenticate the geofeed data CSV files.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9092"/>
          <seriesInfo name="DOI" value="10.17487/RFC9092"/>
        </reference>
        <reference anchor="RFC3912">
          <front>
            <title>WHOIS Protocol Specification</title>
            <author fullname="L. Daigle" initials="L." surname="Daigle"/>
            <date month="September" year="2004"/>
            <abstract>
              <t>This document updates the specification of the WHOIS protocol, thereby obsoleting RFC 954. The update is intended to remove the material from RFC 954 that does not have to do with the on-the-wire protocol, and is no longer applicable in today's Internet. This document does not attempt to change or update the protocol per se, or document other uses of the protocol that have come into existence since the publication of RFC 954. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="3912"/>
          <seriesInfo name="DOI" value="10.17487/RFC3912"/>
        </reference>
      </references>
    </references>
    <?line 491?>

<section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The authors would like to thank their collaborators, who implemented API versions and provided valuable feedback on the design.</t>
      <ul spacing="normal">
        <li>
          <t>Ben Blaustein (Meta)</t>
        </li>
        <li>
          <t>Jakub Heichman (Meta)</t>
        </li>
        <li>
          <t>Stefan Prattner (20c)</t>
        </li>
        <li>
          <t>Ben Ryall (Meta)</t>
        </li>
        <li>
          <t>Erica Salvaneschi (Cloudflare)</t>
        </li>
        <li>
          <t>Job Snijders (Fastly)</t>
        </li>
        <li>
          <t>David Tuber (Cloudflare)</t>
        </li>
      </ul>
    </section>
  </back>
  <!-- ##markdown-source:
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
fF6El2BhAAA=

-->

</rfc>
