Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 110 additions & 0 deletions proposals/4363-oauth-step-up-authentication.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation requirements:

  • Client (ideally multiple)
  • Server

Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# MSC4363: OAuth step up authentication

Homeservers may want to enforce re-authentication to guard access to potentially severe user actions
such as deactivating an account or logging out all devices. Prior to the [OAuth APIs] introduced in
Matrix 1.15, this was handled by an API called [User-Interactive Authentication (UIA)]. UIA is
incompatible with the new [OAuth APIs], however, leading to suboptimal workarounds such as
[MSC4312].

Fortunately, OAuth itself provides a scheme for elevating access rights with [RFC9470] (OAuth 2.0
Step Up Authentication Challenge Protocol). The present proposal generalizes [RFC9470] for use with
Matrix.

## Proposal

The following description assumes that the client has authenticated via the [OAuth APIs].

When a homeserver determines that the authentication event associated with the access token
presented on a request is insufficient, it MAY respond with HTTP 401 and a new error code
`M_INSUFFICIENT_USER_AUTHENTICATION`. Three optional top-level properties are allowed in the
response to convey the authentication requirements challenge back to the client:

- `acr_values`: A space-separated string listing the authentication context class reference (ACR)
values in order of preference.[^1] The protected resource requires *one* of these values for the
authentication event associated with the access token.
- `max_age`: A non-negative integer specifying the allowable elapsed time in seconds since the last
active authentication event associated with the access token.
- `scope`: A space-separated string listing the *full* set of scopes that are required to access the
protected resource.

The following is an example of an error response that requests authentication using either any 2FA
method, or, failing that, password-based authentication. Additionally, a maximum elapsed time since
authentication of 5 minutes is required. The ACR values were taken from [Okta's reference].

``` json5
{
"errcode": "M_INSUFFICIENT_USER_AUTHENTICATION",
"error": "Additional authentication required to complete request",
"acr_values": "urn:okta:loa:2fa:any urn:okta:loa:1fa:pwd",
"max_age": 300,
}
```

A client receiving a challenge SHOULD use the `acr_values`, `max_age` and `scope` properties to
construct a new authorization request. For this purpose, `acr_values` and `max_age` are added to the
[current list of request parameters] using the same definition given above.

Following successful authentication, the client can use the new access token to repeat the original
request.

### Aspects that are out of scope

This proposal consciously leaves a number of things undefined.

Firstly, the act of evaluating whether or not an access token meets a resource's requirements is
left as an implementation detail between the homeserver and the authorization server. As per
[RFC9470], this can, for instance, be achieved by encoding the access token with additional
properties in JWT format or through a dedicated token introspection endpoint.

Furthermore, no concrete ACR values are specified. Again, this is a detail to arrange between the
homeserver and the authorization server as ACR values are not intended for introspection by clients.

Finally, it is left up to the authorization server to determine how exactly the `acr_values`,
`max_age` and `scope` parameters are used during authentication. Implementations should, however,
note the recommendations in [RFC9470].

## Potential issues

None apparent.

## Alternatives

The scheme proposed in [MSC4312] (ab)uses UIA to deeplink into the authorization server's account
management UI. This is less flexible and powerful than OAuth step up authentication, however. It is
also contrary to the idea of standardizing authentication in Matrix on OAuth mechanisms.

## Security considerations

The security impact of this proposal largely follows [RFC9470].

Depending on the concrete values used in the `acr_values` parameter, it is possible to leak
information about the authenticated user, the protected resource, the authorization server, and any
other context-specific data. This risk can be controlled by implementations deciding on the values.

To prevent leaking required properties of an authorization token to an actor who has not proven they
can obtain a token, homeservers SHOULD NOT return a challenge without verifying the client presented
a valid token.

## Unstable prefix

While this MSC is not considered stable, the following replacements should be used in the
homeserver's error response:

- `M_INSUFFICIENT_USER_AUTHENTICATION` → `org.matrix.msc4363.M_INSUFFICIENT_USER_AUTHENTICATION`
- `acr_values` → `org.matrix.msc4363.acr_values`
- `max_age` → `org.matrix.msc4363.max_age`
- `scope` → `org.matrix.msc4363.scope`

The new authorization request parameters should not use prefixes since they follow standard OAuth.

[^1]: As defined in the [OIDC core specification], the authentication context conveys information
about how authentication takes place (e.g., what authentication method(s) or assurance level to
meet).

[OAuth APIs]: https://spec.matrix.org/v1.15/client-server-api/#oauth-20-api
[User-Interactive Authentication (UIA)]: https://spec.matrix.org/v1.16/client-server-api/#user-interactive-authentication-api
[MSC4312]: https://github.com/matrix-org/matrix-spec-proposals/pull/4312
[RFC9470]: https://datatracker.ietf.org/doc/rfc9470/
[Okta's reference]: https://developer.okta.com/docs/guides/step-up-authentication/main/
[current list of request parameters]: https://spec.matrix.org/v1.15/client-server-api/#login-flow
[OIDC core specification]: https://openid.net/specs/openid-connect-core-1_0.html#Terminology