Closed dlongley closed 4 years ago
There is a third option involving operating systems. Operating systems can provide interfaces to browsers for credential repositories, "digital wallets", encapsulating the signing (as per A). If the operating systems' digital wallet software is configured to use a remote service, a digital wallet service, the operating system can still perform the signing, not sending verifier origins to remote digital wallet services. What do you think?
@AdamSobieski,
There is a third option involving operating systems. Operating systems can provide interfaces to browsers for credential repositories, "digital wallets", encapsulating the signing (as per A). If the operating systems' digital wallet software is configured to use a remote service, a digital wallet service, the operating system can still perform the signing, not sending verifier origins to remote digital wallet services. What do you think?
Thanks for the suggestion!
The problem with having the signing portions in the browser is that it's in code that the community doesn't control. That means convincing other parties that the work is worth doing and maintaining. Therefore, moving the signing feature from the browser (code the community doesn't control) to the OS (code the community doesn't control) doesn't help mitigate the problem.
In fact, we already have to convince the browsers to do something -- and by moving portions of what they have to do into the OS we would now have to convince both browser manufacturers and OS manufacturers to do something. It's a step in the wrong direction, IMO.
Also -- I believe browsers have been moving away from models where they integrate with OS-level signing services because it's not clear how to properly express what's going on to users or how to provide appropriate security. It's likely an even heavier lift to get operating systems to do anything narrowly focused on credentials. Even if they did, it would potentially create digital wallet monopolies.
If we weren't able to convince both parties (OS and browsers) to do something, then we're left with the user having to install something. This API is for the Web, so we're trying to avoid that entirely. Users don't like installing things or maintaining them -- and this would be a huge barrier to adoption.
Lastly, the model where the OS provides the signing mechanism but then calls out to a digital wallet service will still require a way for that service to provide a UI. The most extensible way to do all that is through a Web browser. As stated above, this requires both OS and browser implementation -- but it's clear that it can be mapped to a simpler version where only the browser is involved. However, that means it's just a restatement of option B.
For these reasons, I don't consider more strongly tying the API to the operating system and/or a browser plugin to interface with it to be a feasible third option.
Excellent points. In my opinion, option B makes sense, in particular given WebCrypto. Other scenarios exist where digital signatures in the Web browser make sense include Web-based email and other messaging apps — digitally signing messages and content.
In addition to the problems solved by the new API's, we can collect together how both users and Web developers can be convenienced to indicate to browser teams the importance of implementation. For instance, one JavaScript example or library could show an integration of Credential Handler API with HTML forms, showing data entry processes smoother, more streamlined and more secure than autofill / autocomplete (in particular on mobile touchscreen devices).
@AdamSobieski,
Excellent points. In my opinion, option B makes sense, in particular given WebCrypto. Other scenarios exist where digital signatures in the Web browser make sense include Web-based email and other messaging apps — digitally signing messages and content.
To be clear, when I say "in the browser" in this context, I mean in native C++ browser code, not in Web application JavaScript. So, "in the browser" would be option B and a client-side JavaScript-based solution like WebCrypto (or alternatively, any server side code) would be option A.
In addition to the problems solved by the new API's, we can collect together how both users and Web developers can be convenienced to indicate to browser teams the importance of implementation. For instance, one JavaScript example or library could show an integration of Credential Handler API with HTML forms, showing data entry processes smoother, more streamlined and more secure than autofill / autocomplete (in particular on mobile touchscreen devices).
While we always welcome more demos (some of these have already been created and shown in the past), several browser vendors have already indicated to us that the most compelling evidence for their need to implement is a combination of incubation and large user base. This is why a polyfill is so important; we can get this out early to those people who need it and build up its use in the ecosystem.
I'm in the midst of reading some Web cryptography specifications [1][2][3][4] for purposes including, but not limited to, understanding the feasibility of digital signatures for Web-based email and messaging apps. Such technologies can secure communications and can be of use to differentiating spam from ham and, thus, can be of use to curtailing spam (see also: https://en.wikipedia.org/wiki/S/MIME).
I'm wondering about potential differences between native and Web-based applications with regard to accessing users' keys. I'm wondering about interoperations between Web applications and browser or operating system components (such as keyrings, keystores or certificate stores).
I'm for option B:
If we choose B, then:
Users do not have to reveal the verifier origin to their credential repository. However, browsers must implement signatures. It will likely be an uphill battle to convince browser implementers to do this if we even can. We can have the polyfill do it, but I think we may be creating a permanent polyfill.
Users may keep their private keys in their browsers on their local devices which they can authorize to sign on their behalf based on decisions that arise from activities can actually understand (e.g. "Do you want to share these credentials with site X?").
I'm also for granular permissions: does a user want to share their real name, their address, their date of birth, that they're over 21, their citizenship, etc.
[1] https://www.w3.org/TR/WebCryptoAPI/ [2] https://www.w3.org/2012/webcrypto/webcrypto-next-workshop/papers/Using_the_W3C_WebCrypto_API_for_Document_Signing.html [3] https://www.w3.org/TR/webcrypto-key-discovery/ [4] https://w3c.github.io/webauthn/
@AdamSobieski,
I'm wondering about potential differences between native and Web-based applications with regard to accessing users' keys.
The WebCrypto API has no access to any OS-level keystores/certificates/etc. In order for a website to use keys/certificates/etc from OS-level stores with the WebCrypto API, they must first be exported to a format that can be parsed by the WebCrypto API or another JavaScript library. Sites that use the WebCrypto API should be thought of as having full control over the user's keys (they must have direct access to the private key material to make calls to the WebCrypto API).
Using the WebCrypto API on the credential repository's website is a way of implementing option A, not option B.
A polyfill that runs on a separate origin (e.g. a community run website for polyfill purposes only) can use the WebCrypto API to sign VerifiableProfiles -- this is option B -- that it receives from the credential repository origin. Here the polyfill is handling a responsibility that the browser is not (yet) able to perform. Note, however, that this is potentially less secure than the browser doing this natively, as a one time hack of the polyfill website can result in the theft of every users' keys that subsequently download the hacked Web app from the polyfill website.
I'm also for granular permissions: does a user want to share their real name, their address, their date of birth, that they're over 21, their citizenship, etc.
This is a separate issue. It's important, but strays off topic here.
I'm also for granular permissions: does a user want to share their real name, their address, their date of birth, that they're over 21, their citizenship, etc.
This is a separate issue. It's important, but strays off topic here.
Yes, we can open a new issue on that. I opened: #3.
So proponents of option B might desire to create a Digital Signatures API or Native Crypto API which specifies an API for Web applications to access, with users' permissions, browser or operating system keystores/certificates/etc.
So proponents of option B might desire to create a Digital Signatures API or Native Crypto API which specifies an API for Web applications to access, with users' permissions, browser or operating system keystores/certificates/etc.
Yes, and, to my knowledge, this approach has been dead in the water for quite some time. Browser vendors do not believe that the user can make informed decisions with such a generic API -- and such an API would be far too powerful/dangerous if they cannot.
We can design the API and specify for contingencies, such as the browser being able to, at some point, digitally sign. We can design and specify such that the initial credential repositories will be able to digitally sign, and, at some point, browsers may and credential repositories, including remote digital wallet service providers, need not.
Credential repositories may, but need not be able to, digitally sign and they indicate through the API whether they can. Credential repositories can operate without digitally signing if they are capable of digitally signing; that is, credential repositories which can digitally sign can be invoked so as not to, if the browser can and intends to.
If a credential repository cannot digitally sign, then the browser must for the functionality. If the browser ever can, then credential repositories need not.
Not to complicate this more, but can it be designed for both, with a minimum viable implementation (likely of A) for now?
I can see scenarios for both A and B. (And within A, addressing issue 1 with something along the lines of C sounds promising.)
For guardian-managed DIDs, A sounds inevitable. However, requiring credential repository signatures is a high bar for architecturally simple methods (BTCR specifically).
For B, I can envision a fairly nice user experience through, for example, uPort mobile app signatures. I think Harlan Wood's work.nation has a good example of this.
@AdamSobieski,
We can design the API and specify for contingencies, such as the browser being able to, at some point, digitally sign. We can design and specify such that the initial credential repositories will be able to digitally sign, and, at some point, browsers may and credential repositories, including remote digital wallet service providers, need not.
I agree -- and I think that's what approach A would mean. We'd start with A with the potential for B to happen at some point in the future, but we wouldn't count on it happening. We wouldn't implement it in the polyfill.
Credential repositories may, but need not be able to, digitally sign and they indicate through the API whether they can. Credential repositories can operate without digitally signing if they are capable of digitally signing; that is, credential repositories which can digitally sign can be invoked so as not to, if the browser can and intends to.
If a credential repository cannot digitally sign, then the browser must for the functionality. If the browser ever can, then credential repositories need not.
This is significantly harder to pull off, IMO. You can't really get the ecosystem bootstrapped if you have credential repositories that can't provide this functionality when there are browsers (and no polyfill) out there to assist. We could further complicate the polyfill so that it can provide this functionality if the credential repository does not, but I think that's just going to confuse developers ... and they'll end up not providing the functionality without an incentive to do it, leading, potentially, to greater difficulty in adoption given the security and usability drawbacks of having the polyfill do it. Maybe those drawbacks are enough incentive to encourage repositories to take up the mantle, but I'd rather just tell them they have to.
^^ This answered one of my questions. I need to re-read and absorb this thread more completely.
@kimdhamilton,
Not to complicate this more, but can it be designed for both, with a minimum viable implementation (likely of A) for now?
Yeah -- I think perhaps a better way of putting it is that it can be layered. We can implement for A now (and potentially include elements of C for increased privacy) and if browsers elect to implement in the future, this can be one of the reasons why they do -- to further increase privacy.
For guardian-managed DIDs, A sounds inevitable.
Maybe! I'm still not clear on exactly what "guardian-managed" means, but that's for another issue :). I fully expect most people to delegate the ability to authenticate as the entity a DID identifies entirely to their digital wallet. Depending on how authentication proofs are implemented, that probably means it's most convenient to let your repository manage your keys and perform the signing for you anyway -- given that delegation. That just means getting something like C in there to provide the privacy is the last piece.
However, requiring credential repository signatures is a high bar for architecturally simple methods (BTCR specifically).
I'd like to hear more about this.
For B, I can envision a fairly nice user experience through, for example, uPort mobile app signatures. I think Harlan Wood's work.nation has a good example of this.
B is how the original credentials polyfill was implemented as demonstrated here:
Besides my security concerns of this approach -- one major usability downside is that clearing your browser cache flushes your private keys too :). This means getting your digital wallet provider to issue you you new keys -- and update your DDO with them. Again ... demonstrating just how much power you need to grant to your digital wallet to make the system usable for typical internet users.
My favoured approach is to have the repository local to the client, so that the private keys are held within the user's key store on his/her machine. This is a flavour of option A, but is not A as originally described. If the repository is remote from the user, and held by another third party, then the user could login to the remote repository and then sign the profile. There are examples of this type of remote key store in PKI. WRT B, then if we use the W3C proposed standard, Web Authentication: An API for accessing Public Key Credentials Level (https://www.w3.org/TR/webauthn/) this will allow the browser to access the key store and ask for the profile to be signed. There wont be any browser opposition to this polyfill API, so I support the use of this
We will need to further investigate webauthn's constraints on signature formats, algorithms, and same origin usage:
I retract my earlier concern regarding BTCR impact; this was based on an earlier confusion/conflation between the boundaries of DIDs and claims/credentials.
The Credential Handler party is responsible for signing Verifiable Presentations. Closing.
The Credential Handler API should define how a verifier can request credentials and how a credential handler can register with a user agent (browser) to receive credential requests from verifiers. When credentials are transmitted to the verifier, they are enveloped in a Verifiable Profile. This Verifiable Profile should include a proof of possession (e.g. a digital signature) allowing the user to authenticate as that profile.
We can implement the API such that either:
A. Credential repositories are responsible for signing the Verifiable Profiles that are transmitted to verifiers.
B. Browsers are responsible for signing the Verifiable Profiles that are transmitted to verifiers.
If we choose A, there are two main drawbacks:
The origin of the verifier will always be leaked to the credential repository. This is because the counter signature on a Verifiable Profile includes the target origin (or "domain") that the Verifiable Profile is intended for.
The credential repository must be able to use the user's private key to create the signature. This means that the credential repository either has direct access to the key material or is authorized to use a software/hardware security module/signing service on behalf of the user as they see fit (which will hopefully be according to a policy the user agrees to). Note that an alternative idea where the user must approve specific signature requests is a no-go because nearly all users cannot make an informed decision. Advanced users still get a spectrum of control over their own keys: from full control by running their own credential repository to full delegation to a third party credential repository.
Note: For DID-based identity, I currently expect nearly all users to delegate control of most of their DIDs to a credential repository/digital wallet service because of the overwhelming benefit of convenience. If this is the case, there may be little reason to try and avoid problem 2, and we instead only need to work out the details.
If we choose B, then:
Users do not have to reveal the verifier origin to their credential repository. However, browsers must implement signatures. It will likely be an uphill battle to convince browser implementers to do this if we even can. We can have the polyfill do it, but I think we may be creating a permanent polyfill.
Users may keep their private keys in their browsers on their local devices which they can authorize to sign on their behalf based on decisions that arise from activities can actually understand (e.g. "Do you want to share these credentials with site X?").
There may be some C option that is better. I've got some half baked ideas involving blind signatures or salts and hashes, but they add more complexity.
Should we do A, B, or C?
Specifically, how does the group feel about this information being leaked? Will users usually want to share it anyway to get better features from their credential repository? If we think we can't get the browser implementers to implement signing, would we be ok with proceeding with option A? Is there a third way? Is the third way worth the complexity (presuming it is complex).
Regarding C: One of my "half baked" ideas is for the browser, instead of signing the Verifiable Profile, to generate a salt and hash the origin of the verifier. Then pass this hash to the credential repository to be included as a "saltedDomain" in the signature. The salt would have to be kept secret (from the credential repository) so as to prevent brute force guessing of common domains. The credential repository would perform the signature and then hand the Verifiable Profile over to the browser which would add the salt into the signature meta data, as an unsigned field, before passing it on to the verifier. This approach would avoid issue number 1 with option B, but not issue number 2. It would also mean more complexity in signing methods and specs, in the form of an "unsigned primitive" in the signature meta data -- which would have security implications if abused.