/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to doc/developers/authentication-ring.txt

  • Committer: Jelmer Vernooij
  • Date: 2020-07-18 23:14:00 UTC
  • mfrom: (7490.40.62 work)
  • mto: This revision was merged to the branch mainline in revision 7519.
  • Revision ID: jelmer@jelmer.uk-20200718231400-jaes9qltn8oi8xss
Merge lp:brz/3.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
Authentication ring
 
2
===================
 
3
 
 
4
When accessing a remote branch (specified as an URL), it may occur that the
 
5
server requests an authentication.
 
6
 
 
7
This authentication can be provided in different ways:
 
8
 
 
9
1. Embedding the user and password
 
10
in the URL::
 
11
 
 
12
  bzr branch <scheme>://<user>:<password>@host:port/path
 
13
 
 
14
* ``scheme``: Any transport protocol requiring authentication.
 
15
* ``user``: The login used to authenticate.
 
16
* ``password``: The associated password.
 
17
* ``host``: The address of the server.
 
18
* ``port``: The port the server is listening to.
 
19
* ``path``: The path on the server.
 
20
 
 
21
2. Embedding the user in the URL and let bzr find the right password or prompt
 
22
for one::
 
23
 
 
24
  bzr branch <scheme>://<user>@host/path
 
25
 
 
26
3. Embedding nothing in the URL and let bzr find user and password or prompt
 
27
for user and/or password::
 
28
 
 
29
  bzr branch <scheme>://host/path
 
30
 
 
31
This specification proposes a mechanism that will allow users to
 
32
just use ``bzr branch <scheme>://host/path`` or ``bzr branch
 
33
<scheme>://<user>@host/path`` and leaves bzr find the ``user``
 
34
and ``password`` in its configuration files.
 
35
 
 
36
When no user is specified for ``FTP``, ``SFTP`` or ``SSH``, the actual behavior
 
37
of ``bzr`` is to default to ``getpass.get_user()``.
 
38
 
 
39
Any implementation of this specification should respect that behaviour.
 
40
 
 
41
This specification also proposes a way to describe credentials so that several
 
42
remote branches can use the same definition. This is particularily important
 
43
for users handling a lot of passwords and who need to update them on a regular
 
44
basis.
 
45
 
 
46
Rationale
 
47
---------
 
48
 
 
49
Embedding user and passwords in the command line is a security
 
50
hazard (see `bug #34685
 
51
<https://launchpad.net/products/bzr/+bug/34685>`_).
 
52
 
 
53
Storing passwords in ``~/.config/breezy/breezy.conf`` or
 
54
``~/.config/breezy/locations.conf`` is also a security risk.
 
55
 
 
56
Typing user and passwords is error-prone and boring.
 
57
 
 
58
Yet, a safe way to store passwords, while allowing bzr to retrieve them, when
 
59
needed, could improve the bzr user experience.
 
60
 
 
61
This specification describes a way to provide user and passwords to bzr while
 
62
storing them in a relatively safe way.
 
63
 
 
64
Note that SSH servers can be configured to use keys instead of (``user``,
 
65
``password``) and, when used with appropriate agents, provide the same kind of
 
66
comfort this specification aims to provide for all other schemes. Since SSH 
 
67
agents provide a safer way to secure the passwords, this specification is
 
68
restricted to providing ``user`` but does not provide ``password`` when used
 
69
for SSH.
 
70
 
 
71
Authentication definitions
 
72
--------------------------
 
73
 
 
74
There are two kinds of authentication used by the various schemes supported by
 
75
bzr:
 
76
 
 
77
1. user and password
 
78
 
 
79
``FTP`` and ``SFTP`` needs a (``user``, ``password``) to authenticate against a
 
80
``host`` (SFTP can use SSH keys too, but we don't talk about that in this
 
81
specification as SSH agents provide a better solution).
 
82
 
 
83
2. user, realm and password
 
84
 
 
85
``HTTP`` and ``HTTPS`` needs a (``user, realm, password``) to authenticate
 
86
against a host. But, by using ``.htaccess`` files, for example, it is possible
 
87
to define several (``user, realm, password``) for a given ``host``. So what is
 
88
really needed is (``user``, ``password``, ``host``, ``path``). The ``realm``
 
