SSB HTTP Authentication

Revision: 2021-04-26

Author: Andre Medeiros contact@staltz.com

License: This work is licensed under a Creative Commons Attribution 4.0 International License.

Abstract

SSB is a peer-to-peer system where there should not be a client-server distinction, but there are exceptions to this nature. "Pub servers" and "room servers" are nodes with privileged internet-wide presence that can provide replication and tunneled-connection services to several peers. Since these servers often also host a public HTTP interface, concern has been raised on how authenticated clients are to interact with these services over HTTP when requesting access-restricted resources. SSB HTTP Authentication is a protocol that utilizes both SSB muxrpc and HTTPS to grant an HTTP client (such as a browser) access to resources authorized for the SSB client peer.

Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Table of contents

Conditions

This specification makes clear assumptions about the setup involved peers authenticating.

Server: an SSB peer, known as the "server", MUST have an internet-public host address, MUST be accessible for secret-handshake connections under a multiserver address, and MUST support HTTPS requests as well as it MUST NOT support plain HTTP.

Client: another SSB peer, known as the "client", MUST be able to open a secret-handshake and muxrpc connection with the server. The user controlling this SSB peer also SHOULD control a web browser used to make requests to the server. The client's browser and operating system SHOULD support hyperlinks to SSB URIs, redirecting them to SSB applications that recognize and parse SSB URIs. The client's SSB application employed during SSB HTTP Authentication MUST be able to recognize and parse SSB URIs.

Connections: the server and the client SHOULD recognize each other's SSB IDs as mutually trusted (such as a mutual follow relationship, or "membership" relationship where the client has claimed an invite token from the server). For the authentication protocol described in this document to succeed, the two SSB peers MUST be connected to each other via muxrpc and secret-handshake for the entire duration of the protocol. The purpose of SSB HTTP Authentication is to extend the trust that exists between these peers from the muxrpc context to the context of HTTP in the browser.

Specification

A client known by its SSB ID cid is connected via secret-handshake and muxrpc to a server known by its SSB ID sid. The server is hosted at serverHost. A browser controlled by the same person or agent as the cid peer wishes to request an access-restricted resource (such as an admin dashboard) at the server over HTTP. All HTTP requests MUST be done with HTTPS.

The three sides (browser client, SSB client cid, and SSB server sid) perform a challenge-response authentication protocol, specified as UML sequence diagrams. We use the shorthands sc, cc, and sol to mean:

The challenges, cc and sc, are 256-bit cryptographic nonces encoded in base64. The solution sol is a cryptographic signature using the cryptographic keypair cid that identifies the client, described below:

Both sides generate the nonces, but there are use cases where one side should start first. In other words, the challenge-response protocol described here can be either client-initiated or server-initiated.

The HTTPS endpoint /login with the query parameter ssb-http-auth MUST be employed as specified here, but URLs for logging out and for Server-Sent Events (SSE) are left unspecified and implementations are free to choose their routes. The muxrpc APIs httpAuth.requestSolution(sc, cc), httpAuth.sendSolution(sc, cc, cr), httpAuth.invalidateAllSolutions() and the SSB URI ssb:experimental?action=start-http-auth&sid=${sid}&sc=${sc} MUST be employed as specified here.

Client-initiated protocol

In the client-initiated variant of the challenge-response protocol, the first step is the client creating cc and opening a web page in the browser. Then, the server attending to that HTTP request will call httpAuth.requestSolution(sc, cc) on the client SSB peer.

The UML sequence diagram for the whole client-initial protocol is shown below:

sequenceDiagram participant Umux as SSB client `cid` participant Uweb as Browser client participant Serv as SSB server `sid` note over Umux: Generates
challenge `cc` Umux->>Uweb: `https://${serverHost}/login
?ssb-http-auth=1&cid=${cid}&cc=${cc}` Uweb->>+Serv: `https://${serverHost}/login
?ssb-http-auth=1&cid=${cid}&cc=${cc}` Note over Serv: Generates
challenge `sc` alt client is disconnected from the server Serv-->>Uweb: HTTP 403 else client is connected to the server Serv->>+Umux: (muxrpc async) `httpAuth.requestSolution(sc, cc)` Note over Umux: Generates
signature `sol` Umux-->>-Serv: respond httpAuth.requestSolution with `sol` alt `sol` is incorrect Serv-->>Uweb: HTTP 403 else `sol` is correct Serv-->>-Uweb: HTTP 200, auth token Note over Uweb: Stores auth token as a cookie end end

