Browse Source

Add spec for MFA auth receipts

Change-Id: Ia8f25cf84070c271fc2ffb9f8fd115f55b3e428e
Adrian Turjak 1 year ago
parent
commit
d3695a1b5d
2 changed files with 324 additions and 0 deletions
  1. 11
    0
      doc/source/index.rst
  2. 313
    0
      specs/keystone/rocky/mfa-auth-receipt.rst

+ 11
- 0
doc/source/index.rst View File

@@ -14,6 +14,17 @@ Project Documentation:
14 14
 keystone
15 15
 ========
16 16
 
17
+Rocky approved specs:
18
+
19
+`Rocky Roadmap <https://trello.com/b/wmyzbFq5/keystone-rocky-roadmap>`_
20
+
21
+.. toctree::
22
+   :glob:
23
+   :maxdepth: 1
24
+
25
+   specs/keystone/rocky/*
26
+
27
+
17 28
 Queens approved specs:
18 29
 
19 30
 `Queens Roadmap <https://trello.com/b/5F0h9Hoe/keystone-queens-roadmap>`_

+ 313
- 0
specs/keystone/rocky/mfa-auth-receipt.rst View File

@@ -0,0 +1,313 @@
1
+..
2
+ This work is licensed under a Creative Commons Attribution 3.0 Unported
3
+ License.
4
+
5
+ http://creativecommons.org/licenses/by/3.0/legalcode
6
+
7
+================
8
+MFA Auth Receipt
9
+================
10
+
11
+`mfa-auth-receipt <https://blueprints.launchpad.net/keystone/+spec/
12
+mfa-auth-receipt>`_
13
+
14
+
15
+To provide proper usable multi-factor authentication (MFA) support in
16
+OpenStack we need to return an auth receipt to the user representing partial
17
+authentication, which can be returned to Keystone as part of a challenge
18
+response process.
19
+
20
+
21
+Problem Description
22
+===================
23
+
24
+As of Ocata Keystone supports setting auth rules on a given user and
25
+potentially requiring them to auth with multiple methods. This is a good
26
+implementation of MFA, but the problem rests in a user or service knowing ahead
27
+of time how they need to auth. Most standard MFA systems are challenge response
28
+based. You auth with one of your factors, then are given a receipt of that
29
+partial authentication, which you can return along with the missing pieces.
30
+
31
+Keystone needs such a mechanism because without it we can't realistically
32
+consume MFA anywhere else in OpenStack in a manner that makes sense for users.
33
+
34
+The original proposal for MFA in Keystone actually included this concept but
35
+was never implemented:
36
+`multi-factor-authn <https://blueprints.launchpad.net/keystone/+spec/
37
+multi-factor-authn>`_
38
+
39
+The concept of a half-token was discussed, but it never really got implemented
40
+in a way we could use for MFA.
41
+
42
+Proposed Change
43
+===============
44
+
45
+The proposal is to add a new mechanism which returns a receipt to the user on a
46
+partially successful auth attempt. This would in essence be very similar to a
47
+token, and ideally use a similar system for storage (fernet, jwt) to keep
48
+internal logic consistent and reusable.
49
+
50
+When a user successfully authenticates with one of their many auth rules, we
51
+can infer that they are who they say they are, and then return to them a
52
+receipt that contains information about missing auth rules.
53
+
54
+If a user attempts auth with multiple methods and most fail but at least one
55
+succeeds, we do not return a receipt, but we do include json error data as to
56
+what methods failed, and which did not.
57
+
58
+Using a receipt to get a new receipt with extra auth methods should ideally be
59
+possible. If you need three auth methods to get a token, you should be able to
60
+add to your receipt until it can become a token.
61
+
62
+This receipt would allow no API interaction, but it would be proof that
63
+certain auth methods have been completed. The expiry for the receipt would
64
+default to a fairly short time-frame (5 minutes).
65
+
66
+Receipt Response
67
+----------------
68
+
69
+The return code for this would be ``401`` as the user is still unauthorized,
70
+with the response header containing the receipt id, and the body containing
71
+information about the receipt which they need to continue the auth process.
72
+
73
+In addition this response would be explicitly setup to only occur when a user
74
+with auth rules successfully auths with one of the methods in any of their auth
75
+rules.
76
+
77
+The receipt id (the encrypted payload) would be included in the header of the
78
+``401`` response in the same fashion as a token is but under the header
79
+``OPENSTACK-AUTH-RECEIPT``.
80
+
81
+An example response::
82
+
83
+    {
84
+        "receipt": {
85
+            "methods": [
86
+                "password"
87
+            ],
88
+            "user_id": "423f19a4ac1e4f48bbb4180756e6eb6c",
89
+            "expires_at": "2015-11-06T15:32:17.893769Z"
90
+        },
91
+        "required_auth_methods": [
92
+            ['password', 'totp'],
93
+            ['password', 'option2'],
94
+            ['password', 'option3', 'option4']
95
+        ]
96
+    }
97
+
98
+``required_auth_methods`` would be a list of rules that include the
99
+successfully authenticated methods and not a list of all of the user's auth
100
+rules. The methods in the receipt do not entirely have to be all from the same
101
+auth rule, the receipt contains valid methods, and what rules they could apply
102
+to, so it's an intersection test.
103
+
104
+Another example response::
105
+
106
+    {
107
+        "receipt": {
108
+            "methods": [
109
+                "password", "option3"
110
+            ],
111
+            "user_id": "423f19a4ac1e4f48bbb4180756e6eb6c",
112
+            "expires_at": "2015-11-06T15:32:17.893769Z"
113
+        },
114
+        "required_auth_methods": [
115
+            ['password', 'option2'],
116
+            ['option3', 'option4']
117
+        ]
118
+    }
119
+
120
+In this above case, the user now has two optional MFA paths off the same
121
+receipt despite there being no overlap between the two auth rules.
122
+
123
+Receipt payload
124
+---------------
125
+
126
+The receipt will not include scope data as it isn't relevant to it. A user will
127
+supply scope when using the receipt and trying to get a token, Keystone will
128
+not look at the receipt for scope. The only reason to potentially introduce
129
+scope to the receipt is if and when we introduce auth rules based on scope.
130
+
131
+The actual provider for the receipt should be configurable in the same fashion
132
+as token, and similar types (fernet, jwt). In the case of fernet the key
133
+repository should ideally be able to be shared with the token provider, but
134
+configuration should be possible to split the repo. This minimises potential
135
+pain for deployers and gives them time before they need to add a second key
136
+repository.
137
+
138
+Ideally any code we can share with the token providers we do, and move as much
139
+as makes sense into common utils. Much like tokens, we even handle key
140
+rotation in the same way. Accept receipts encrypted by the current and last key
141
+but issue new ones with the current key.
142
+
143
+The receipt data itself (before encryption) would likely be::
144
+
145
+    {
146
+        "methods": [
147
+            "password"
148
+        ],
149
+        "user_id": "423f19a4ac1e4f48bbb4180756e6eb6c",
150
+        "issued_at": "2015-11-06T14:32:17.893797Z",
151
+    }
152
+
153
+``methods`` in the above payload being the valid and already satisfied auth
154
+methods for that receipt.
155
+
156
+There isn't much data Keystone itself needs that it can't get from database
157
+as long as it knows the user id. All we need to pass back is what methods have
158
+already been validated, when it was issued at (for expiry checking), and the
159
+user the receipt applies to (so we can match it with the user in the auth
160
+request).
161
+
162
+Receipt processing
163
+------------------
164
+
165
+When auth is continued with a receipt a user must supply the receipt id in the
166
+``OPENSTACK-AUTH-RECEIPT`` header. When Keystone sees an auth attempt with
167
+that header it will use the set receipt provider to decrypt the payload (id),
168
+and will then treat the ``methods`` as defined in the receipt as having been
169
+already satisfied as part of auth, and auth continues with the new user
170
+supplied methods.
171
+
172
+If all given methods are valid, but all the total valid methods including those
173
+from the receipt still do not fulfill any of the auth rules, another receipt is
174
+returned.
175
+
176
+If the receipt is expired, don't even process the user supplied auth methods
177
+and fail right away.
178
+
179
+A mismatch between receipt user_id and user_id in any of the methods is a
180
+failure.
181
+
182
+A failure in any of the user supplied auth methods is a failure, and does not
183
+extend the receipt even if some new methods were valid, but should include
184
+failure details.
185
+
186
+If a user supplies a method that was already satisfied in the receipt, the user
187
+supplied method takes precedence, even if it fails.
188
+
189
+All of these failures return a ``401``.
190
+
191
+Alternatives
192
+============
193
+
194
+In Ocata when the auth rules were introduced the alternative was put forward
195
+to simply change the error messages of the failed MFA auth to inform the user
196
+why their auth failed. Any services could also parse the errors and infer
197
+what the missing auth was and generate GUI or cli queries back to the user.
198
+
199
+This doesn't work for a few reasons. While we can structure the response to be
200
+parsable it still requires that for every auth attempt ALL methods are
201
+supplied. This means an MFA attempt for password+totp needs to cache the
202
+password to resubmit it when it is determined that totp is also needed.
203
+
204
+For Horizon that doesn't work. We can't cache the password server-side, and we
205
+shouldn't store it in a cookie or in browser really, and asking the user to
206
+supply their password again isn't good UX.
207
+
208
+This alternative also isn't a real challenge response.
209
+
210
+Security Impact
211
+===============
212
+
213
+A user who authenticates with one successful method now knows what auth rules
214
+can be used for a given user. This isn't particularly unsafe, as while they
215
+know the rules, they can't auth with them. Additionally it is safe to assume
216
+that one successful auth method is enough to prove identity of the user, while
217
+not enough to satisfy authentication requirements.
218
+
219
+If any method fails, we still return an error, and auth rules are only exposed
220
+if at least one method was valid.
221
+
222
+An additional security concern is that a given receipt could be used to make
223
+multiple tokens in the short window it is valid. Given that users can already
224
+have multiple tokens, this is only a concern if a receipt is intercepted and
225
+completed by someone else. Given though that this receipt exists in the context
226
+of MFA, the second factor should limit this concern quite heavily. In reality
227
+this isn't a problem unique to the auth receipt, but an eventual action we
228
+should take is to do some form of receipt revocations when turned into a token.
229
+
230
+Notifications Impact
231
+====================
232
+
233
+Notifications will continue to be issued for successful and fail authentication
234
+as today. Issuance of a receipt will not issue a notification.
235
+
236
+We may add receipt notifications in the future.
237
+
238
+Other End User Impact
239
+=====================
240
+
241
+The user may now process the returned data and utilize the receipt to
242
+authenticate in multiple steps.
243
+
244
+It is important to note that this change does not affect anyone only doing
245
+auth with no auth rules set. The default auth use case does not change, only
246
+the MFA use case which is not yet fully implemented or used anyway.
247
+
248
+Performance Impact
249
+==================
250
+
251
+It is expected load and auth-processing-time will increase a small amount due
252
+added encryption and decryption of the receipt.
253
+
254
+Other Deployer Impact
255
+=====================
256
+
257
+Depending on how we handle fernet/jwt key repositories, deployers may need to
258
+add a second key repository. Ideally we'd allow this to be configurable so at
259
+first they didn't need to do this, but had the option to for added security.
260
+
261
+Developer Impact
262
+================
263
+
264
+This would only affect authentication workflows in OpenStack and any code
265
+dealing with them. This change though will give us a good programmatic way to
266
+deal with MFA and will mean those tools can handle failures in a useful way.
267
+
268
+
269
+Implementation
270
+==============
271
+
272
+Assignee(s)
273
+-----------
274
+
275
+Primary assignee:
276
+
277
+  * Adrian Turjak - adriant@catalyst.net.nz (IRC adriant)
278
+
279
+Work Items
280
+----------
281
+
282
+#. Add support for the auth receipt to Keystone and change the auth plugin
283
+   layer to return it on one successful auth method out of configured rules
284
+   rather than an error, and make the auth layer able to process a receipt for
285
+   continued auth.
286
+#. Add support to KeystoneAuth to handle this correctly and infer from this
287
+   receipt what other methods are needed, as well as adding proper Multi-Method
288
+   support into KeystoneAuth.
289
+#. Work with the CLI and Dashboard teams to build support in for MFA using the
290
+   changes made to KeystoneAuth. (optional follow up)
291
+
292
+Dependencies
293
+============
294
+
295
+N/A
296
+
297
+Documentation Impact
298
+====================
299
+
300
+Will require extra documentation for new features, but no existing non-MFA auth
301
+paths will change.
302
+
303
+We need to add to the docs that MFA receipts also need encryption keys, and
304
+that by default they are shared with fernet. Will need notes added that fernet
305
+key rotation affect the receipts if their repository is shared.
306
+
307
+
308
+References
309
+==========
310
+
311
+* https://adam.younglogic.com/2012/10/multifactor-auth-and-keystone/
312
+* https://blueprints.launchpad.net/keystone/+spec/multi-factor-authn
313
+* https://specs.openstack.org/openstack/keystone-specs/specs/keystone/ocata/per-user-auth-plugin-requirements.html

Loading…
Cancel
Save