Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sources data model #11

Merged
merged 12 commits into from
Dec 6, 2018
314 changes: 292 additions & 22 deletions content/information-distribution/source.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,301 @@ weight: 2
---

A source is an entity holding the responsibility of publishing information
through the Matrix room. Before publishing any information, a source **must**
register itself as such on the room, including data on the organism or
individual operating the source, the publication language and the publication
name space (2️⃣: a Matrix event type), along with one or more public signature
verification keys that will be used to assert the integrity of the information
it publishes, and the signing algorithm used to generate the signature of its
articles (`ed25519`, `hmac-sha256`, `hmac-sha512`, etc.).

A source **must** be trusted by trust authorities operated by organisms it
trusts and is in contact with outside of Informo. If at least one of a source's
private keys gets compromised, the source **must** update its list of public
signature verification keys, and every trust authority trusting the source
**must** compute and issue a new signature taking the updated list of keys into
account. The reason behind this is to encourage trust authorities to communicate
with their trusted sources, estimate how much compromised the source is (i.e.
one key vs all of the keys vs the source's entire Matrix account), and take the
actions it deems necessary.
through the Matrix room. Each source **must** be a registered Matrix user. A
Matrix user **must not** register more than one source.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

A source **must** register itself as such on the room. This **must** be done
through the publication of a `network.informo.source` state event. The event's
state key **must** be the ID of the source's Matrix user. The content of this
event **must** be provided using the following model:

## Matrix event `network.informo.source`

| Parameter | Type | Req. | Description |
| ------------------- | ----------------- | :--: | ----------------------------------------------------------------------------------------------------------------------------------- |
| `name` | `localisedString` | x | Name of the source. |
| `owner` | `string` | x | The company or individual maintaining this source. |
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
| `l10n` | `lang` | x | Languages of the source's publications. |
| `sig_algo` | `string` | x | Algorithm the source will use to cryptographically sign its articles. 🔧 |
| `sig_keys` | `[string]` | x | Public keys the source will use to cryptographically sign its articles. 🔧 |
| `website` | `string` | | URL of the source's website, if there's one. |
| `description` | `localisedString` | | Short description of the source and its publications. |
| `logo` | `string` | | Logo of the source. If provided, must be a [`mxc://` URL](https://matrix.org/docs/spec/client_server/r0.4.0.html#id112). |
| `country` | `string` | | Country of the source's owner. If provided, **must** be compliant with [ISO 3166](https://www.iso.org/iso-3166-country-codes.html). |
| `custom` | `object` | | Additional information for custom client implementations. |

<!-- 🔧: Need to do some research on Megolm and Matrix APIs around encryption
and key management -->

Where:

* `localisedString` is a map associating a [RFC
5646](https://tools.ietf.org/html/rfc5646)-compliant language (and variant)
identifier to a localisation of the string in the language the identifier
refers to.
* `lang` is a map associating a [RFC
5646](https://tools.ietf.org/html/rfc5646)-compliant language (and variant)
identifier to the Matrix user ID of the sub-source that handles the
publication of articles in this language (and variant). This map **must**
contain at least one element. More information on localised sub-sources and
examples are available [below](#localisation).

Each time one of the source's properties changes, it **must** publish a new
registration event, and every trust authority certifying the trustworthiness of
this source **must** update their signature by basing it on the new event. This
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
signature lives in a TA's registration event 📝.

If a source doesn't provide a logo, client implementations **can** use the
[avatar](https://matrix.org/docs/spec/client_server/r0.4.0.html#get-matrix-client-r0-profile-userid-avatar-url)
of its Matrix user in lieu of it if its avatar has been set.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

## Compromission of cryptographic private keys

Every trust authority certifying a source's trustworthiness **must** be
operating by an organism or individual the source trusts and is in contact with
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
outside of Informo. If at least one of a source's private keys gets compromised,
the source **must** update its list of public signature verification keys by
publishing a new registration event containing the updated list, and every trust
authority trusting the source **must** compute and issue a new signature taking
the updated list of keys into account. The reason behind this is to encourage
trust authorities to communicate with their trusted sources, estimate how much
compromised the source is (i.e. one key vs all of the keys vs the source's
entire Matrix account), and take the actions it deems necessary.

In such an event, client implementations **should** consider articles posted
prior to the key being compromised as possibly, but not surely trustworthy.
prior to the key being declared as compromised as possibly, but not surely
trustworthy.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

## Localisation

An information website might want to publish articles in more than one language.
In such case, it **can** create sub-sources, each of which handling the
publication of its articles in one language. A source, regardless of whether it
is a sub-source or not, **must not** publish articles in more than one language.

A sub-source is an entity similar to a source, with the exception that it
**must** be referenced to by a source. Each sub-source **must** be a registered
Matrix user, and **must** register itself on the Matrix room through the
publication of a `network.informo.subsource` state event, with the Matrix user's
ID as the event's state key. The event's content **must** be embedded in a
[signed Matrix event](/information-distribution/signature/#signed-matrix-event),
signed by one of the parent source's public keys, with its `signed` object using
the following model:

### Matrix event `network.informo.subsource`

| Parameter | Type | Req. | Description |
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
| ------------------- | ---------- | :--: | ------------------------------------------------------------------------------ |
| `sig_algo` | `string` | x | Algorithm the sub-source will use to cryptographically sign its articles. 🔧 |
| `sig_keys` | `[string]` | x | Public keys the sub-source will use to cryptographically sign its articles. 🔧 |
| `website` | `string` | | URL of the source's website in this language, if there's one. |
| `description` | `string` | | Short localised description of the source and its publications. |
| `custom` | `object` | | Additional information for custom client implementations. |
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

The parent source **must** then reference the sub-source in its own registration
event, as a `lang` object. The `lang` object **can** reference the source that
emitted the `network.informo.source` event, but a Matrix user ID **must not** be
referenced more than once in a source registration's whole array of `lang`
objects.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

{{% notice info %}}
A source **can** register itself as one if its own sub-sources. In this case, it
doesn't need to emit any `network.informo.subsource` event for this specific
sub-source. The articles published by the source acting as one of its
sub-sources **must** then be signed using the one of the source's public keys.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
{{% /notice %}}

If set, client implemetations **must** use the value for the `description` and
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
`website` keys of the `network.informo.subsource` event instead of the localised
description and the website provided in the parent source's
`network.informo.source` event.

Client implementations **must** consider a sub-source as holding the same [trust
level](/trust-management/trust-level) as its parent source, and therefore
**must** consider it at the same location in trust networks as its parent.
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved

### Example

Considering the example of an example website publishing news only in English,
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
and registering itself as a source with the Matrix user id
`@acmenews:example.com`, and not registering any sub-source, the `lang` object
would look like this:

```
{
"en": "@acmenews:example.com"
}
```

{{% notice tip %}}
In this example, `en-US`, `en-GB`, etc. can be used instead of `en` if the
source wants to explicitely specify language variants.
{{% /notice %}}

## Client implemetations behaviours regarding sources

Client implementations **must** allow users to subscribe to all of the articles
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
published by a specific source.

Client implemetations **can** display a source and all of its sub-sources as a
single entity with several languages available.

Client implemetations **should** allow users to set at least one preferred
language and use it to select the corresponding name and description for sources
that offer a name or a description in this language. If a source doesn't offer
either a name or a description in the user's preferred language, client
implementations **can** select another language to fall back to by allowing the
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
user to set a weighted list of preferred languages. If a source only provide its
name or description in one language, client implemetations **must** use that
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
value.

## Full example

Let's consider a news website, named "ACME News", publishing news in both
English and French, each on a localised website. We'll also consider
`@acmenews:example.com` its main Informo source, and `@acmenewsen:example.com`
and `@acmenewsfr:example.com` its sub-sources, handling the publications of
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
articles, respectively in English and in French.

Here are the state events it needs to emit to properly register all of its
sources.

{{% notice note %}}
In the event of an organism or individual publishing information in several
languages, this organism or individual **must** register a source for each
publication language, with each registration containing the relevant data.
Please keep in mind that, although this can look like a troublesome thing to do,
it can easily be automated using one of the existing [SDKs for
Matrix](https://matrix.org/docs/projects/try-matrix-now.html#client-sdks).
{{% /notice %}}

2️⃣: rest of the page
#### `network.informo.source` event

| Emitter | State key |
| ----------------------- | ----------------------- |
| `@acmenews:example.com` | `@acmenews:example.com` |

```
{
"name": "ACME News",
"origin": "ACME News Group",
"website": "https://www.example.com",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"logo": "mxc://weu.informo.network/AtEuTuVSeIlZQgjEzjGyMDtG",
"sig_algo": "ed25519",
"sig_keys": [
"IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA"
],
"lang": {
"en": "@acmenewsen:example.com",
"fr": "@acmenewsfr:example.com"
}
}
```

#### `network.informo.subsource` event

| Emitter | State key |
| ------------------------- | ------------------------- |
| `@acmenewsen:example.com` | `@acmenewsen:example.com` |

```
{
"algorithm": "ed25519",
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA",
"signature": "54ab6f6f18d63ef1",
"signed": {
"website": "https://www.example.com/en",
"description": "This is the English source for ACME News.",
"sig_algo": "ed25519",
"sig_keys": [
"Noh0oot2chahTheixeuviX6seidiweewahK/8mLeMjA"
]
}
}
```

#### `network.informo.subsource` event

| Emitter | State key |
| ------------------------- | ------------------------- |
| `@acmenewsfr:example.com` | `@acmenewsfr:example.com` |

```
{
"algorithm": "ed25519",
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA",
"signature": "0a1df56f18d63ef1",
"signed": {
"website": "https://www.example.com/fr",
"description": "Ceci est la source française d'ACME News.",
"sig_algo": "ed25519",
"sig_keys": [
"xee1PahM1jutohz2jiec1keeshoW0GooVei/8mLeMjA"
]
}
}
```

Once all of these events have been published, `@acmenewsen:example.com` can
start publishing articles in English, and `@acmenewsfr:example.com` can start
publishing articles in French.

## Alternate example

Let's consider a news website, named "ACME News", publishing news in both
English and French, each on a localised website. We'll also consider
`@acmenews:example.com` its main Informo source, and `@acmenewsfr:example.com`
its sub-source handling the publications of articles in French. The
publication of articles in English is done by ACME News's main source,
`@acmenews:example.com`.

Here are the state events it needs to emit to properly register all of its
sources.

#### `network.informo.source` event

| Emitter | State key |
| ----------------------- | ----------------------- |
| `@acmenews:example.com` | `@acmenews:example.com` |

```
{
"name": "ACME News",
"origin": "ACME News Group",
"website": "https://www.example.com",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
"logo": "mxc://weu.informo.network/AtEuTuVSeIlZQgjEzjGyMDtG",
"sig_algo": "ed25519",
"sig_keys": [
"IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA"
],
"lang": {
"en": "@acmenews:example.com",
"fr": "@acmenewsfr:example.com"
GordonF42 marked this conversation as resolved.
Show resolved Hide resolved
}
}
```

#### `network.informo.subsource` event

| Emitter | State key |
| ------------------------- | ------------------------- |
| `@acmenewsfr:example.com` | `@acmenewsfr:example.com` |

```
{
"algorithm": "ed25519",
"sender_key": "IlRMeOPX2e0MurIyfWEucYBRVOEEUMrOHqn/8mLqMjA",
"signature": "0a1df56f18d63ef1",
"signed": {
"website": "https://www.example.com/fr",
"description": "Ceci est la source française d'ACME News.",
"sig_algo": "ed25519",
"sig_keys": [
"xee1PahM1jutohz2jiec1keeshoW0GooVei/8mLeMjA"
]
}
}
```

Once both of these events have been published, `@acmenews:example.com` can
start publishing articles in English, and `@acmenewsfr:example.com` can start
publishing articles in French.