Currently, the authentication flow (1) uses the application origin to derive the application private key, and (2) requires that the manifest URI matches the application's origin. The rationale of point (2) is that the application proves to the authenticator that it owns the origin, so the right application key will be derived -- a rogue client cannot derive the private key for another application. However, this treatment of the origin and manifest.json creates a few issues:
This makes it hard to switch the application's URL, since the origin is used to derive the key.
It leaves applications and users vulnerable to DNS hijacking.
This makes it hard to build locally-hosted apps and apps that run inside Web extensions in conjunction with the hosted browser, since the application may not even have an HTTP endpoint (let alone one that is available via HTTPS).
Instead, I propose the following "version 2" of authentication flow that will allow us to use BNS to authenticate applications. The high-level idea is that the manifest.json would be the BNS name's profile, and that the BNS name (not the origin) would be the way by which we identify applications -- including for the purposes of generating application private keys. The developer could change the application's origin by updating the BNS profile, but users would receive a warning from the authenticator when this happens.
The protocol overview is as follows:
Have the developer register a BNS name for the publishing the application. The BNS name is used to cryptographically identify the application. There would be one BNS name per application, and would be used to derive the application private key.
Have the developer structure the manifest.json as a JWT, signed by the BNS private key. Add the following data to the manifest.json:
Have the developer include the following fields in the authentication request:
Have the authenticator take the following extra steps on sign-in if this scheme is used:
Have the authenticator take the following steps to generate the app private key:
bns://-prefixed origin into the user's profile for this app, so the authenticator knows in the future to use the BNS name to generate the app private key. Include the app's (DNS) origin in the entry, and in future sign-ins, alert the user if the app origin fetched via BNS does not match the auth request (indicates the app origin changed).The "wins" this scheme gets us are:
What do you think? @larrysalibra @zone117x @yknl @hstove
@jcnelson Maybe post this in the forum when you want feedback from App developers.
This proposal makes sense to me. In order to be backwards compatible with the current version of blockstack.js, the apps key would have to be unchanged, since its currently an array of strings.
I would add that in implementing this, we should extend the key derivation path to use the full hash160 of the app name.
Also, note that we won't be able to detect and apply backwards-compatibility fixes for single-player applications without some additional measures.
This proposal makes sense to me. In order to be backwards compatible with the current version of blockstack.js, the apps key would have to be unchanged, since its currently an array of strings.
Sounds reasonable. In implementing this, I'd take the opportunity to define an appsData map that links versioned information to application names, where the "version" refers to the version of the authentication protocol. I think adopting a schema like this would help us get into the habit of designing for backwards compatibility for when we modify the authentication protocol in the future. Example:
"appsData": {
"v1": {
/* version 1 stuff goes here */
},
"v2": {
/* version 2 stuff goes here */
},
}
I would add that in implementing this, we should extend the key derivation path to use the full hash160 of the app name.
Agreed 100%.
Also, note that we won't be able to detect and apply backwards-compatibility fixes for single-player applications without some additional measures.
I think this could be addressed with a flag in the manifest.json. If the app developer is using this protocol or a future protocol, then the manifest.json would need to indicate an explicit version of the authentication protocol to use. If it doesn't, then we assume that the app wants the authenticator to do what we do today.
I think this is great, it will be one step closer to replacing DNS completely with BNS.
The minimum age of the manifest.json
What is the reason for having a minimum age for the manifest.json?
Also should we register a name space for apps?
What is the reason for having a minimum age for the manifest.json?
The manifest.json now identifies mutable information, including the application's origin. If the app developer updates their manifest.json, it's possible that a client will see a stale version. Having the app developer pass in the expected creation-date of the manifest.json to the authenticator ensures that the authenticator detects a stale manifest.json. The app developer would deploy an updated version of the app with the newer timestamp whenever the manifest.json contents changed.
An alternative (possibly stronger) mechanism would be for the app developer to pass the _cryptographic hash_ of the manifest.json in the auth request. It would achieve the same ends -- if the developer changes the manifest.json, they also need to change the app's signin handler to ensure that users don't accidentally fetch and process a stale manifest.json.
Also should we register a name space for apps?
We can do this, but any BNS name will work. However, I would be open to further refining this spec to require the BNS name to _not_ have an expiration date -- i.e. you couldn't use a .id name to register an app, but you could use a .blockstack name. You could use also use a subdomain.
An alternative (possibly stronger) mechanism would be for the app developer to pass the cryptographic hash of the manifest.json in the auth request.
I thought about something similar -- just having the app pass the manifest.json contents themselves during the auth request -- but I think that it would require a kind of strange build pattern and might be a pretty frequent stumbling block for developers. It seems easier to have the auth request pass a "manifestNewerThan" with a timestamp. So by default, the blockstack app generator would just initialize that with the current date, and things would mostly work out until the developer wanted to force a revocation, in which case, they'd just need to update one field.
We can do this, but any BNS name will work. However, I would be open to further refining this spec to require the BNS name to not have an expiration date -- i.e. you couldn't use a .id name to register an app, but you could use a .blockstack name. You could use also use a subdomain.
That's interesting. Maybe in V1 of this scheme, we require a non-expiring name. Otherwise, I think we'd want to detect and prevent the case where a name expires, is renewed, and the app key can be taken by the new owner, which for V1 would probably complicate the auth flow too much.
just having the app pass the manifest.json contents themselves during the auth request
This would be risky -- the resulting auth-request URL might be too long for some browsers.
So by default, the blockstack app generator would just initialize that with the current date, and things would mostly work out until the developer wanted to force a revocation, in which case, they'd just need to update one field.
The fact that the app generator would need to be involved in this process makes me like the idea of passing a timestamp a lot more than passing a cryptographic hash.
That's interesting. Maybe in V1 of this scheme, we require a non-expiring name. Otherwise, I think we'd want to detect and prevent the case where a name expires, is renewed, and the app key can be taken by the new owner, which for V1 would probably complicate the auth flow too much.
Yeah, the more I think about how to handle renews and re-registers, the less I like the idea of dealing with expiring app names. I don't think making app names expire and have to be renewed is justified, since there are way more BNS names available than DNS names, when counting all the namespaces that could be created (and subdomain registrars and namespace creators can prevent squatters from consuming all the "good" names). I'm in favor of disallowing expiring names for apps.
EDIT: accidentally closed
The proposed extensions to the manifest.json are not conform to the W3C standard. It is recommended to prefix new properties with a vendor prefix.
This is a great proposal @jcnelson
I'm interested in being able to sign in to apps without having to make additional network requests to servers controlled by the developer. (ie. the manifest.json file)
Can we put application origin info in the Atlas zone file instead of an external file like profile.json or manifest.json?
Removing the need for manifest.json files would give us some benefits:
* Privacy: users no longer have to make requests to an app developer controlled server to sign in. This opens up the ability to make apps that after you download them the first time can be cached and don't need to make requests back to the developer's servers.
* No more CORS headaches: developers no longer have to spend time figuring out how to set proper CORS headers in both their developer and production environments so that manifest.json works
2 questions, users Gaia data are signed with app origin? if so, how we can access and migrate after we switch over BNS included manifest files?
Can we put application origin info in the Atlas zone file instead of an external file like profile.json or manifest.json?
Definitely! If the application includes its Origin information and manifest.json information in the Atlas zone file, it should be used instead of anything learned through a network request.
@jcnelson Sounds like manifest.json info in Atlas is the way to go? If so should we update the proposal?
Also, what is the priority for this? (And estimated time you think it might take?)
Also, what is the priority for this? (And estimated time you think it might take?)
Same question!
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed. Please reopen if needed.
Most helpful comment
Same question!