Hazelnoot<p>Concept for discussion: <b>Replacing HTTP Signatures with Bearer Tokens for ActivityPub Federation</b><span><br><br>Curious what other people think about this idea. What if federation security was re-worked to use target-assigned </span><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Authentication#bearer" rel="nofollow noopener" target="_blank">bearer tokens</a><span> to authenticate GET/POST requests? This would remove the need for complicated signing schemes and reduce system load under heavy traffic bursts (as no cryptography is required).<br><br></span><b>A basic implementation could look like this:</b><span><br>1. When instance A (</span><code>a.example.com</code>) first attempts to federate with instance B (<code>b.example.com</code>), a POST request is made to a dedicated registration endpoint. (for discussion, we'll say it's <code>https://b.example.com/activity-pub/register-instance</code>). This request includes fields necessary for verification, including the <b>source domain name</b>, <b>target domain name</b>, and a securely-generated <b>verification token</b><span>. Other metadata could be included to allow instance B to selectively allow/prohibit federation based on other criteria, but this is optional.<br>2. Instance B makes a POST request back to a dedicated verification endpoint on instance A (for discussion, we'll say it's </span><code>https://a.example.com/activity-pub/verify-registration</code><span>). This request must include the target domain name and verification token provided in step 2.<br>3. Instance A checks the verification token (and verify that it matches the target domain name) and return a successful value. </span><b>The verification code must be invalidated after this call!</b><span><br>4. Instance B, after verifying instance A's request, returns a securely-generated </span><b>federation key</b> back to instance A. This federation key is a bearer token used to authenticate all requests from instance A to instance B. <b>This key must be unique to instance A!</b><span><br>5. Instance A completes the original request with the </span><code>Authorization</code> header set to <code>Bearer {federation_key}</code><span>.<br>6. Instance B receives the request, detects the federation key, and checks it against the list of registered instances.<br>7. If the key does not exist or A has been defederated, then a </span><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/401" rel="nofollow noopener" target="_blank"><code>403 Forbidden</code> error</a><span> is returned.<br>8. If the key is expired or revoked, then </span><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/401" rel="nofollow noopener" target="_blank"><code>401 Unauthorized</code> error</a> is returned. Upon receiving a 401 error, instance A should start over from step 1 to re-authenticate and complete the request with a new token. <b>This process should not be repeated for recursive failures!</b><span><br>9. If the key is approved, then a </span><a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/200" rel="nofollow noopener" target="_blank"><code>200 OK</code> response</a> or <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status/202" rel="nofollow noopener" target="_blank"><code>202 Accepted</code> response</a><span> is returned, and A can consider the request as successful.<br><br></span><b>Advantages versus HTTP Signatures:</b><span><br>- No cryptography requirements.<br>- Simple logic, no edge cases around HTTP query parameters or header order.<br>- Equally effective for all request types.<br>- Keys can be easily revoked or rotated.<br>- Supports authorized fetch and defederation use cases "by default".<br><br></span><b>Disadvantages versus HTTP Signatures:</b><span><br>- Breaks the actor model - instances are required as a first-class concept. (but really, the actor model is basically dead already. you can't even federate reliably without a WebFinger server, at minimum.)<br>- Requires multi-request "handshake" before communication. (but this is already required in practice, since a signature can't be validated without first requesting the signing actor.)<br>- Out-of-band protocol - communication can't happen over ActivityPub / ActivityStreams because this is a prerequisite to authenticate any request. (but again, we already require WebFinger and some software requires NodeInfo for full support.)<br><br>So, what are your thoughts? Good idea? Bad idea? Did I miss something? Please let me know, I welcome replies here!<br><br></span><a href="https://enby.life/tags/ActivityPub" rel="nofollow noopener" target="_blank">#ActivityPub</a> <a href="https://enby.life/tags/AP" rel="nofollow noopener" target="_blank">#AP</a> <a href="https://enby.life/tags/Federation" rel="nofollow noopener" target="_blank">#Federation</a></p>