diff --git a/api/client-server/administrative_contact.yaml b/api/client-server/administrative_contact.yaml index 0e93e4cd..30153bb0 100644 --- a/api/client-server/administrative_contact.yaml +++ b/api/client-server/administrative_contact.yaml @@ -110,10 +110,13 @@ paths: id_server: type: string description: The identity server to use. + id_access_token: + type: string + description: An access token previously registered with the identity server. sid: type: string description: The session identifier given by the identity server. - required: ["client_secret", "id_server", "sid"] + required: ["client_secret", "id_server", "id_access_token", "sid"] bind: type: boolean description: |- @@ -125,6 +128,7 @@ paths: example: { "three_pid_creds": { "id_server": "matrix.org", + "id_access_token": "abc123_OpaqueString", "sid": "abc123987", "client_secret": "d0n'tT3ll" }, @@ -189,6 +193,11 @@ paths: homeserver does not know the original ``id_server``, it MUST return a ``id_server_unbind_result`` of ``no-support``. example: "example.org" + id_access_token: + type: string + description: |- + An access token previously registered with the identity server. Required + if an ``id_server`` is specified. medium: type: string description: The medium of the third party identifier being removed. diff --git a/api/client-server/create_room.yaml b/api/client-server/create_room.yaml index bce61aad..d7a29d99 100644 --- a/api/client-server/create_room.yaml +++ b/api/client-server/create_room.yaml @@ -139,6 +139,9 @@ paths: id_server: type: string description: The hostname+port of the identity server which should be used for third party identifier lookups. + id_access_token: + type: string + description: An access token previously registered with the identity server. medium: type: string # TODO: Link to Identity Service spec when it eixsts @@ -146,7 +149,7 @@ paths: address: type: string description: The invitee's third party identifier. - required: ["id_server", "medium", "address"] + required: ["id_server", "id_access_token", "medium", "address"] room_version: type: string description: |- diff --git a/api/client-server/definitions/openid_token.yaml b/api/client-server/definitions/openid_token.yaml new file mode 100644 index 00000000..b50fcd54 --- /dev/null +++ b/api/client-server/definitions/openid_token.yaml @@ -0,0 +1,36 @@ +# Copyright 2018 New Vector Ltd +# Copyright 2019 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +type: object +properties: + access_token: + type: string + description: |- + An access token the consumer may use to verify the identity of + the person who generated the token. This is given to the federation + API ``GET /openid/userinfo`` to verify the user's identity. + token_type: + type: string + description: The string ``Bearer``. + matrix_server_name: + type: string + description: |- + The homeserver domain the consumer should use when attempting to + verify the user's identity. + expires_in: + type: integer + description: |- + The number of seconds before this token expires and a new one must + be generated. +required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in'] diff --git a/api/client-server/definitions/request_email_validation.yaml b/api/client-server/definitions/request_email_validation.yaml index 15bc5b3a..63e3ee21 100644 --- a/api/client-server/definitions/request_email_validation.yaml +++ b/api/client-server/definitions/request_email_validation.yaml @@ -23,4 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. example: "id.example.com" - required: ["id_server"] + id_access_token: + type: string + description: An access token previously registered with the identity server. + required: ["id_server", "id_access_token"] diff --git a/api/client-server/definitions/request_msisdn_validation.yaml b/api/client-server/definitions/request_msisdn_validation.yaml index 370a10cc..43513628 100644 --- a/api/client-server/definitions/request_msisdn_validation.yaml +++ b/api/client-server/definitions/request_msisdn_validation.yaml @@ -23,4 +23,7 @@ allOf: include a port. This parameter is ignored when the homeserver handles 3PID verification. example: "id.example.com" - required: ["id_server"] + id_access_token: + type: string + description: An access token previously registered with the identity server. + required: ["id_server", "id_access_token"] diff --git a/api/client-server/openid.yaml b/api/client-server/openid.yaml index cb982fb3..01fdf68f 100644 --- a/api/client-server/openid.yaml +++ b/api/client-server/openid.yaml @@ -73,28 +73,7 @@ paths: "expires_in": 3600, } schema: - type: object - properties: - access_token: - type: string - description: |- - An access token the consumer may use to verify the identity of - the person who generated the token. This is given to the federation - API ``GET /openid/userinfo``. - token_type: - type: string - description: The string ``Bearer``. - matrix_server_name: - type: string - description: |- - The homeserver domain the consumer should use when attempting to - verify the user's identity. - expires_in: - type: integer - description: |- - The number of seconds before this token expires and a new one must - be generated. - required: ['access_token', 'token_type', 'matrix_server_name', 'expires_in'] + $ref: "definitions/openid_token.yaml" 429: description: This request was rate-limited. schema: diff --git a/api/client-server/registration.yaml b/api/client-server/registration.yaml index 71177d0c..a747e38b 100644 --- a/api/client-server/registration.yaml +++ b/api/client-server/registration.yaml @@ -542,6 +542,11 @@ paths: it must return an ``id_server_unbind_result`` of ``no-support``. example: "example.org" + id_access_token: + type: string + description: |- + An access token previously registered with the identity server. Required if an + ``id_server`` is supplied. responses: 200: description: The account has been deactivated. diff --git a/api/client-server/third_party_membership.yaml b/api/client-server/third_party_membership.yaml index 077e1f6a..075cd34b 100644 --- a/api/client-server/third_party_membership.yaml +++ b/api/client-server/third_party_membership.yaml @@ -92,6 +92,7 @@ paths: type: object example: { "id_server": "matrix.org", + "id_access_token": "abc123_OpaqueString", "medium": "email", "address": "cheeky@monkey.com" } @@ -99,6 +100,9 @@ paths: id_server: type: string description: The hostname+port of the identity server which should be used for third party identifier lookups. + id_access_token: + type: string + description: An access token previously registered with the identity server. medium: type: string # TODO: Link to Identity Service spec when it eixsts @@ -106,7 +110,7 @@ paths: address: type: string description: The invitee's third party identifier. - required: ["id_server", "medium", "address"] + required: ["id_server", "id_access_token", "medium", "address"] responses: 200: description: The user has been invited to join the room. diff --git a/api/identity/v2_auth.yaml b/api/identity/v2_auth.yaml new file mode 100644 index 00000000..16864b8e --- /dev/null +++ b/api/identity/v2_auth.yaml @@ -0,0 +1,109 @@ +# Copyright 2019 The Matrix.org Foundation C.I.C. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +swagger: '2.0' +info: + title: "Matrix Identity Service Authentication API" + version: "2.0.0" +host: localhost:8090 +schemes: + - https +basePath: /_matrix/identity/v2 +consumes: + - application/json +produces: + - application/json +securityDefinitions: + $ref: definitions/security.yaml +paths: + "/account/register": + post: + summary: Exchanges an OpenID token for an access token. + description: |- + Exchanges an OpenID token from the homeserver for an access token to + access the identity server. The request body is the same as the values + returned by ``/openid/request_token`` in the Client-Server API. + operationId: registerAccount + parameters: + - in: body + name: body + schema: + $ref: "../client-server/definitions/openid_token.yaml" + responses: + 200: + description: |- + A token which can be used to authenticate future requests to the + identity server. + examples: + application/json: { + "token": "abc123_OpaqueString" + } + schema: + type: object + properties: + token: + type: string + description: |- + An opaque string representing the token to authenticate future + requests to the identity server with. + required: ['token'] + "/account": + get: + summary: Gets account holder information for a given token. + description: |- + Gets information about what user owns the access token used in the request. + operationId: getAccount + security: + - accessToken: [] + parameters: [] + responses: + 200: + description: The token holder's information. + examples: + application/json: { + "user_id": "@alice:example.org" + } + schema: + type: object + properties: + user_id: + type: string + description: The user ID which registered the token. + required: ['user_id'] + "/account/logout": + post: + summary: Logs out an access token, rendering it unusable. + description: |- + Logs out the access token, preventing it from being used to authenticate + future requests to the server. + operationId: logout + security: + - accessToken: [] + parameters: [] + responses: + 200: + description: The token was successfully logged out. + examples: + application/json: {} + schema: + type: object + 401: + description: |- + The token is not registered or is otherwise unknown to the server. + examples: + application/json: { + "errcode": "M_UNKNOWN_TOKEN", + "error": "Unrecognised access token" + } + schema: + $ref: "../client-server/definitions/errors/error.yaml" diff --git a/changelogs/client_server/newsfragments/2255.breaking b/changelogs/client_server/newsfragments/2255.breaking new file mode 100644 index 00000000..f9c8c6e1 --- /dev/null +++ b/changelogs/client_server/newsfragments/2255.breaking @@ -0,0 +1 @@ +Add a required ``id_access_token`` to many places which require an ``id_server`` parameter. diff --git a/changelogs/identity_service/newsfragments/2254.feature b/changelogs/identity_service/newsfragments/2254.feature new file mode 100644 index 00000000..089d01fe --- /dev/null +++ b/changelogs/identity_service/newsfragments/2254.feature @@ -0,0 +1 @@ +Deprecate the v1 API in favour of an authenticated v2 API. diff --git a/changelogs/identity_service/newsfragments/2255.new b/changelogs/identity_service/newsfragments/2255.new new file mode 100644 index 00000000..fcb6ba88 --- /dev/null +++ b/changelogs/identity_service/newsfragments/2255.new @@ -0,0 +1 @@ +Add ``/account``, ``/account/register``, and ``/account/logout`` to authenticate with the identity server. diff --git a/proposals/2140-terms-of-service-2.md b/proposals/2140-terms-of-service-2.md index 9f96a00b..e5bcd0ac 100644 --- a/proposals/2140-terms-of-service-2.md +++ b/proposals/2140-terms-of-service-2.md @@ -170,7 +170,7 @@ This endpoint does *not* require authentication. #### `POST $prefix/terms`: Requests to this endpoint have a single key, `user_accepts` whose value is -a list of URLs (given by the `url` field in the GET response) of documents that +a list of URLs (given by the `url` field in the GET response) of documents that the user has agreed to: ```json @@ -269,7 +269,7 @@ A client uses this client/server API endpoint to request that the Homeserver removes the given 3PID from the given Identity Server, or all Identity Servers. Takes the same parameters as `POST /_matrix/client/r0/account/3pid/delete`, ie. `id_server`, `medium`, -`address` and the newly added `is_token`. +`address` and the newly added `id_access_token`. Returns the same as `POST /_matrix/client/r0/account/3pid/delete`. diff --git a/specification/client_server_api.rst b/specification/client_server_api.rst index 916604a3..5ff710d1 100644 --- a/specification/client_server_api.rst +++ b/specification/client_server_api.rst @@ -802,7 +802,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "sid": "", "client_secret": "", - "id_server": "" + "id_server": "", + "id_access_token": "" } ], "session": "" @@ -830,7 +831,8 @@ To use this authentication type, clients should submit an auth dict as follows: { "sid": "", "client_secret": "", - "id_server": "" + "id_server": "", + "id_access_token": "" } ], "session": "" diff --git a/specification/identity_service_api.rst b/specification/identity_service_api.rst index f8211f70..4afac6ef 100644 --- a/specification/identity_service_api.rst +++ b/specification/identity_service_api.rst @@ -57,8 +57,6 @@ The following other versions are also available, in reverse chronological order: General principles ------------------ -.. TODO: TravisR - Define auth for IS v2 API in a future PR - The purpose of an identity server is to validate, store, and answer questions about the identities of users. In particular, it stores associations of the form "identifier X represents the same user as identifier Y", where identities may @@ -173,6 +171,33 @@ to be returned by servers on all requests are:: Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization +Authentication +-------------- + +Most ``v2`` endpoints in the Identity Service API require authentication in order +to ensure that the requesting user has accepted all relevant policies and is otherwise +permitted to make the request. The ``v1`` API (currently deprecated) does not require +this authentication, however using ``v1`` is strongly discouraged as it will be removed +in a future release. + +Identity Servers use a scheme similar to the Client-Server API's concept of access +tokens to authenticate users. The access tokens provided by an Identity Server cannot +be used to authenticate Client-Server API requests. + +An access token is provided to an endpoint in one of two ways: + +1. Via a query string parameter, ``access_token=TheTokenHere``. +2. Via a request header, ``Authorization: Bearer TheTokenHere``. + +Clients are encouraged to the use the ``Authorization`` header where possible to prevent +the access token being leaked in access/HTTP logs. The query string should only be used +in cases where the ``Authorization`` header is inaccessible for the client. + +When credentials are required but missing or invalid, the HTTP call will return with a +status of 401 and the error code ``M_UNAUTHORIZED``. + +{{v2_auth_is_http_api}} + Status check ------------