|
| 1 | +# MSC4114: Matrix as a password manager |
| 2 | + |
| 3 | +Password managers are used in abundance in both the personal and corporate |
| 4 | +space to securely and conveniently store and share secrets. This proposal |
| 5 | +outlines a scheme for storing a hierarchy of secrets in Matrix by borrowing |
| 6 | +from standard concepts such as rooms and spaces. |
| 7 | + |
| 8 | +## Proposal |
| 9 | + |
| 10 | +### Secret hierarchy |
| 11 | + |
| 12 | +Two new room types `m.vault` and `m.vault.secret` are introduced. Vault-rooms |
| 13 | +work similar to [spaces] and can group other vault-rooms or secret-rooms. |
| 14 | +Secret-rooms store the actual sensitive data, such as passwords. |
| 15 | + |
| 16 | +Sending normal `m.room.message` events within vault- and secret-rooms is |
| 17 | +discouraged - clients are not generally expected to have a way to render the |
| 18 | +timeline of these rooms. As such, vault- and secret-rooms should be created |
| 19 | +with `m.room.power_levels` which prohibit normal events by setting |
| 20 | +`events_default` to a suitably high number. In the default power level |
| 21 | +structure, this would be 100. |
| 22 | + |
| 23 | +Additionally, vault- and secret-rooms should be created with a join rule of |
| 24 | +`invite` to prevent unintended access without explicit sharing. |
| 25 | + |
| 26 | +To include a secret (or another vault) in a vault, an `m.vault.child` state |
| 27 | +event is introduced. The state key of the event is the room ID of the secret |
| 28 | +(or other vault) to include. In `content`, the event has a single field `via` |
| 29 | +that lists servers to try and join through. |
| 30 | + |
| 31 | +``` |
| 32 | +{ |
| 33 | + "type": "m.vault.child", |
| 34 | + "state_key": "!roomid:example.org", |
| 35 | + "content": { |
| 36 | + "via": [ |
| 37 | + "example.org", |
| 38 | + "other.example.org" |
| 39 | + ] |
| 40 | + }, |
| 41 | + ... |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +No rooms other than those of type `m.vault` and `m.vault.secret` are allowed to |
| 46 | +be stored in `m.vault.child` events. |
| 47 | + |
| 48 | +Unlike with spaces, there is no corresponding `m.vault.parent` event, meaning a |
| 49 | +vault or secret does not know which parent vaults contain it. While in spaces |
| 50 | +this backlink exists to aid discoverability, this feature appears unessential |
| 51 | +for secret hierarchies. |
| 52 | + |
| 53 | +### Storing secrets |
| 54 | + |
| 55 | +To store secrets, a new room event type `m.secret` is introduced. Building upon |
| 56 | +[MSC1767], secret-events contain a single `m.secret.sections` content block that |
| 57 | +holds an ordered array of section definitions with the following properties: |
| 58 | + |
| 59 | +- `title` – A textual description (optional) |
| 60 | +- `fields` – An ordered array of field definitions (required) |
| 61 | + |
| 62 | +Fields in turn have the following properties: |
| 63 | + |
| 64 | +- `title` – A textual description (optional) |
| 65 | +- `type` – An identifier for the type of value stored (optional). One of: |
| 66 | + - `text` – Any text. If `type` is omitted, this is the default. |
| 67 | + - `username` – A username or other account identifier |
| 68 | + - `password` – A password or other account secret |
| 69 | + - `url` – A web address |
| 70 | + - `email` – An email address |
| 71 | + - `address` – A street or postal address |
| 72 | + - `date` – A date represented as a UNIX timestamp |
| 73 | + - `monthyear` – A month / year combination expressed as `MM/YY` |
| 74 | + - `phonenumber` – A phone number |
| 75 | + - `security_question` – A security question answer. The question itself is to be |
| 76 | + put into the `title` field. |
| 77 | +- `value` – The content stored (required). For fields of type `date`, this is an |
| 78 | + integer, otherwise a string. |
| 79 | + |
| 80 | +``` |
| 81 | +{ |
| 82 | + "type": "m.secret", |
| 83 | + "content": { |
| 84 | + "m.secret.sections": [{ |
| 85 | + "fields": [{ |
| 86 | + "type": "username", |
| 87 | + "value": "johndoe" |
| 88 | + }, { |
| 89 | + "type": "password", |
| 90 | + "value": "johnboy84" |
| 91 | + }] |
| 92 | + }, { |
| 93 | + "title": "Security questions", |
| 94 | + fields: [{ |
| 95 | + "type": "security_question", |
| 96 | + "title": "What is your favorite ice cream flavor?", |
| 97 | + "value": "Lemon" |
| 98 | + }] |
| 99 | + }] |
| 100 | + } |
| 101 | +} |
| 102 | +``` |
| 103 | + |
| 104 | +Clients can choose to use the order of sections and fields in the event for |
| 105 | +sorting data in the UI but are not required to do so. |
| 106 | + |
| 107 | +`m.secret` events are not meant to be used in rooms other than those of type |
| 108 | +`m.vault.secret` and should always be encrypted. |
| 109 | + |
| 110 | +When updating secrets, clients should use [event replacements] which allows |
| 111 | +building a history of changes. Similarly, clients can use [redactions] to |
| 112 | +clear parts of the change history. At any given time, a secret-room should, |
| 113 | +thus, contain at most one non-redacted, non-replaced `m.secret` event which |
| 114 | +gives the current state of the secret. |
| 115 | + |
| 116 | +### Other aspects |
| 117 | + |
| 118 | +Vaults and secrets can be shared through standard room membership. When adding |
| 119 | +a secret-room (or another vault-room) to a vault-room, a restricted [join rule] |
| 120 | +should be set so that being invited into a vault-room enables users to also |
| 121 | +join all of its child-rooms. |
| 122 | + |
| 123 | +The standard `m.room.name` and `m.room.avatar` state events can be used to label |
| 124 | +and decorate vaults and secrets. These are not currently encryptable but will be |
| 125 | +once [MSC3414] lands. While exposing vault and secret names is not considered a |
| 126 | +security concern by other password managers such as [pass], it can still be a |
| 127 | +privacy concern. Therefore, clients should warn users appropriately in the meantime. |
| 128 | + |
| 129 | +## Potential issues |
| 130 | + |
| 131 | +When sharing _and_ federating, secrets can end up being stored on different home |
| 132 | +servers over time. However, federation is probably not a desirable feature of |
| 133 | +password managers anyway. |
| 134 | + |
| 135 | +## Alternatives |
| 136 | + |
| 137 | +Multiple `m.secret` events could be stored in the same room, eliminating the |
| 138 | +need to have different room types for vaults and secrets. However, this doesn't |
| 139 | +allow for fine-grained sharing of secrets with other users and would make it |
| 140 | +impossible to reuse `m.room.name` and `m.room.avatar` events to annotate secrets. |
| 141 | + |
| 142 | +Secrets could be stored in state events which already have replacement semantics. |
| 143 | +As mentioned earlier though, state events are not encryptable yet. |
| 144 | + |
| 145 | +The sections and fields of `m.secret` events could be broken out into separate |
| 146 | +events. This would, however, complicate client display logic and require an |
| 147 | +additional way of sorting sections and fields. |
| 148 | + |
| 149 | +## Security considerations |
| 150 | + |
| 151 | +Until [MSC3414] lands, `m.room.name` and `m.room.avatar` events will leak meta |
| 152 | +data of vaults and secrets. |
| 153 | + |
| 154 | +## Unstable prefix |
| 155 | + |
| 156 | +Until this proposal is accepted into the spec implemenations should refer to: |
| 157 | + |
| 158 | +- `m.vault` as `org.matrix.mscXXXX.vault` |
| 159 | +- `m.vault.secret` as `org.matrix.mscXXXX.vault.secret` |
| 160 | +- `m.vault.child` as `org.matrix.mscXXXX.vault.child` |
| 161 | +- `m.secret` as `org.matrix.mscXXXX.secret` |
| 162 | +- `m.secret.sections` as `org.matrix.mscXXXX.secret.sections` |
| 163 | + |
| 164 | +## Dependencies |
| 165 | + |
| 166 | +None. |
| 167 | + |
| 168 | +[event replacements]: https://spec.matrix.org/latest/client-server-api/#event-replacements |
| 169 | +[join rule]: https://spec.matrix.org/v1.3/client-server-api/#mroomjoin_rules |
| 170 | +[MSC1767]: https://github.com/matrix-org/matrix-spec-proposals/pull/1767 |
| 171 | +[MSC3414]: https://github.com/matrix-org/matrix-spec-proposals/pull/3414 |
| 172 | +[pass]: https://www.passwordstore.org/ |
| 173 | +[redactions]: https://spec.matrix.org/latest/client-server-api/#redactions |
| 174 | +[spaces]: https://spec.matrix.org/v1.3/client-server-api/#spaces |
0 commit comments