summaryrefslogtreecommitdiff
path: root/design-documents/049-auth.rst
blob: d328aabf58daf9aa19ba390f385f3ea0d336ace6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
DD 49: Authentication
#####################

Summary
=======

This design document specifies a simple authentication framework to be used by multiple Taler
components that require authentication.

Motivation
==========

SPAs currently store the username and password in locals storage (or at least
session storage).

There's also no way to manage auth tokens third parties (e.g.
auditors).

Requirements
============

* simple specification
* simple implementation
* simple to use
* must cover two main use cases:

  * SPA login
  * delegating (possibly restricted) access to a third party using a token

Proposed Solution
=================

We define a ``token`` endpoint that can be used to obtain access tokens from
other forms of authentication, typically HTTP Basic auth.


.. _dd48-token:

Token Endpoint
--------------

.. http:post:: /${RESOURCE...}/token

   **Request Body**

   .. ts:def:: TokenRequest

     interface TokenRequest {
       // Service-defined scope for the token.
       // Typical scopes would be "readonly" or "readwrite".
       scope: string;

       // Server may impose its own upper bound
       // on the token validity duration
       duration?: RelativeTime;

       // Is the token refreshable into a new token during its
       // validity?
       // Refreshable tokens effectively provide indefinite
       // access if they are refreshed in time.
       refreshable?: boolean;
     }

   **Response:**

   :http:statuscode:`200 Ok`:
     The response is a `TokenSuccessResponse`

   **Details:**

   .. ts:def:: TokenSuccessResponse

     interface TokenSuccessResponse {
       // Expiration determined by the server.
       // Can be based on the token_duration
       // from the request, but ultimately the
       // server decides the expiration.
       expiration: Timestamp;

       // Opque access token.
       access_token: string;
     }

Token Revocation
-----------------

Clients using session tokens log by forgetting the session token.
Tokens can be explicitly revoked by making a ``DELETE`` request on
the token endpoint.

.. http:delete:: /${RESOURCE...}/token

   Invalidate the access token that is being used to make the request.

   **Authentication:**  The client must authenticate
   with a valid access token.



Definition of Done
==================

* DONE: spec reviewed
* DONE: implemented in merchant backend
* implemented in libeufin-bank
* DONE: implemented in the bank webui SPA
* implemented in the merchant backoffice SPA


Alternatives
============

* use something much closer to OAuth2

  * would be unnecessarly generic and complex

Session Tokens / Signatures
---------------------------

For performance reasons, OAuth 2.0 uses two types of tokens: Short-lived access
tokens and long-lived refresh tokens.  The access tokens can be implemented via
signatures and the long-lived refresh tokens via server-stored tokens.  This
allows to cheaply validate access tokens, while still allowing longer expiration times
for refresh tokens.

We could do something similar by introducing login and session tokens.  A login
token is a server-stored token.  In addition to being used directly as an
access token, a login token can also be converted to a short-lived session
token.

Session access tokens should be implemented as "self-encoded tokens", i.e.
as tokens signed by the server without requiring server-side token storage.
Session access tokens should have a rather short maximum expiration.

The signature should be over ``(username, kind, scope, creation_timestamp, expiry)``.

To revoke session tokens, the server must store the timestamp of the last
revocation and only accept tokens with a ``creation_timestamp`` larger than the
last revocation timestamp. Individual session tokens cannot be revoked, only
all issued session tokens can be revoked at once.

However, we decided against doing this because the performance benefits
are not significant enough for us and having multiple token types would
lead to unnecessary complexity.

Drawbacks
=========

* still more complex than simple auth tokens or HTTP basic auth

Discussion / Q&A
================

(This should be filled in with results from discussions on mailing lists / personal communication.)