Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

[1] OAuth 2.0 (RFC 6749)

[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)

[5] OpenID Connect Core 1.0

[6] OAuth 2.0 for Native Apps (RFC 8252)