Versions Compared

Key

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

...

Requirements/Notes/Considerations

Each point in this section will be fleshed out with reasoning, pros, cons, etc. and then consolidated once confident in what’s necessaryThis section contains an explanation of each requirement for supporting OAuth 2 public clients in Synapse. This section is summarized at the top of this document, and services are enumerated at the bottom of this document.

PKCE

Best practices suggest that authorization servers are required to support PKCE [2][3]. 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 would require clients to generate a code and send a hash of the code to Synapse when initiating the authorization code OAuth flow. When redeeming the authorization code, the client must send the original code. Synapse would then hash the code and verify that the hash matches the initial hash sent by the client. must have knowledge of an OAuth client’s credentials to execute the attack.

For more details, expand the following section:

Expand
titlePKCE 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 observing traffic to the user agent (mobile app or web browser). 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 in the authorization code)

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.

...

Use of an expired refresh token invalidates the active refresh token

...

refresh token

The following would only apply to public OAuth clients because the refresh token acts as a bearer token. The goal is to reduce the risk and impact of token theft/replay attacks.

OAuth 2.1 ([2]) Note on refresh tokens for public clients:

...

We will use refresh token rotation because it is partially implemented (we currently do not revoke an active token if an expired token is used). We can extend our implementation to include this the missing behavior.

Token binding is also more complicatedcomplicated, so we won’t use it. For details, expand the following section.

...

Endpoint

Request Body

Response Body

Notes/Modifications

New Service?

POST /oauth2/client/

OAuthClient

OAuthClient

OAuthClient extended to require a new field clientType (enum with values PUBLIC,CONFIDENTIAL)

POST /oauth2/client/secret/{id}

None

OAuthClientIdAndSecret

Do not generate client secrets for public clients.

POST /oauth2/consent

OIDCAuthorizationRequest

OAuthAuthorizationResponse

OIDCAuthorizationRequest extended to include code_challenge, code_challenge_method. The fieldcode_challenge is required for clients of type PUBLIC.

POST /oauth2/token

Multiple parameters

OIDCTokenResponse

Additional request parameter code_verifier, required if the corresponding authorization code is associated with a code_challenge.

POST /oauth2/token

Multiple parameters

OIDCTokenResponse

Client secret not required if the client ID is a public client.

POST /oauth2/token

Multiple parameters

OIDCTokenResponse

If a public client uses an expired/rotated refresh token, revoke the current ‘version’ of the refresh token

(e.g. refresh token is abcd with ID: 7, when it is used, the new refresh token is efgh with ID: 7. if someone attempts to use abcd is used again, revoke efgh.

POST /oauth2/consent

POST /oauth2/token

-

-

Restrict client 0 from using these endpointsusing these endpoints (this is already the case, but it is unclear if it is explicit).

Support for first-party command line public clients

...

Endpoint

Request Body

Response Body

Notes

New Service?

N/A

N/A

N/A

Add a bootstrapped ‘Synapse Command Line’ OAuth client.

We use a new client and not client 0 for two reasons

  • If we add OAuth flows to command line apps, a user should see a prompt for authorizing ‘Synapse Command Line’, which they wouldn’t see for client 0

  • There is a limit on active refresh tokens per user-client combination. If we decide to use client 0 to issue refresh tokens elsewhere (e.g. for browser sessions), then they could interfere/invalidate command line sessions.

POST /oauth2/userGeneratedToken

OIDCTokenGenerationRequest {

name: string (a unique-to-the-user, human-readable name. if unspecified, this will be a UUID)

clientId: string (the client that can use the OAuth token)

scope: Array<OAuthScope> (scopes granted by the tokens)

claims: OIDCClaimsRequest (claims granted by the tokens)

}

OIDCTokenResponse

Generates a token response that users can copy and paste into the command line client. Effectively replaces API keys.

In most cases, the clientId will be set to the ID used for the bootstrapped command line client (SWC could even hard-code it, since users likely only need to generate tokens for this client).

...