...
In particular, we can aim to replace usage of the API key with OAuth refresh tokens. The most common use case for the API key is to authenticate Synapse command line clients. Using refresh/access tokens in place of an API key provides a couple of advantages:
Timed Leased/timed expiration - if a particular session isn’t used for 180 days, the token expires
The ability to grant/revoke access on the machine-level, instead of having one key used everywhere
Scoped access, in cases where the command line app is running a job that only needs a subset of access/functionality
Using either the authorization code (currently supported) or device code (not currently supported) OAuth 2 flows require users to login on Synapse.org via a browser, instead of entering credentials at the command line, or pasting an API key into a config file.
...
Each point in this section will be fleshed out with reasoning, pros, cons, etc. and then consolidated once confident in what’s necessary.
PKCE
TODO
Can’t require it from all clients bc breaking API change
Require it just for public clients?
Designating new clients as public/confidential
OAuth 2.1 suggests doing so:
...
Best practices suggest that authorization servers are required to support PKCE [2][4]. PKCE only provides benefits to public OAuth clients, since a malicious app must have knowledge of an OAuth client’s credentials to execute the attack.
PKCE in a nutshell
PKCE prevents a malicious application from hijacking an authorization code. This can occur when using a native app’s OAuth client, and the redirect URI is compromised by a malicious application. In this scenario, the malicious app has the authorization code, and is in possession of the client’s credentials (if they exist), because it is a public client. Thus the malicious app now has access to the user’s account.
With PKCE, the client generates a high-entropy random string, and calculates the SHA256 hash of the string. When making the initial authorization request, the hash is sent to the authorization server. The authorization server associates the hash with the authorization code, before sending it to the client (the hash may be embedded)
When a client uses the authorization code, they must provide the initial random string. The authorization server computes the SHA256 hash of the string, and will only issue token(s) to the client if the hashes match.
Designating new clients as either public or confidential
All existing clients are considered to be “confidential” clients, so we can easily backfill that information.
We can also use the public/private
Authorization servers MUST record the client type in the client registration details in order to identify and process requests accordingly.
By doing this, we can require that public clients utilize
Public clients may or may not be issued credentials
...
TODO: Look into implementation and costs/benefits of binding tokens to clients
Refresh token rotation is implemented, but we currently do not revoke an active token if an invalid token is used (so an attacker could hijack the session). Should we implement this? If so, should this be the behavior for confidential clients as well?
...
Resources and References
[2] OAuth 2.1 (IETF Draft, last updated 2020 April 24)
[3] OAuth 2.0 for Browser-Based Apps (IETF Draft, last updated 2020 April 05)
[4] OAuth 2.0 Security Best Current Practice (IETF Draft, last updated 2020 April 05)