~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Aaron Bentley
  • Date: 2008-10-16 21:27:10 UTC
  • mfrom: (0.15.26 unshelve)
  • mto: (0.16.74 shelf-ui)
  • mto: This revision was merged to the branch mainline in revision 3820.
  • Revision ID: aaron@aaronbentley.com-20081016212710-h9av3nhk76dvmsv5
Merge with unshelve

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