049-auth.rst (8194B)
1 DD 49: Authentication 2 ##################### 3 4 Summary 5 ======= 6 7 This design document specifies a simple authentication framework to be used by multiple Taler 8 components that require authentication. 9 10 Motivation 11 ========== 12 13 SPAs currently store the username and password in locals storage (or at least 14 session storage). 15 16 There's also no way to manage auth tokens third parties (e.g. 17 auditors). 18 19 Requirements 20 ============ 21 22 * simple specification 23 * simple implementation 24 * simple to use 25 * must cover two main use cases: 26 27 * SPA login 28 * delegating (possibly restricted) access to a third party using a token 29 30 Proposed Solution 31 ================= 32 33 We define a ``token`` endpoint that can be used to obtain access tokens from 34 other forms of authentication, typically HTTP Basic auth. 35 36 Token Creation 37 -------------- 38 39 .. http:post:: /${RESOURCE...}/token 40 41 Create an authentification token. 42 43 **Request:** 44 45 .. ts:def:: TokenRequest 46 47 interface TokenRequest { 48 // Service-defined scope for the token. 49 // Typical scopes would be "readonly" or "readwrite". 50 scope: string; 51 52 // Server may impose its own upper bound 53 // on the token validity duration 54 duration?: RelativeTime; 55 56 // Is the token refreshable into a new token during its 57 // validity? 58 // Refreshable tokens effectively provide indefinite 59 // access if they are refreshed in time. 60 // Deprecated, use ":refreshable" suffix in scope instead. 61 refreshable?: boolean; 62 63 // Optional token description 64 // @since v4 65 description?: string; 66 } 67 68 **Response:** 69 70 :http:statuscode:`200 Ok`: 71 The response is a `TokenSuccessResponse` 72 73 **Details:** 74 75 .. ts:def:: TokenSuccessResponse 76 77 interface TokenSuccessResponse { 78 // Expiration determined by the server. 79 // Can be based on the token_duration 80 // from the request, but ultimately the 81 // server decides the expiration. 82 expiration: Timestamp; 83 84 // Opque access token. 85 access_token: string; 86 } 87 88 Token Revocation 89 ---------------- 90 91 Clients using session tokens log by forgetting the session token. 92 Tokens can be explicitly revoked by making a ``DELETE`` request on 93 the token endpoint. 94 95 .. http:delete:: /${RESOURCE...}/token 96 97 Invalidate the access token that is being used to make the request. 98 **Authentication:** The client must authenticate 99 with a valid access token. 100 101 Token Information 102 ----------------- 103 104 List existing token informations. 105 106 .. http:get:: /${RESOURCE...}/tokens 107 108 **Request:** 109 110 :query delta: *Optional.* 111 Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries. 112 :query start: *Optional.* 113 Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign. 114 115 **Response:** 116 117 :http:statuscode:`200 OK`: 118 Response is a `TokenInfos`. 119 :http:statuscode:`204 No content`: 120 No tokens. 121 122 **Details:** 123 124 .. ts:def:: TokenInfos 125 126 interface TokenInfos { 127 tokens: TokenInfo[]; 128 } 129 130 .. ts:def:: TokenInfo 131 132 interface TokenInfo { 133 // Time when the token was created. 134 creation_time: Timestamp; 135 136 // Expiration determined by the server. 137 // Can be based on the token_duration 138 // from the request, but ultimately the 139 // server decides the expiration. 140 expiration: Timestamp; 141 142 // Service-defined scope for the token. 143 // Typical scopes would be "readonly" or "readwrite". 144 scope: string; 145 146 // Is the token refreshable into a new token during its 147 // validity? 148 // Refreshable tokens effectively provide indefinite 149 // access if they are refreshed in time. 150 refreshable: boolean; 151 152 // Optional token description 153 description?: string; 154 155 // Time when the token was last used. 156 last_access: Timestamp; 157 158 // Opaque unique ID used for pagination. 159 row_id: Integer; 160 } 161 162 Permissions 163 =========== 164 165 Each API request to an endpoint **may** be associated with a *permission*. 166 A permission is a descriptive string, e.g. ``orders-read`` for a ``GET`` request on the endpoint ``/private/orders``. 167 Another example would be ``orders-write`` for a ``POST`` or ``PUT`` request on the same endpoint. 168 If no permission is defined for a request, no access control is enforced. 169 170 Each component API **must** define and document appropriate permissions for its requests. 171 Permission strings best practice include that *read-only* access end with the suffix ``-read``, e.g. ``orders-read``. 172 If the access to the endpoint modifies the state it is suffixed with ``-write``, e.g. ``orders-write``. 173 Special permissions may deviate from this. 174 Two endpoints **may** use the same permission. 175 176 In the API documentaction where the **Request** to an endpoint is defined, **Required permission** entry should be added. 177 See the Merchant API for examples. 178 179 Scopes 180 ====== 181 182 A ``scope`` is a set of permissions that is associated with a token. 183 The scope is provided when requesting the token, see `TokenRequest`. 184 185 Default scopes that can be requested in a `TokenRequest` are or rather **must** be defined and documented by the component. 186 Here are some *examples* of possible scopes: 187 188 * ``readonly``: ``*-read`` -- This wildcard match will grant access to all endpoints protected with a permission that has the ``-read`` suffix. 189 * ``admin``: ``*`` -- This matches all permissions, essentially the *key to the kingdom*. 190 * ``orders-simple``: ``orders-read,orders-write`` -- Access to reading and writing orders. 191 * ``orders-full``: ``orders-read,orders-write,orders-refund`` -- Like ``orders-simple``, but also allows for refunds. 192 193 In the merchant component, scopes are currently hard-coded. In the future, additional scopes may be configurable 194 through configuration files and/or default scopes overridden. 195 196 Token refresh 197 ============= 198 199 Tokens may be requested to be refreshable. 200 In older API versions this was achieved by setting the ``refreshable`` field in the `TokenRequest`. 201 In recent API versions this is achieved by suffixing the requested scope with ``:refreshable``, e.g. ``orders-full:refreshable``. 202 203 Definition of Done 204 ================== 205 206 * DONE: spec reviewed 207 * DONE: implemented in merchant backend 208 * implemented in libeufin-bank 209 * DONE: implemented in the bank webui SPA 210 * implemented in the merchant backoffice SPA 211 212 213 Alternatives 214 ============ 215 216 * use something much closer to OAuth2 217 218 * would be unnecessarly generic and complex 219 220 Session Tokens / Signatures 221 --------------------------- 222 223 For performance reasons, OAuth 2.0 uses two types of tokens: Short-lived access 224 tokens and long-lived refresh tokens. The access tokens can be implemented via 225 signatures and the long-lived refresh tokens via server-stored tokens. This 226 allows to cheaply validate access tokens, while still allowing longer expiration times 227 for refresh tokens. 228 229 We could do something similar by introducing login and session tokens. A login 230 token is a server-stored token. In addition to being used directly as an 231 access token, a login token can also be converted to a short-lived session 232 token. 233 234 Session access tokens should be implemented as "self-encoded tokens", i.e. 235 as tokens signed by the server without requiring server-side token storage. 236 Session access tokens should have a rather short maximum expiration. 237 238 The signature should be over ``(username, kind, scope, creation_timestamp, expiry)``. 239 240 To revoke session tokens, the server must store the timestamp of the last 241 revocation and only accept tokens with a ``creation_timestamp`` larger than the 242 last revocation timestamp. Individual session tokens cannot be revoked, only 243 all issued session tokens can be revoked at once. 244 245 However, we decided against doing this because the performance benefits 246 are not significant enough for us and having multiple token types would 247 lead to unnecessary complexity. 248 249 Drawbacks 250 ========= 251 252 * still more complex than simple auth tokens or HTTP basic auth 253 254 Discussion / Q&A 255 ================ 256 257 (This should be filled in with results from discussions on mailing lists / personal communication.)