~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

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

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-04-28 09:59:22 UTC
  • mfrom: (1684.1.8 bzr.mbp.integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060428095922-4c5cfc2812115f2f
(mbp) commit editor improvements

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 ``~/.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`` 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 ``~/.bazaar/bazaar.conf`` and ``~/.bazaar/locations.conf`` seems to
183
 
provide most of the needed infrastructure, we choose to use a dedicated file
184
 
for the authentication info ``~/.bazaar/authentication.conf`` for the following
185
 
reasons:
186
 
 
187
 
  * allow the user to protect the content of one file only, relaxing security
188
 
    constraints on the others,
189
 
 
190
 
  * while ``locations.conf`` is organized around *local* branches,
191
 
    ``authentication.conf`` is organized around *remote* branches or more
192
 
    generally servers. The same authentification definition can even be used
193
 
    for several schemes for servers providing those schemes.
194
 
 
195
 
``~/.bazaar/authentication.conf`` will use the same file format as
196
 
``~/.bazaar/bazaar.conf``.
197
 
 
198
 
Each section describes an authentication definition.
199
 
 
200
 
The section name is an arbitrary string, only the ``DEFAULT`` value is reserved
201
 
and should appear as the *last* section.
202
 
 
203
 
Each section should define:
204
 
 
205
 
  * ``user``: the login to be used,
206
 
 
207
 
Each section could define:
208
 
 
209
 
  * ``host``: the remote server,
210
 
 
211
 
  * ``port``: the port the server is listening,
212
 
 
213
 
  * ``verify_certificates``: to control certificate verification (useful
214
 
    for self certified hosts). This applies to HTTPS only. Accepted values
215
 
    are yes and no, default to yes.
216
 
 
217
 
  * ``path``: the branch location,
218
 
 
219
 
  * ``password``: the password,
220
 
 
221
 
  * ``password_encoding``: the method used to encode the password if any,
222
 
 
223
 
The default content of the file will be::
224
 
 
225
 
    [DEFAULT]
226
 
 
227
 
This section could define:
228
 
 
229
 
  * ``user``: default user to be used (if not defined the usual
230
 
    bzr way applies, see below).
231
 
 
232
 
  * ``password_encoding``: default password encoding.
233
 
 
234
 
Use Cases
235
 
---------
236
 
 
237
 
The use cases described below use the file format defined above.
238
 
 
239
 
  * all FTP connections to the foo.net domain are done with the same (``user``,
240
 
    ``password``)::
241
 
 
242
 
        # Identity on foo.net
243
 
        [foo.net]
244
 
        scheme=ftp
245
 
        host=foo.net
246
 
        user=joe
247
 
        password=secret-pass
248
 
 
249
 
    will provide ('joe', 'secret-pass') for::
250
 
 
251
 
        bzr branch ftp://foo.net/bzr/branch
252
 
        bzr pull ftp://bzr.foo.net/bzr/product/branch/trunk
253
 
 
254
 
  * all connections are done with the same ``user`` (the remote one for which
255
 
    the default bzr one is not appropriate) and the password is always prompted
256
 
    with some exceptions::
257
 
 
258
 
        # Pet projects on hobby.net
259
 
        [hobby]
260
 
        host=r.hobby.net
261
 
        user=jim
262
 
        password=obvious1234
263
 
 
264
 
        # Home server
265
 
        [home]
266
 
        scheme=https
267
 
        host=home.net
268
 
        user=joe
269
 
        # Obtain the base64 encoded password by running 'echo -n "secret-pass" | base64'
270
 
        password='c2VjcmV0LXBhc3M='
271
 
        password_encoding=base64
272
 
        verify_certificates=no # Still searching a free certificate provider
273
 
 
274
 
        [DEFAULT]
275
 
        # Our local user is barbaz, on all remote sites we're known as foobar
276
 
        user=foobar
277
 
 
278
 
  * an HTTP server and a proxy::
279
 
 
280
 
        # development branches on dev server
281
 
        [dev]
282
 
        scheme=https
283
 
        host=dev.company.com
284
 
        path=/dev
285
 
        user=user1
286
 
        password=pass1
287
 
 
288
 
        # toy branches
289
 
        [localhost]
290
 
        scheme=http
291
 
        host=dev.company.com
292
 
        path=/
293
 
        user=user2
294
 
        password=pass2
295
 
 
296
 
        # proxy
297
 
        [proxy]
298
 
        scheme=http
299
 
        host=proxy.company.com
300
 
        port=3128
301
 
        user=proxyuser1
302
 
        password=proxypass1
303
 
 
304
 
  * source hosting provider declaring sub-domains for each project::
305
 
 
306
 
        [sfnet domain]
307
 
        # we use SFTP, but SSH is the scheme used for authentication
308
 
        scheme=ssh
309
 
        # The leading '.' ensures that 'sf.net' alone doesn't match
310
 
        host=.sf.net
311
 
        user=georges
312
 
        password=ben...son
313
 
 
314
 
 
315
 
UI Changes
316
 
----------
317
 
 
318
 
Depending on the info provided in the URL, bzr will interact with the user in
319
 
different ways:
320
 
 
321
 
1. ``user`` and ``password`` given in the URL.
322
 
 
323
 
  Nothing to do.
324
 
 
325
 
2. ``user`` given in the URL.
326
 
 
327
 
  Get a password from ``~/.bazaar/authentication.conf`` or prompt
328
 
  for one if none is found.
329
 
 
330
 
3. No ``user`` given in the URL (and no ``password``).
331
 
 
332
 
  Get a user from ``~/.bazaar/authentication.conf`` or prompt for one if none is
333
 
  found. Continue as 2. (Not implemented yet)
334
 
 
335
 
Note: A user will be queried only if the server requires it for ``HTTP`` or
336
 
``HTTPS``, other protocols always require a user.
337
 
 
338
 
In any case, if the server refuses the authentication, bzr reports to the user
339
 
and terminates.
340
 
 
341
 
Implementation constraints
342
 
--------------------------
343
 
 
344
 
* bzr should be able to prompt for a ``user`` for a given (``scheme``, ``host``
345
 
  [, ``realm``]). Note that ``realm`` is available only after a first
346
 
  connection attempt to the server.
347
 
 
348
 
* No assumptions should be made about the clients of this service
349
 
  (i.e. Transport is the primary target but plugins must be able to use it as
350
 
  well, the definitions used: (``scheme, host, [port,] path``) are general
351
 
  enough to described credentials for ``svn`` servers or LaunchPad XML-RPC
352
 
  calls).
353
 
 
354
 
* Policies regarding default users may be taken into account by the
355
 
  implementations, there is no good way to represent that in this specification
356
 
  and stays flexible enough to accommodate various needs (default user policies
357
 
  may differ for different schemes and that may be easier to handle in the code
358
 
  than in the authentication file itself).
359
 
 
360
 
* If no user can be found by the mechanism described above, bzr should still
361
 
  default to ``getpass.get_user()`` and may attempt a second matching to obtain
362
 
  a password.
363
 
 
364
 
* As this specification proposes a matching between some credentials
365
 
  definitions and real URLs, the implementation provides an optional UI
366
 
  feedback about which credential definition is used. Using ``-Dauth`` will
367
 
  output some traces in the ``.bzr.log`` file metionning the sections
368
 
  used. This allows the user to validate his definitions.
369
 
 
370
 
Questions and Answers
371
 
---------------------
372
 
 
373
 
  * What if a ``.authinfo`` file exists ?
374
 
 
375
 
    * It will be ignored,
376
 
 
377
 
    * Automatic (one-time) conversions may be proposed if sufficient demand
378
 
      exists,
379
 
 
380
 
  * What if a ``.netrc`` file exists ?
381
 
 
382
 
    * It is honored if the definition specifies
383
 
      ``password_encoding=netrc``.
384
 
 
385
 
  * What mode should the authentication file use ?
386
 
 
387
 
    * 600 read/write for owner only by default, if another mode (more
388
 
      permissive) is used, a warning will be issued to inform the users of the
389
 
      potential risks.(Not implemented yet)
390
 
 
391
 
  * What about using ``seahorse`` on Ubuntu or ``KeyChain Access`` on Mac OS X ?
392
 
 
393
 
    * plugins can be written and registered to handle the associated
394
 
      ``password_encoding``.
395
 
 
396
 
  * Could it be possible to encode the whole authentication file with an SSH key
397
 
    ?
398
 
 
399
 
    * yes and if the user configure a ssh-agent it will not be queried for
400
 
      pass-phrase every time we want to query the file for a password. But
401
 
      that seems a bit extreme for a first version.(Not implemented yet and
402
 
      may be never)
403
 
 
404
 
  * Why can't bzr update the authentication file when it queried the user for a
405
 
    password ?
406
 
 
407
 
    * a future version may address that but:
408
 
 
409
 
      1. The user may want to decide which passwords are stored in the file and
410
 
      which aren't.
411
 
 
412
 
      2. The user should decide if the passwords are encoded (and how) or not
413
 
      (but we may default to base64).
414
 
 
415
 
      3. The right definition may be hard to get right, but reducing it to
416
 
      (``scheme, host, [port,] user, password``) may be a good start. I.e. no
417
 
      path so that all paths on the host will match. The user will have to
418
 
      modify it for more complex configurations anyway.
419