-
Notifications
You must be signed in to change notification settings - Fork 8
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
Identity RFC & Research #15
base: master
Are you sure you want to change the base?
Conversation
d681499
to
68e0f82
Compare
82ec4d1
to
949c415
Compare
It's unclear to me how the identity-manager is aware of all of the devices? Say they're using uport -- which has an attested DID, is this their root identity and key? How does that get them a list of other devices that they logged in with? Are they going to use their ethereum key as their root key? The web3 sign method doesn't work in any gateway that I've tried. It's very unclear to me how the identity-manager is a) going to be aware of other device entries b) going to be able to sign new identities for existing users |
It depends on the DID method. A naive solution for uPort is to use an attestation (something like "IDM-Devices") to store an array of the devices. When the DID “did:uport:x” gets setup on a IDM of a new device, this array grows to 1 device. When the same DID gets setup on the IDM of a second device, this array will grow to two devices. Note that during each setup, the user will be prompted to accept the updated attestation.
Yes.
Answered in the first question. Essentially, in case of uPort, diferent IDMs that hold the same DID would request this attestation to get the list of devices. @joaosantos15 will answer your last question. |
Hey, @fritzy, thank you for your comments. You point out some aspects which can be clarified in the RFC, @satazor and I will get to it. Regarding some of your questions,
That would be the case if the user chooses to use an Ethereum based DID (such as ERC-725)
I am not entirely sure I understand the problem. I have used web3.eth sign methods before, usually in the browser, with Metamask, but also in a Nodejs environment using eth-sign-util. In order for the function to work you need to have your Ethereum account unlocked, so you need to call If, however, there is another problem with web3 signature methods, maybe you could open an issue on the |
I've updated the RFC where I mistakenly said the the Session Private Keys where generated and stored on applications side. It's now clear the the Session Private Key securely lives in the IdentityManager. |
Updated perfect-forward-secrecy paragraph and minor typos fixes
|
||
## Standards & foundations | ||
|
||
### Decentralized identifiers (DIDs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jonnycrunch, @b5, @ianopolous would love your review on this RFC, I know that you have been thinking about Identity on the Decentralized Web a ton :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lanzafame just read up ipfs/notes#292, you should review this one too! :)
docs/rfc-identity.md
Outdated
The DID spec states that DID methods must provide a way for the owner to rotate keys, which solves `2`. The DID spec also states that DID methods must provide a way to recover the DID (e.g.: in case of theft), which solves `3`. | ||
|
||
Nevertheless, the [DID specification](https://w3c-ccg.github.io/did-spec/) advises DID methods to support adding delegate keys that can act on behalf of the identity, but with granular capabilities. As an example, the [erc725](https://github.com/ethereum/EIPs/issues/725) DID method has such feature via adding keys with the `action` type, allowing such keys to perform signing or authentication. | ||
delegate public keys will be listed in the DID-Document as well, which improves interoperability and compatibility with many other specs in the ecosystem, such as the [DID Auth](https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-spring2018/blob/master/draft-documents/did_auth_draft.md) and [Identity Hubs](https://github.com/decentralized-identity/hubs/blob/master/explainer.md). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to self: Fix capitalization
docs/rfc-identity.md
Outdated
|
||
To illustrate how [DID-Auth](https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-spring2018/blob/master/draft-documents/did_auth_draft.md) works, consider the following example: Alice wants to share a secret with Bob. | ||
|
||
After agreeing on a transport, Alice presents herself with a DID, a Device Public Key, and a set of self-signed Verifiable Claims. Alice does this by encrypting all this material, along with a nonce, with Bob's public key and signing her `authentication` key (a key present in the DID-Document under the `authentication` property). To trust Alice, Bob must: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
signing her -> signing with her
docs/rfc-identity.md
Outdated
3. Check if Alice's Device Public Key is listed in `authentication` property of the DID-Document | ||
4. Verify the message signature against her Device Public Key using the correct algorithm | ||
5. Verify the signatures of the self-signed Verifiable Claims against the public keys listed in the `publicKey` property of the DID-Document. | ||
6. Manually verify Alice's Verifiable Claims to see if they credible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If they credible -> if they are credible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi all, this is really great. Thanks so much for putting thought into identity, and I'm very excited with the direction this is going.
Apologies for the verbosity. I don't traditionally leave such long-winded reviews, but I wanted to get some ideas on the table, all of which you should feel free to ignore 🙂.
docs/rfc-identity.md
Outdated
- Uses DID best practices, such as using delegate keys to associate devices. | ||
- Doesn't require any extensions, scanning of QRCodes, or any other unfriendly processes for daily use. | ||
- Acts like a "server" in the sense that sensitive information may be safely stored in it. Many DID methods require a secret for certain actions, e.g.: uPort requires an app secret to request normal and verified credentials. | ||
- Has a wide support among devices. If we make it a PWA, users may install the application in the OS itself, further enhancing the user experience. Later on, we can develop native mobile apps to support OS's that don't yet allow PWA to be installed natively. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
plz de-acronymize "PWA". Thanks!
|
||
### Managing identities | ||
|
||
Users will be able to create identities using their preferred DID method or associate existing ones. They will be guided throughout the process according to the chosen DID method. Once they complete it, they will have successfully created a Device Key. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Associate existing keys" implies duplicate use of keys across services? It's worth considering the attack vector of app developers knowing both a secret and where to use it as part of the key association process.
If keys aren't moving / duplicating, then we lose the underlying assumption that the private keys live withing IdentityManager, which'll drive implementation complexity up a bunch if one intends to keep the experience for app developers smooth.
Some of this may be better covered in the verifiable claims spec, apologies if this is out of scope / covered elsewhere 😄. Seems like derivative keys are once again the answer, but worth calling out explicitly if so.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Associate existing keys" implies duplicate use of keys across services? It's worth considering the attack vector of app developers knowing both a secret and where to use it as part of the key association process.
Depending on the DID method, associate existing ones means one of:
- Create a new key (pair) and add it as the delegate. The DID method must support delegates, as explained here: DID Delegates & devices. This new key becomes the Device Key.
- In case the DID method does not support delegates, import the Master Private Key that controls the DID. In this scenario, the Master Key is the same as the Device Key.
1
is preferable but 2
is the only viable option for some DID methods. You may read more on https://w3c-ccg.github.io/did-spec/#authorization-and-delegation.
If keys aren't moving / duplicating, then we lose the underlying assumption that the private keys live withing IdentityManager, which'll drive implementation complexity up a bunch if one intends to keep the experience for app developers smooth.
Some of this may be better covered in the verifiable claims spec, apologies if this is out of scope / covered elsewhere 😄. Seems like derivative keys are once again the answer, but worth calling out explicitly if so.
The Device & Session private keys live within the IdentityManager and dApps must use the IdentityManagerClient to sign/decipher payload. I didn't understand why is this related with the verifiable claims, is it because of the signatures?
docs/rfc-identity.md
Outdated
|
||
Users will be able to create identities using their preferred DID method or associate existing ones. They will be guided throughout the process according to the chosen DID method. Once they complete it, they will have successfully created a Device Key. | ||
|
||
All the Device Private Keys will be encrypted with a passphrase to improve security. Even if a device gets stolen, the robber won't be able to use most features without the passphrase as all the information stored locally will be encrypted with the Device Public Key. This gives time for the owner of the Identity to revoke the compromised device in the IdentityManager of another device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not to stack too many interfaces on interfaces, but passphrases are coming under a bunch of scrutiny these days. It'd be great to have notes of what alternatives were considered in the footnotes on this doc, and why such an interface was omitted so that when the discussion of passphrases resurfaces someone can point to notes.
For example, it's too early for biometric authentication, but if such a standard were widely adopted today, how would this document react? Would this password be locked in a secure enclave, unlocked with biometric authentication, and used on the key which still lives in the IdentityManager, or is the relationship made explict with the master key in IdentityManager becoming a derivative key of a new key which is stored in a secure enclave? Seems like the async part is covered in the next paragraph.
This conversation does sound like a big time investment. Maybe this comment and a reply or two could serve as those notes 😄.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree, I will mention alternative methods that we could explore in the future.
Applications may want to sign artifacts, such as regular data or Ephemeral Keys. This will be possible in two different ways: | ||
|
||
1. Sign with the Session Private Key | ||
2. Sign with the Device Private Key |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could a third option be to issue a one-time-use key? I've used json web tokens in the past for such a purpose back when they were considered a good idea.
For this to work one would need to scope the capabilities of such a key, or place a reasonably-short TTL on the key.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will answer below as it is related.
|
||
The second method provides more security as the user is prompted for the Device Private Key passphrase, but it's more intrusive. The interaction is similar to the Authentication process, where a popup pointing to the sign screen gets open. The user either allows or denies the signing and the result gets back into the application. Please note that the passphrase might be stored in memory in the IdentityManager during a certain amount of time, which in turn makes this process less intrusive for subsequent signings. | ||
|
||
Ultimately, the application may choose between both methods for different situations depending on the security degree they want to have. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm secretly hoping for a parallel document for defining d.app capabilities, which in this context would be classified as an artifact, but intersect at the point of permissions.
This document seems to carry forward the assumption that I want to orient my experience of d.apps around the present model of sign-up-for-service-and-stay-signed-up. As a user I want to live in a world where if I stop using a service after a while, it's capacity to act on my behalf (sessions) is reduced without my intervention.
This will greatly frustrate app developers if presented directly, but a smooth-enough cross-app authentication interface coupled with a well-defined capabilities spec would make it possible for app developers to build upon each-other's features. Github & Continuous Integration feels like the prototype for this, where two app developers have a strong mutual interest to build on each-other's work because continuous integration is a big problem, and code management is a big problem.
I want to live in a world where authentication & capability definition is so well defined I don't have to build a chat feature into my app, instead I can just rely on some other app's implementation. For that to work we need uniform identity management & a common method for defining the capabilities of a d.app. The IPFS project is a bold step for common infrastructure that makes much of this conversation possible, if only a dream at this point 😉.
Amazon Temporary Security Credentials and it's STS service come to mind as non-oAuth prior art.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm secretly hoping for a parallel document for defining d.app capabilities, which in this context would be classified as an artifact, but intersect at the point of permissions.
Me, @joaosantos15 and @pgte were also working on a Authorization RFC that would be built on top of this document.
This document seems to carry forward the assumption that I want to orient my experience of d.apps around the present model of sign-up-for-service-and-stay-signed-up. As a user I want to live in a world where if I stop using a service after a while, it's capacity to act on my behalf (sessions) is reduced without my intervention.
That's right. As of now, the only way for the application to act on your behalf is to sign artifacts that are meaningful in the context of it, like creating a comment in a discussion and sign it. But because this all happens in the browser environment, if you just do not use the app, the app code won't be acting on your behalf without you noticing it. There's an exception, which is if an app tries to sign stuff within ServiceWorkers, but we can handle that gracefully by notifying the user if the app is doing it regularly in the background.
It seems that you are referring to situations where a person authorizes a application, similar to oAuth, and then the application may initiate actions on the person's behalf without the user being interacting with the app. This is out of the scope of this RFC for now. If you are indeed referring to this kind of situation, there's some overlapping with identity hubs's actions & permissions. We could study it and mention it in this RFC for such situations.
docs/rfc-identity.md
Outdated
2. Over exposes the private key: A Master Key should be used as few times as possible. Using it a lot makes it easier for an attacker to gain access to it. | ||
3. If the Master Key is compromised, the attacker is able to completely impersonate the real DID owner. | ||
|
||
The DID spec states that DID methods must provide a way for the owner to rotate keys, which solves `2`. The DID spec also states that DID methods must provide a way to recover the DID (e.g.: in case of theft), which solves `3`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
must provide a way to recover the DID (e.g.: in case of theft)
revocation is MUST, whereas recovery is optional, see here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct, thanks for pointing that out.
docs/rfc-identity.md
Outdated
|
||
To illustrate how [DID-Auth](https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-spring2018/blob/master/draft-documents/did_auth_draft.md) works, consider the following example: Alice wants to share a secret with Bob. | ||
|
||
After agreeing on a transport, Alice presents herself with a DID, a Device Public Key, and a set of self-signed Verifiable Claims. Alice does this by encrypting all this material, along with a nonce, with Bob's public key and signing with her `authentication` key (a key present in the DID-Document under the `authentication` property). To trust Alice, Bob must: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alice presents herself with a DID, a Device Public Key, and a set of self-signed Verifiable Claims
This sentence sounds like Alice has given herself a present containing a DID, device key and claims. I could be incorrect, but I am guessing the gist of it is that Alice presents herself as herself to Bob with these things.
Long way to say that the sentence could be made clearer, whichever way it is meant to be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed presents
to introduces
to avoid confusion.
docs/rfc-identity.md
Outdated
- Manage Verifiable Claims of identities | ||
- Authenticate to dApps (sessions) | ||
|
||
Because it runs on its own domain, it provides a sandboxed environment where access to functionality and data is completely controlled. More specifically, all interactions made with the IdentityManager it will be made via [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) where control and data segmentation is made via the messages' origin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is communicating with an IdentityManager from something other than a browser within scope of this document?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I've mentioned that briefly in the IdentityManager introduction:
- Has a wide support among devices. If we make it a Progressive Web App (PWA), users may install the application in the OS itself, further enhancing the user experience. Later on, we can develop native mobile apps to support OS's that don't yet allow PWAs to be installed natively.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't explored situations where the user wants to authenticate to a dApp, via another device. Were you mentioning that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was more referring to something you addressed above:
It seems that you are referring to situations where a person authorizes a application, similar to oAuth, and then the application may initiate actions on the person's behalf without the user being interacting with the app. This is out of the scope of this RFC for now.
That answers my question. 👍
docs/rfc-identity.md
Outdated
- Manage Verifiable Claims of identities | ||
- Authenticate to dApps (sessions) | ||
|
||
Because it runs on its own domain, it provides a sandboxed environment where access to functionality and data is completely controlled. More specifically, all interactions made with the IdentityManager it will be made via [`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) where control and data segmentation is made via the messages' origin. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interactions made with the IdentityManager it will be
^^
there is an extra it
in the sentence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
|
||
All the Device Private Keys will be locked to improve security. One such locking method is using a passphrase to encrypt the Device Private Key. Other methods, such as [biometric signatures](https://en.wikipedia.org/wiki/Electronic_signature#Biometric_signature), can be used instead if they prove to be effective and are available in the user's device. | ||
|
||
Even if a device gets stolen, the robber won't be able to use most features without unlocking the Device Private Key as all the information stored locally will be encrypted with the Device Public Key. This gives time for the owner of the Identity to revoke the compromised device in the IdentityManager of another device. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure how this would work: all of the private keys
are encrypted with the Device Public Key
. I think all of the key wrapping
will have to work via a symmetric PBKDF2 key as you are wrapping the private keys (needed to decrypt the private key material) with a public key. Won't one need the wrapped private keys to do the decryption?
(Luckily, mobile devices have the excellent UX of fingerprint and face-unlock that can extract the symmetric wrapping key from the device's secure enclave
, on desktop, this is less tidy. I hope I am not getting too deep into implementation here).
I'm very excited to hear all of your feedback!