89
can be ignored [#ignored_realm]_ as long as it is still presented to the user
 
90
when prompting for the password (unless someone found a way to declare two
 
91
different realms for the same path).
 
92
 
 
93
``HTTP proxy`` can be handled as ``HTTP`` (or ``HTTPS``) by explicitly
 
94
specifying the appropriate port.
 
95
 
 
96
.. [#ignored_realm] The true purpose of realms is to allow the same credentials
 
97
   to be reused for disjoint hierarchies. Ignoring them in this specification
 
98
   aims to simplify the user experience while still allowing to share the same
 
99
   credentials for a whole hierarchy.
 
100
 
 
101
To take all schemes into account, the password will be deduced from a set of
 
102
authentication definitions (``scheme``, ``host``, ``port``, ``path``, ``user``,
 
103
``password``).
 
104
 
 
105
  * ``scheme``: can be empty (meaning the rest of the definition can be used
 
106
    for any scheme), ``SFTP`` and ``bzr+ssh`` should not be used here, ``ssh``
 
107
    should be used instead since this is the real scheme regarding
 
108
    authentication,
 
109
 
 
110
  * ``host``: can be empty (to act as a default for any host),
 
111
 
 
112
  * ``port`` can be empty (useful when an host provides several servers for the
 
113
    same scheme), only numerical values are allowed, this should be used only
 
114
    when the server uses a port different than the scheme standard port,
 
115
 
 
116
  * ``path``: can be empty (FTP or SFTP will never use it),
 
117
 
 
118
  * ``user``: can be empty (``bzr`` will defaults to Python's
 
119
    ``getpass.get_user()`` for FTP, SFTP and SSH),
 
120
 
 
121
  * ``password``: can be empty (for security reasons, a user may use the
 
122
    definitions without storing the passwords but want to be prompted ; or the
 
123
    password will be provided by an external plugin via the
 
124
    ``password_encoding`` mechanism decribed below). Must be left empty for
 
125
    ``ssh``.
 
126
 
 
127
  * ``password_encoding``: can be empty (default is ``plaintext``).
 
128
 
 
129
Also note that an optional ``verify_certificates=no`` field will allow the
 
130
connection to ``HTTPS`` hosts that provides a self certified certificate (the
 
131
default should be to refuse the connection and inform the user). (Not
 
132
implemented yet)
 
133
 
 
134
Multiple definitions can be provided and, for a given URL, bzr will select a
 
135
(``user`` [, ``password``]) based on the following rules :
 
136
 
 
137
 1. the first match wins,
 
138
 
 
139
 2. empty fields match everything,
 
140
 
 
141
 3. ``scheme`` matches even if decorators are used in the requested URL,
 
142
 
 
143
 4. ``host`` matches exactly or act as a domain if it starts with '.'
 
144
    (``project.bzr.sf.net`` will match ``.bzr.sf.net`` but ``projectbzr.sf.net``
 
145
    will not match ``bzr.sf.net``).
 
146
 
 
147
 5. ``port`` matches if included in the requested URL (exact matches only)
 
148
 
 
149
 6. ``path`` matches if included in the requested URL (and by rule #2 above,
 
150
    empty paths will match any provided path).
 
151
 
 
152
An optional ``password_encoding`` field may specify how the password is encoded
 
153
but has no impact on the definition selection.
 
154
 
 
155
Possible values are ``plaintext`` (no encoding at all) and ``base64``. When the
 
156
field is absent, ``plaintext`` is assumed. Additional encodings may be added in
 
157
future versions.
 
158
 
 
159
Encoding passwords in ``base64``, while weak, provides protection against
 
160
accidental reading (if an administrator have to look into the file, he will not
 
161
see the passwords in clear).
 
162
 
 
163
This specification intends to ease the authentication providing, not to secure
 
164
it in the best possible way.
 
165
 
 
166
Plugins can provide additional password encodings. The provided
 
167
``netrc_credential_store`` plugin can be used as an example implementation.
 
168
 
 
169
Future versions of this specification may provide additional
 
170
encodings [#password_encoding]_.
 
171
 
 
172
.. [#password_encoding] Additional password encoding methods may be defined
 
173
   that will rely on external means to store the password which, in these
 
174
   cases, will not appear anymore in the definition. It is assumed that
 
175
   additional password encodings will provide a storage outside of the file
 
176
   described here. The ``netrc`` encoding, for example, provides passwords by
 
177
   retrieving them from the ``.netrc`` file.
 
178
 
 
179
File format
 
180
-----------
 
181
 
 
182
Even if ``~/.config/breezy/breezy.conf`` and
 
183
``~/.config/breezy/locations.conf`` seems to provide most of the needed
 
184
infrastructure, we choose to use a dedicated file
 
185
for the authentication info ``~/.config/breezy/authentication.conf`` for the following
 
186
reasons:
 
187
 
 
188
  * allow the user to protect the content of one file only, relaxing security
 
189
    constraints on the others,
 
190
 
 
191
  * while ``locations.conf`` is organized around *local* branches,
 
192
    ``authentication.conf`` is organized around *remote* branches or more
 
193
    generally servers. The same authentification definition can even be used
 
194
    for several schemes for servers providing those schemes.
 
195
 
 
196
``~/.config/breezy//authentication.conf`` will use the same file format as
 
197
``~/.config/breezy/breezy.conf``.
 
198
 
 
199
Each section describes an authentication definition.
 
200
 
 
201
The section name is an arbitrary string, only the ``DEFAULT`` value is reserved
 
202
and should appear as the *last* section.
 
203
 
 
204
Each section should define:
 
205
 
 
206
  * ``user``: the login to be used,
 
207
 
 
208
Each section could define:
 
209
 
 
210
  * ``host``: the remote server,
 
211
 
 
212
  * ``port``: the port the server is listening,
 
213
 
 
214
  * ``verify_certificates``: to control certificate verification (useful
 
215
    for self certified hosts). This applies to HTTPS only. Accepted values
 
216
    are yes and no, default to yes.
 
217
 
 
218
  * ``path``: the branch location,
 
219
 
 
220
  * ``password``: the password,
 
221
 
 
222
  * ``password_encoding``: the method used to encode the password if any,
 
223
 
 
224
The default content of the file will be::
 
225
 
 
226
    [DEFAULT]
 
227
 
 
228
This section could define:
 
229
 
 
230
  * ``user``: default user to be used (if not defined the usual
 
231
    bzr way applies, see below).
 
232
 
 
233
  * ``password_encoding``: default password encoding.
 
234
 
 
235
Use Cases
 
236
---------
 
237
 
 
238
The use cases described below use the file format defined above.
 
239
 
 
240
  * all FTP connections to the foo.net domain are done with the same (``user``,
 
241
    ``password``)::
 
242
 
 
243
        # Identity on foo.net
 
244
        [foo.net]
 
245
        scheme=ftp
 
246
        host=foo.net
 
247
        user=joe
 
248
        password=secret-pass
 
249
 
 
250
    will provide ('joe', 'secret-pass') for::
 
251
 
 
252
        bzr branch ftp://foo.net/bzr/branch
 
253
        bzr pull ftp://bzr.foo.net/bzr/product/branch/trunk
 
254
 
 
255
  * all connections are done with the same ``user`` (the remote one for which
 
256
    the default bzr one is not appropriate) and the password is always prompted
 
257
    with some exceptions::
 
258
 
 
259
        # Pet projects on hobby.net
 
260
        [hobby]
 
261
        host=r.hobby.net
 
262
        user=jim
 
263
        password=obvious1234
 
264
 
 
265
        # Home server
 
266
        [home]
 
267
        scheme=https
 
268
        host=home.net
 
269
        user=joe
 
270
        # Obtain the base64 encoded password by running 'echo -n "secret-pass" | base64'
 
271
        password='c2VjcmV0LXBhc3M='
 
272
        password_encoding=base64
 
273
        verify_certificates=no # Still searching a free certificate provider
 
274
 
 
275
        [DEFAULT]
 
276
        # Our local user is barbaz, on all remote sites we're known as foobar
 
277
        user=foobar
 
278
 
 
279
  * an HTTP server and a proxy::
 
280
 
 
281
        # development branches on dev server
 
282
        [dev]
 
283
        scheme=https
 
284
        host=dev.company.com
 
285
        path=/dev
 
286
        user=user1
 
287
        password=pass1
 
288
 
 
289
        # toy branches
 
290
        [localhost]
 
291
        scheme=http
 
292
        host=dev.company.com
 
293
        path=/
 
294
        user=user2
 
295
        password=pass2
 
296
 
 
297
        # proxy
 
298
        [proxy]
 
299
        scheme=http
 
300
        host=proxy.company.com
 
301
        port=3128
 
302
        user=proxyuser1
 
303
        password=proxypass1
 
304
 
 
305
  * source hosting provider declaring sub-domains for each project::
 
306
 
 
307
        [sfnet domain]
 
308
        # we use SFTP, but SSH is the scheme used for authentication
 
309
        scheme=ssh
 
310
        # The leading '.' ensures that 'sf.net' alone doesn't match
 
311
        host=.sf.net
 
312
        user=georges
 
313
        password=ben...son
 
314
 
 
315
 
 
316
UI Changes
 
317
----------
 
318
 
 
319
Depending on the info provided in the URL, bzr will interact with the user in
 
320
different ways:
 
321
 
 
322
1. ``user`` and ``password`` given in the URL.
 
323
 
 
324
  Nothing to do.
 
325
 
 
326
2. ``user`` given in the URL.
 
327
 
 
328
  Get a password from ``~/.config/breezy/authentication.conf`` or prompt
 
329
  for one if none is found.
 
330
 
 
331
3. No ``user`` given in the URL (and no ``password``).
 
332
 
 
333
  Get a user from ``~/.config/breezy/authentication.conf`` or prompt for one if
 
334
  none is found. Continue as 2. (Not implemented yet)
 
335
 
 
336
Note: A user will be queried only if the server requires it for ``HTTP`` or
 
337
``HTTPS``, other protocols always require a user.
 
338
 
 
339
In any case, if the server refuses the authentication, bzr reports to the user
 
340
and terminates.
 
341
 
 
342
Implementation constraints
 
343
--------------------------
 
344
 
 
345
* bzr should be able to prompt for a ``user`` for a given (``scheme``, ``host``
 
346
  [, ``realm``]). Note that ``realm`` is available only after a first
 
347
  connection attempt to the server.
 
348
 
 
349
* No assumptions should be made about the clients of this service
 
350
  (i.e. Transport is the primary target but plugins must be able to use it as
 
351
  well, the definitions used: (``scheme, host, [port,] path``) are general
 
352
  enough to described credentials for ``svn`` servers or LaunchPad XML-RPC
 
353
  calls).
 
354
 
 
355
* Policies regarding default users may be taken into account by the
 
356
  implementations, there is no good way to represent that in this specification
 
357
  and stays flexible enough to accommodate various needs (default user policies
 
358
  may differ for different schemes and that may be easier to handle in the code
 
359
  than in the authentication file itself).
 
360
 
 
361
* If no user can be found by the mechanism described above, bzr should still
 
362
  default to ``getpass.get_user()`` and may attempt a second matching to obtain
 
363
  a password.
 
364
 
 
365
* As this specification proposes a matching between some credentials
 
366
  definitions and real URLs, the implementation provides an optional UI
 
367
  feedback about which credential definition is used. Using ``-Dauth`` will
 
368
  output some traces in the ``brz.log`` file metionning the sections
 
369
  used. This allows the user to validate his definitions.
 
370
 
 
371
Questions and Answers
 
372
---------------------
 
373
 
 
374
  * What if a ``.authinfo`` file exists ?
 
375
 
 
376
    * It will be ignored,
 
377
 
 
378
    * Automatic (one-time) conversions may be proposed if sufficient demand
 
379
      exists,
 
380
 
 
381
  * What if a ``.netrc`` file exists ?
 
382
 
 
383
    * It is honored if the definition specifies
 
384
      ``password_encoding=netrc``.
 
385
 
 
386
  * What mode should the authentication file use ?
 
387
 
 
388
    * 600 read/write for owner only by default, if another mode (more
 
389
      permissive) is used, a warning will be issued to inform the users of the
 
390
      potential risks.(Not implemented yet)
 
391
 
 
392
  * What about using ``seahorse`` on Ubuntu or ``KeyChain Access`` on Mac OS X ?
 
393
 
 
394
    * plugins can be written and registered to handle the associated
 
395
      ``password_encoding``.
 
396
 
 
397
  * Could it be possible to encode the whole authentication file with an SSH key
 
398
    ?
 
399
 
 
400
    * yes and if the user configure a ssh-agent it will not be queried for
 
401
      pass-phrase every time we want to query the file for a password. But
 
402
      that seems a bit extreme for a first version.(Not implemented yet and
 
403
      may be never)
 
404
 
 
405
  * Why can't bzr update the authentication file when it queried the user for a
 
406
    password ?
 
407
 
 
408
    * a future version may address that but:
 
409
 
 
410
      1. The user may want to decide which passwords are stored in the file and
 
411
      which aren't.
 
412
 
 
413
      2. The user should decide if the passwords are encoded (and how) or not
 
414
      (but we may default to base64).
 
415
 
 
416
      3. The right definition may be hard to get right, but reducing it to
 
417
      (``scheme, host, [port,] user, password``) may be a good start. I.e. no
 
418
      path so that all paths on the host will match. The user will have to
 
419
      modify it for more complex configurations anyway.
 
420