summaryrefslogtreecommitdiff
path: root/design-documents/009-backup.rst
blob: 0f2a434ac3b56a52b7c6445632c008038f009895 (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
155
156
157
158
159
Design Doc 009: Wallet Backup
#############################

Summary
=======

This document describes the backup system used by Taler wallets.
This is the second, simplified iteration of the proposal, which leaves
out multi-device synchronization.


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

* Backup must work both with and without Anastasis.

  * When not using Anastasis, the user is responsible for keeping
    their wallet's **root secret** safe.

* Arbitrary number of backup providers must be supported.
* Minimize information leaks / timing side channels.

  * User might be able to change some setting to allow more frequent
    backup with less potential data loss but more leakage.

* Minimize potential to lose money or important information.
* Since real-time sync is not supported yet, wallets should have a feature
  where their whole content is "emptied" to another wallet, and the wallet is
  reset.

  .. Note::
     CG: This boils down to the existing 'reset' button (developer mode).
     Very dangerous. Could be OK if we had some way to notice the number of wallets
     using the same backup and then allow this 'reset' as longa as # wallets > 1.
     Still, doing so will require a handshake with the other wallets to ensure
     that the user doesn't accidentally reset on both wallets at the same time,
     each believing the other wallet is still sync'ed. So we would need like
     a 2-phase commit "planning to remove", "acknowledged" (by other wallet), "remove".
     Very bad UX without real-time sync.

* Even without real-time sync, the backup data must support merging with old, existing wallet
  state, as the device that the wallet runs on may  be restored from backup or be offline
  for a long time.


Solution Overview
=================

Each wallet has a 64 (CG: 32 should be enough, AND better for URLs/QR codes/printing/writing down)
byte wallet **root secret**, which is used to derive all other secrets
used during backup, which are currently:

1. The private **account key** for a sync provider, derived using the sync provider's base URL as salt.
   The base URL must be normalized to end with a "/". The schema ("http://" or "https://") is part of the
   base URL, thus different account keys would be used for "http://" vs. "https://" (reduces linkability).
2. The **symmetric key** used to encrypt/decrypt the backup blob. FIXME: document exact KDF salt here
   once implemented.

If the user chooses to use Anastasis, the following information is backed up in Anastasis
(as the **core secret** in Anastasis terminology):

* Taler Wallet core secret tag (new GANA registry) and format version
* List of used backup providers (sync)
* Wallet root secret
* **Tor constraint** (boolean) advising wallets that the backup should only be accessed via
  Tor and that users must be warned before attempting to restore the backup without Tor.


Supported Operations
--------------------

* **restore-from-anastasis**:  Start Anastasis recovery process.
  This requires the wallet backup state to be uninitialized.
  FIXME: The last sentence makes no sense, as the user may have to pay for recovery!
* **restore-from-recovery-secret**:  This requires the wallet backup state to be uninitialized.
  FIXME: Again, I do not think we can require this. User could make backup,
  then loose device. Create new wallet. Use new wallet (including making
  yet another backup). THEN user remembers that he
  had a backup (or find root key) and now want to restore backup. This should
  MERGE the two states (you can consider it a 'poor' version of 'sync'). Note
  that the lost device cannot 'abandon' the backed up state here!
* **add-provider** / **remove-provider**:  Add/remove a sync provider from the
  list of providers.  Adding a provider will cause payment(s) to the provider
  to be scheduled according to the provider's terms.  If the wallet backup
  state is "uninitialized", adding a provider will set the backup state to
  "initialized" with a fresh wallet root key.  Changing the provider list will
  also update the sync provider URL list in the  Anastasis core secret (forcing
  a new policy to be uploaded).
* **abandon** / **takeover**: When the user wants to stop using a wallet on a particular
  device, another wallet can "take over" by reading the recovery secret of the abandoned wallet.
  The abandoned wallet marks explicitly in its backup blob that it is abandoned.
  Abandoning a wallet will set the backup state to "uninitialized".
* **backup**: Do a backup cycle.  Uploads the latest wallet state to all
  sync providers.  If sync provider state has changed unexpectedly, downloads
  backup, merges, and then uploads the reconciled state.
* **rekey**:  Change to a new wallet root secret, in case the old one has been
  compromised.  Only protectes future funds of the wallet from being
  compromised.  Requires a new payment to all configured sync providers.
* **backup-to-anastasis** is missing.



Backup Format
-------------

TBD.  Considerations from :doc:`005-wallet-backup-sync` still apply,
especially regarding the CRDT.


Initial User Experience
-----------------------

The user will be asked to set up backup&sync (by selecting a provider)
after the first withdrawal operation has been confirmed.  After selecting
the backup&sync providers, the user will be presented with a "checklist" that
contains an option to (1) show/print the recovery secret and (2) set up Anastasis.

The wallet will initially only withdraw enough money to pay the
backup&sync/anastasis providers.  Only after successful backup of the wallet's
signed planchets, the full withdrawal will be completed.


Open Questions
==============

* Should the exchange tell the wallet about available sync/Anastasis providers?
  Otherwise, what do we do if the wallet does not know any providers for the
  currency of the user?
* Should the wallet root secret and wallet database be locally encrypted
  and protected via a passphrase?
* What happens if the same Anastasis user has multiple wallets?  Can Anastasis somehow
  support multiple "instances" per application?

  .. Note::
     CG would definitively solve this using a more complex format for the **master secret**,
     basically serializing mutliple **root secret** values with meta data
     (which wallet/device/name).


Future Work / Ideas
===================

* Incremental backups?

  * Instead of one big blob that always needs to be read/written, we could have (1) a
    limited length append-only journal and (2) a merkle tree so that the backup blob can
    be updated incrementally once the journal is full.
  * Leaks more information and is more complex.

* Mult-device synchronization, with synchronous communication either over some signaling server
  or P2P connectivity (WebRTC, etc.)

  * Destroys the "wallet" metaphor, now the wallet is more like an account.
  * We should first agree on the requirements from the perspective of end users
  * P2P payments in Taler might also make sync less important
  * Maybe only parts of the state (purchases / contracts, but not coins) should be synchronized?
  * WhatsApp web model:  The wallet runs only on one devices, but other devices
    can connect to it as clients.  (Allows my browser wallet to temporarily access
    money from my phone wallet and vice versa.)