From 902c7d3ea69c56b9c1576756123d98721135af12 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Wed, 19 Aug 2015 15:00:22 +0100 Subject: [PATCH 01/11] Add draft macaroon caveat specification --- drafts/macaroons_caveats.rst | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 drafts/macaroons_caveats.rst diff --git a/drafts/macaroons_caveats.rst b/drafts/macaroons_caveats.rst new file mode 100644 index 00000000..b6920d6c --- /dev/null +++ b/drafts/macaroons_caveats.rst @@ -0,0 +1,30 @@ +Macaroon Caveats +================ + +Macaroons (http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) are issued by Matrix servers as authorization tokens. Macaroons may be restricted, by adding caveats to them. + +Caveats can only be used for reducing the scope of a token, never for increasing it. Servers are required to reject any macroon with a caveat that they do not understand. + +Some caveats are specified in this specification, and must be understood by all servers. The use of non-standard caveats is allowed. + +All caveats must take the form: + +`key` `operator` `value` +where `key` is a non-empty string drawn from the character set [A-Za-z0-9_] +`operator` is a non-empty string which does not contain whitespace +`value` is a non-empty string +And these are joined by single space characters. + +Specified caveats: + ++-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ +| Caveat name | Description | Legal Values | ++-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ +| gen | Generation of the macaroon caveat spec. | 1 | +| user_id | ID of the user for which this macaroon is valid. | Pure equality check. Operator must be =. | +| type | The purpose of this macaroon. | access - used to authorize any action except token refresh | +| refresh - only used to authorize a token refresh | +| time | Time before/after which this macaroon is valid. | A POSIX timestamp in milliseconds (in UTC). | +| Operator < means the macaroon is valid before the timestamp, as interpreted by the server. | +| Operator > means the macaroon is valid after the timestamp, as interpreted by the server. | ++-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ From 0440983c4ab74f30a38f27d70c51f47ea1a8ff30 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 28 Aug 2015 10:31:45 +0100 Subject: [PATCH 02/11] Spec exchanging refresh tokens for new access tokens --- specification/10_client_server_api.rst | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/specification/10_client_server_api.rst b/specification/10_client_server_api.rst index 83c8b7a8..6b8ffbcc 100644 --- a/specification/10_client_server_api.rst +++ b/specification/10_client_server_api.rst @@ -1087,10 +1087,33 @@ On success, this returns a JSON object with keys: user_id The fully-qualified Matrix ID that has been registered. access_token - An access token for the new account. + An access token for the account. This token may expire at some point, and if + so, it MAY come with a refersh_token, described below. +refresh_token (optional) + A refresh token may be exchanged for a new access_token as described in + `Refreshing access tokens`. home_server The hostname of the Home Server on which the account has been registered. +Refreshing access tokens +~~~~~~~~~~~~~~~~~~~~~~~~ +Exchanging a refresh token for an access token is done using the request:: + + POST $PREFIX/tokenrefresh + +The body of the POST request is a JSON object containing: + +refresh_token + The refresh token. + +On success, this invalidates the refresh token, so that it cannot be used again, +and returns a JSON object with keys: + +access_token + An access token for the account, as is returned from login. +refresh_token (optional) + A refresh token, as is returned from login. + Changing Password ~~~~~~~~~~~~~~~~~ This section refers to API Version 2. These API calls currently use the prefix From 9515640d5e0ef51e075a0635ebd8261888e04501 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 28 Aug 2015 10:41:49 +0100 Subject: [PATCH 03/11] Add note about no specific 'token expired' error --- specification/10_client_server_api.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/specification/10_client_server_api.rst b/specification/10_client_server_api.rst index 6b8ffbcc..5dd215d4 100644 --- a/specification/10_client_server_api.rst +++ b/specification/10_client_server_api.rst @@ -1114,6 +1114,11 @@ access_token refresh_token (optional) A refresh token, as is returned from login. +There is no specific error message to indicate that a request has failed because +an access token has expired; instead, if a client has reason to believe its +access token is valid, and it receives an auth error, they should attempt to +refresh for a new token on failure, and re-try the request with the new token. + Changing Password ~~~~~~~~~~~~~~~~~ This section refers to API Version 2. These API calls currently use the prefix From 0341c30824ed89b64cb09b5eea74f011eed81495 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Mon, 14 Sep 2015 10:39:22 +0100 Subject: [PATCH 04/11] Minor typo and formatting fixes --- drafts/macaroons_caveats.rst | 2 +- specification/10_client_server_api.rst | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drafts/macaroons_caveats.rst b/drafts/macaroons_caveats.rst index b6920d6c..2a45fe12 100644 --- a/drafts/macaroons_caveats.rst +++ b/drafts/macaroons_caveats.rst @@ -1,7 +1,7 @@ Macaroon Caveats ================ -Macaroons (http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) are issued by Matrix servers as authorization tokens. Macaroons may be restricted, by adding caveats to them. +Macaroons (http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) are issued by Matrix servers as authorization tokens. Macaroons may be restricted by adding caveats to them. Caveats can only be used for reducing the scope of a token, never for increasing it. Servers are required to reject any macroon with a caveat that they do not understand. diff --git a/specification/10_client_server_api.rst b/specification/10_client_server_api.rst index 6a589f8e..440f98e4 100644 --- a/specification/10_client_server_api.rst +++ b/specification/10_client_server_api.rst @@ -1035,7 +1035,7 @@ user_id The fully-qualified Matrix ID that has been registered. access_token An access token for the account. This token may expire at some point, and if - so, it MAY come with a refersh_token, described below. + so, it MAY come with a refresh_token, described below. refresh_token (optional) A refresh token may be exchanged for a new access_token as described in `Refreshing access tokens`. @@ -1064,7 +1064,7 @@ refresh_token (optional) There is no specific error message to indicate that a request has failed because an access token has expired; instead, if a client has reason to believe its access token is valid, and it receives an auth error, they should attempt to -refresh for a new token on failure, and re-try the request with the new token. +refresh for a new token on failure, and retry the request with the new token. Changing Password ~~~~~~~~~~~~~~~~~ From 3b44fb92f972104bc781999303631d7ba5d649f2 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Mon, 14 Sep 2015 17:13:54 +0100 Subject: [PATCH 05/11] Clarify == case --- drafts/macaroons_caveats.rst | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/drafts/macaroons_caveats.rst b/drafts/macaroons_caveats.rst index 2a45fe12..791d217a 100644 --- a/drafts/macaroons_caveats.rst +++ b/drafts/macaroons_caveats.rst @@ -17,14 +17,16 @@ And these are joined by single space characters. Specified caveats: -+-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ -| Caveat name | Description | Legal Values | -+-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ -| gen | Generation of the macaroon caveat spec. | 1 | -| user_id | ID of the user for which this macaroon is valid. | Pure equality check. Operator must be =. | -| type | The purpose of this macaroon. | access - used to authorize any action except token refresh | -| refresh - only used to authorize a token refresh | -| time | Time before/after which this macaroon is valid. | A POSIX timestamp in milliseconds (in UTC). | -| Operator < means the macaroon is valid before the timestamp, as interpreted by the server. | -| Operator > means the macaroon is valid after the timestamp, as interpreted by the server. | -+-------------+--------------------------------------------------+--------------------------------------------------------------------------------------------+ ++-------------+--------------------------------------------------+------------------------------------------------------------------------------------------------+ +| Caveat name | Description | Legal Values | ++-------------+--------------------------------------------------+------------------------------------------------------------------------------------------------+ +| gen | Generation of the macaroon caveat spec. | 1 | +| user_id | ID of the user for which this macaroon is valid. | Pure equality check. Operator must be =. | +| type | The purpose of this macaroon. | access - used to authorize any action except token refresh | +| refresh - only used to authorize a token refresh | +| time | Time before/after which this macaroon is valid. | A POSIX timestamp in milliseconds (in UTC). | +| Operator < means the macaroon is valid before the timestamp, as interpreted by the server. | +| Operator > means the macaroon is valid after the timestamp, as interpreted by the server. | +| Operator == means the macaroon is valid at exactly the timestamp, as interpreted by the server.| +| Note that exact equality of time is largely meaningless. | ++-------------+--------------------------------------------------+------------------------------------------------------------------------------------------------+ From 2e9d3d283a351dae22bf2d88e8dfed821442d6de Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Tue, 15 Sep 2015 16:23:19 +0100 Subject: [PATCH 06/11] Swagger refresh tokens --- api/client-server/v1/login.yaml | 71 ++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) diff --git a/api/client-server/v1/login.yaml b/api/client-server/v1/login.yaml index 2df695be..0852db6b 100644 --- a/api/client-server/v1/login.yaml +++ b/api/client-server/v1/login.yaml @@ -63,7 +63,19 @@ paths: description: The fully-qualified Matrix ID that has been registered. access_token: type: string - description: An access token for the account. This access token can then be used to authorize other requests. + description: |- + An access token for the account. + This access token can then be used to authorize other requests. + The access token may expire at some point, and if so, it SHOULD come with a refresh_token. + There is no specific error message to indicate that a request has failed because + an access token has expired; instead, if a client has reason to believe its + access token is valid, and it receives an auth error, they should attempt to + refresh for a new token on failure, and retry the request with the new token. + refresh_token: + type: string + # TODO: Work out how to linkify /tokenrefresh + description: |- + (optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the /tokenrefresh API endpoint. home_server: type: string description: The hostname of the Home Server on which the account has been registered. @@ -77,3 +89,60 @@ paths: description: This request was rate-limited. schema: "$ref": "definitions/error.yaml" + "/tokenrefresh": + post: + summary: Exchanges a refresh token for an access token. + description: |- + Exchanges a refresh token for a new access token. + This is intended to be used if the access token has expired. + security: + - accessToken: [] + parameters: + - in: body + name: body + required: true + schema: + type: object + example: |- + { + "refresh_token": "a1b2c3" + } + properties: + refresh_token: + type: string + description: The refresh token which was issued by the server. + required: ["refresh_token"] + responses: + 200: + description: |- + The refresh token was accepted, and a new access token has been issued. + The passed refresh token is no longer valid, and cannot be used. + A new refresh token may have been returned. + examples: + application/json: |- + { + "access_token": "bearwithme123", + "refresh_token": "exchangewithme987" + } + schema: + type: object + properties: + access_token: + type: string + description: |- + An access token for the account. + This access token can then be used to authorize other requests. + The access token may expire at some point, and if so, it SHOULD come with a refresh_token. + refresh_token: + type: string + description: (optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the TODO Linkify /tokenrefresh API endpoint. + 403: + description: |- + The exchange attempt failed. For example, the refresh token may have already been used. + examples: + application/json: |- + {"errcode": "M_FORBIDDEN"} + 429: + description: This request was rate-limited. + schema: + "$ref": "definitions/error.yaml" From 6c89e6ea6717d9cd07afed7906add62ab82c0431 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 25 Sep 2015 13:03:46 +0100 Subject: [PATCH 07/11] Wrap refresh_token in `s --- api/client-server/v1/login.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/client-server/v1/login.yaml b/api/client-server/v1/login.yaml index 0852db6b..a4fd8b95 100644 --- a/api/client-server/v1/login.yaml +++ b/api/client-server/v1/login.yaml @@ -66,7 +66,7 @@ paths: description: |- An access token for the account. This access token can then be used to authorize other requests. - The access token may expire at some point, and if so, it SHOULD come with a refresh_token. + The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``. There is no specific error message to indicate that a request has failed because an access token has expired; instead, if a client has reason to believe its access token is valid, and it receives an auth error, they should attempt to @@ -132,7 +132,7 @@ paths: description: |- An access token for the account. This access token can then be used to authorize other requests. - The access token may expire at some point, and if so, it SHOULD come with a refresh_token. + The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``. refresh_token: type: string description: (optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the TODO Linkify /tokenrefresh API endpoint. From fc87f4cdb03cca548ee7ec499949c1d52d5104a3 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 25 Sep 2015 13:10:15 +0100 Subject: [PATCH 08/11] Remove unused keys --- api/client-server/v1/login.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/client-server/v1/login.yaml b/api/client-server/v1/login.yaml index a4fd8b95..4cb564b7 100644 --- a/api/client-server/v1/login.yaml +++ b/api/client-server/v1/login.yaml @@ -29,7 +29,6 @@ paths: parameters: - in: body name: body - required: true schema: type: object example: |- @@ -100,7 +99,6 @@ paths: parameters: - in: body name: body - required: true schema: type: object example: |- From 5c4398c181bbf9da4aada6d4f8a3bf5b0d49c877 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 25 Sep 2015 13:10:49 +0100 Subject: [PATCH 09/11] Remove superfluous comma --- api/client-server/v1/login.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/client-server/v1/login.yaml b/api/client-server/v1/login.yaml index 4cb564b7..e415e798 100644 --- a/api/client-server/v1/login.yaml +++ b/api/client-server/v1/login.yaml @@ -114,7 +114,7 @@ paths: 200: description: |- The refresh token was accepted, and a new access token has been issued. - The passed refresh token is no longer valid, and cannot be used. + The passed refresh token is no longer valid and cannot be used. A new refresh token may have been returned. examples: application/json: |- From 6c1491b3bafb3a806d8fdf4ed59eacdf4df79d06 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 25 Sep 2015 13:17:11 +0100 Subject: [PATCH 10/11] Respond to some review comments --- api/client-server/v1/login.yaml | 3 ++- drafts/macaroons_caveats.rst | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/api/client-server/v1/login.yaml b/api/client-server/v1/login.yaml index e415e798..3d415c29 100644 --- a/api/client-server/v1/login.yaml +++ b/api/client-server/v1/login.yaml @@ -115,7 +115,8 @@ paths: description: |- The refresh token was accepted, and a new access token has been issued. The passed refresh token is no longer valid and cannot be used. - A new refresh token may have been returned. + A new refresh token will have been returned unless some policy does + not allow the user to continue to renew their session. examples: application/json: |- { diff --git a/drafts/macaroons_caveats.rst b/drafts/macaroons_caveats.rst index 791d217a..c4b6b6a4 100644 --- a/drafts/macaroons_caveats.rst +++ b/drafts/macaroons_caveats.rst @@ -1,7 +1,9 @@ Macaroon Caveats ================ -Macaroons (http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) are issued by Matrix servers as authorization tokens. Macaroons may be restricted by adding caveats to them. +`Macaroons`_ are issued by Matrix servers as authorization tokens. Macaroons may be restricted by adding caveats to them. + +.. _Macaroons: http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) Caveats can only be used for reducing the scope of a token, never for increasing it. Servers are required to reject any macroon with a caveat that they do not understand. From f5d436bd808ac9a1f20d816dccceac63a9202546 Mon Sep 17 00:00:00 2001 From: Daniel Wagner-Hall Date: Fri, 25 Sep 2015 13:18:09 +0100 Subject: [PATCH 11/11] Remove extraneous ) --- drafts/macaroons_caveats.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drafts/macaroons_caveats.rst b/drafts/macaroons_caveats.rst index c4b6b6a4..93622c3d 100644 --- a/drafts/macaroons_caveats.rst +++ b/drafts/macaroons_caveats.rst @@ -3,7 +3,7 @@ Macaroon Caveats `Macaroons`_ are issued by Matrix servers as authorization tokens. Macaroons may be restricted by adding caveats to them. -.. _Macaroons: http://theory.stanford.edu/~ataly/Papers/macaroons.pdf) +.. _Macaroons: http://theory.stanford.edu/~ataly/Papers/macaroons.pdf Caveats can only be used for reducing the scope of a token, never for increasing it. Servers are required to reject any macroon with a caveat that they do not understand.