Skip to content
This repository was archived by the owner on Apr 16, 2025. It is now read-only.

Commit 6213f30

Browse files
committed
RFC: Identity Proofs
Signed-off-by: Kim Altintop <[email protected]>
1 parent 18a4bd0 commit 6213f30

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

docs/rfc/identity_proofs.md

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
# RFC: Identity Proofs
2+
3+
* Author: @kim
4+
* Date: 2021-02-23
5+
* Status: draft
6+
* Community discussion: n/a
7+
8+
## Motivation
9+
10+
A `radicle-link` [identity][ids] is a hash-linked sequence of signed statements
11+
about public-key delegations: if an entry in this sequence is found to conform
12+
to a quorum rule of cryptographic signatures, the set of keys it delegates to
13+
can be considered trustworthy _iff_ the previous set was. Yet, how can we trust
14+
the initial set of keys in this chain?
15+
16+
## Overview
17+
18+
We consider it impractical for most participants in the `radicle-link` network
19+
to exchange public keys out-of-band, given a pattern of casual interaction with
20+
others. While the protocol mandates connections between participants, similar to
21+
"following" relationships found in social media, we thus consider it
22+
insufficient to infer a [web of trust][wot] from those relationships.
23+
24+
To lift the requirement for physical authenticity checks, but still increase
25+
confidence of a given public key being associated with a particular person,
26+
[keybase] have popularised a scheme dubbed "Social Proofs": a statement claiming
27+
ownership of a particular account on a social media site is written to the
28+
keybase "sigchain" (which has properties similar to a `radicle-link` identity).
29+
This claim (implying also the history of the sigchain) is signed using a key
30+
currently valid according to the chain, and the signature (along with the public
31+
key) is stored at the social media site. To verify the claim, the signature is
32+
retrieved from the social media site in such a way that it could _plausibly_
33+
only be created by the owner of the claimed account. If both the sigchain
34+
integrity and the claim signature can be verified, the association is proven.
35+
36+
This mechanism can be considered a practical application of the [Turing test]:
37+
even though it can not be proven beyond doubt that the account is indeed
38+
associated with a real person, the evidence of others accepting it as such, as
39+
well as conversational behaviour, can increase the confidence in the
40+
authenticity of the online persona. Because key and account ownership at a given
41+
point in time can be cryptographically verified, this confidence can be extended
42+
to the proving side.
43+
44+
We conclude that this mechanism would be a good fit for `radicle-link` (due to
45+
the similarities), and a desirable feature of applications built on top of it.
46+
47+
The following sections describe how such claims shall be stored in the identity
48+
payload of a `radicle-link` identity, how to obtain a publishable proof, and how
49+
to verify it.
50+
51+
## Claims
52+
53+
Claims can only be made by identities of kind `Person`, and claim a single
54+
external account identifier. They are introduced by defining a new payload type,
55+
identified by the URL:
56+
57+
https://radicle.xyz/link/claim/v1
58+
59+
The shape of the JSON structure is:
60+
61+
```json
62+
{
63+
"service": {
64+
"name": "STRING",
65+
"account": "STRING"
66+
},
67+
"expiration": {
68+
"created": INTEGER,
69+
"expires": INTEGER
70+
},
71+
"proof": "URL"
72+
}
73+
```
74+
75+
Where the fields denote:
76+
77+
* `service`
78+
* `name`
79+
80+
A conventional identifier of the external service, e.g. "github",
81+
"twitter", "radicle-ethereum"
82+
83+
* `account`
84+
85+
The unique account identifier within the service, using the service-
86+
specific canonical string representation e.g. "kim",
87+
"0x32be343b94f860124dc4fee278fdcbd38c102d88".
88+
89+
* `expiration` (optional)
90+
* `created`
91+
92+
Creation timestamp of the claim, in seconds since 1970-01-01T00:00:00Z.
93+
94+
* `expires`
95+
96+
Seconds relative to `created`, after which the claim should no longer be
97+
considered.
98+
99+
* `proof` (optional)
100+
101+
A URL to assist verification tooling in retrieving the proof from the external
102+
system. This is mainly a convenience, and obviously requires creation of a new
103+
revision after the fact.
104+
105+
## Proof Generation
106+
107+
The above claim payload is committed to the identity history as a new revision.
108+
Technically, this revision needs to be approved by all key delegations for
109+
verification to pass later on, but since we assume that eligible keys are held
110+
by the same person, it may be acceptable to publish the proof right away for
111+
user experience reasons.
112+
113+
The actual proof consists of the following tuple:
114+
115+
(root, revision, public key, signature)
116+
117+
> TODO: include a protocol bit (denoting "git"), for forwards compat?
118+
119+
The values `root`, `revision`, and `public key` are specified in
120+
[identities][ids], and it is RECOMMENDED to follow the serialisation formats
121+
devised there. `signature` is the Ed25519 signature over `revision`, in much the
122+
same way as the actual revision is signed. All values can thus be obtained by
123+
inspecting the identity storage.
124+
125+
It is beyond the scope of this document to devise the exact external format to
126+
serialise the tuple into, as this is expected to vary from service to service.
127+
128+
## Revocation
129+
130+
A claim can be revoked by creating a new identity revision which simply does not
131+
contain the claim payload. Likewise, a later claim describing the same `(service
132+
name, account)` mapping invalidates an earlier one.
133+
134+
> NOTE: claiming multiple accounts per service is permissible in principle, but
135+
> might be undesirable for certain services. In this case, service-specific
136+
> post-validation is required.
137+
138+
## Verification
139+
140+
1. Given the 4-tuple specified [above][#proof-generation], it is first verified
141+
that the signature is valid for the given `revision` and `public key`.
142+
143+
2. If it is, the identity history needs to be resolved from local storage, or
144+
the network.
145+
146+
2.1 If persistence of verification results is available, the identity document
147+
at the given `revision` is retrieved, its `root` compared against the
148+
supplied one, and it is verified that the given `public key` is a member
149+
of the `delegations` set. If expiration is specified in the claim, it is
150+
determined if `expiration` seconds already elapsed since `created`
151+
according to the clock, in which case verification fails.
152+
2.2 Otherwise, the identity verification procedure is run first, after which
153+
the history is walked backwards until the `revision` is found. Then, step
154+
2.1 is performed.
155+
156+
3. Lastly, the identity history needs to be examined for revocations.
157+
158+
## Discussion
159+
160+
The inclusion of the `revision` in the proof allows to assert that `root` is
161+
indeed an ancestor, which opens up another way to detect "forks" of the identity
162+
history: due to the peer-to-peer nature of the `radicle-link` network, it is
163+
vulnerable to attacks which involve withholding data from other participants, in
164+
which case a fork may go unnoticed.
165+
166+
It should be noted, however, that refreshing the proof from time to time in
167+
order to ensure freshness of the data retrieved through `radicle-link` is not
168+
always practicable.
169+
170+
In order to prove that the(ir own) server is not lying by omission, Keybase
171+
[anchors a merkle root][keybase-stellar] on a blockchain, which includes all
172+
sigchains registered in the Keybase directory. Because `radicle-link` does not
173+
have such a central directory, this approach could only be applied to a partial
174+
view of the network.
175+
176+
While conceivable that, given the right incentives, such a directory service
177+
could be operated independently (similar to what the [ceramic] network devises),
178+
it is unclear what value blockchain anchors of individual identities have, given
179+
that transaction costs discourage frequent updates.
180+
181+
It has also been proposed to employ a mutual attestation scheme with a
182+
blockchain (namely the [radicle-contracts]), but we haven't been able to
183+
convince ourselves that this is practical (or even beneficial) because:
184+
185+
1. the verification obligation becomes more complex
186+
2. the creation procedure becomes more complex
187+
3. it is unclear what to do in case of conflicting statements (in the presence
188+
of revocations)
189+
4. the lying by omission problem is not solved, due to the disincentive to
190+
refresh proofs
191+
192+
We thus RECOMMEND to either:
193+
194+
* incentivise bulk anchoring
195+
196+
* integrate with an existing bulk anchoring service
197+
198+
Note that in this case the external service becomes authoritative, and no
199+
extension to the `radicle-link` protocol as described here is necessary.
200+
201+
* treat "web3"- like any other web-service
202+
203+
This may entail finding ways to reduce costs, for example by storing the proof
204+
payload in transaction logs (which can be verified separately).
205+
206+
---
207+
208+
[ids]: ../spec/identities.md
209+
[wot]: https://en.wikipedia.org/wiki/Web_of_trust
210+
[keybase]: https://keybase.io
211+
[tt]: https://en.wikipedia.org/wiki/Turing_test
212+
[keybase-stellar]: https://book.keybase.io/docs/server/stellar
213+
[ceramic]: https://github.com/ceramicnetwork/ceramic/blob/master/SPECIFICATION.md#blockchain-anchoring
214+
[radicle-contracts]: https://github.com/radicle-dev/radicle-contracts

0 commit comments

Comments
 (0)