Server-initiated protocol

In the server-initiated variant of the challenge-response protocol, the first step is the browser requesting a login from the server without any input data. The server answers the browser, which in turn displays an SSB URI which the SSB peer knows how to open.

The primary difference between this variant and the previous one is that the muxrpc async RPC call direction is reversed. Previously, the server called httpAuth.requestSolution on the client. In this variant, the client calls httpAuth.sendSolution on the server. The response is also different. In the previous case, the client's response is expected to be the sol. In this variant, the sol argument is provided by the client and the server's response is expected to be true.

The secondary difference with this variant is the addition of Server-Sent Events (SSE) between the browser and the server, to update the browser when the muxrpc protocol succeeds.

The UML sequence diagram for the whole server-initial protocol is shown below:

sequenceDiagram participant Umux as SSB client `cid` participant Uweb as Browser client participant Serv as SSB server `sid` Uweb->>Serv: Some URL on the `serverHost` activate Serv Note over Serv: Generates
challenge `sc` Serv-->>Uweb: Displays `ssb:experimental?
action=start-http-auth&sid=${sid}&sc=${sc}` Uweb->>Serv: Subscribe to some SSE URL with `sc` as input Uweb->>Umux: Consumes SSB URI Note over Umux: Generates
challenge `cc` Note over Umux: Generates
signature `sol` Umux->>+Serv: (muxrpc async) `httpAuth.sendSolution(sc, cc, sol)` alt `sol` is incorrect, or other errors Serv-->>Umux: `false` Serv-->>Uweb: (SSE) "redirect to ${url}" Uweb->>+Serv: GET `${url}` Serv-->>-Uweb: HTTP 403 else `sol` is correct Serv-->>-Umux: `true` Serv-->>Uweb: (SSE) "redirect to ${url}" Uweb->>+Serv: GET `${url}` Serv-->>-Uweb: HTTP 200, auth token deactivate Serv Note over Uweb: Stores auth token as a cookie end

The SSB URI MAY also contain the query parameter multiserverAddress with value msaddr matching the server's multiserver address, in case the client does not know how to map the server's sid to a multiserver address in order to call the muxrpc http.sendSolution:

ssb:experimental?action=start-http-auth&sid=${sid}&sc=${sc}&multiserverAddress=${msaddr}

Sign-out

An optional (but recommended) muxrpc API httpAuth.invalidateAllSolutions on the server to allow the SSB peer to invalidate all auth tokens associated with the cid. See UML sequence diagram:

sequenceDiagram participant Umux as SSB client `cid` participant Uweb as Browser client participant Serv as SSB server `sid` Umux->>+Serv: (muxrpc async) `httpAuth.invalidateAllSolutions()` Note over Serv: Invalidates every `sc`
and `authtoken` associated
with `cid` Serv-->>-Umux: respond httpAuth.invalidateAllSolutions with `true` Note over Uweb,Serv: Potentially thereafter... Uweb->>+Serv: Authenticate using `authtoken` Serv-->>-Uweb: HTTP 401

The browser client also has the option of signing out with HTTP endpoints. This does not require a muxrpc call with the SSB peer. See UML sequence diagram:

sequenceDiagram participant Uweb as Browser client participant Serv as SSB server `sid` Uweb->>+Serv: Some URL on the `serverHost` Note over Serv: Invalidates `authtoken` Serv-->>-Uweb: HTTP 200 Note over Uweb,Serv: Potentially thereafter... Uweb->>+Serv: Authenticate using `authtoken` Serv-->>-Uweb: HTTP 401

Security considerations

Because the sign-in process is seemless and happens in the background via muxrpc, without any input from the user who controls the client SSB peer, there is potential for vulnerabilities if the SSB URI is manipulated or the URL is manipulated.

SSB applications that control the client SSB peer therefore MUST prompt user consent before httpAuth.requestSolution or httpAuth.sendSolution are sent. The prompt SHOULD display the server's SSB ID and ask the user to confirm their intent to sign-in.

Client impersonation

To be done.

Tokens

To be done.

Appendix

List of required HTTP endpoints

List of new muxrpc APIs

List of new SSB URIs