You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Provide request deserialization, response serialization #1683
The addition of ArrayBuffer in the WebAuthn APIs has been an often-cited challenge for relying party developers, as JavaScript does not have integration for converting such buffers to text for serialization via JSON. JSON itself is not necessarily the best format because of the binary content, including for items like extensions.
I'd like to propose deserialization request forms of PublicKeyCredential as long as serialization of the response forms of PublicKeyCredential.
To do this, I would propose a serialization based on a schema (such as CBOR and CDDL) covering the options valid for a PublicKeyCredential. CBOR data is preferred because of the need to preserve the binary signed messages, and due to several internal values being declared as binary identifiers or as CBOR.
Additionally, convenience methods to work in terms of a base64-encoded form of the CBOR data would be desirable for use in text-based API.
As deserialization would result in a PublicKeyCredential object, Javascript would still have full fidelity to inspect and possibly manipulate before making a create() or get() request. Likewise, Javascript would have the ability to inspect the response object before serializing it to share with a remote service.
Deserialization for responses and serialization of requests would both be more difficult due to the possibility of arbitrary manipulation by the user and responses having methods in addition to data.
Thank you for submitting this ticket, I had intended to file something similar ages ago but never managed to make time for it. In my mind I totally think PublicKeyCredential needs to be expanded in this direction.
I encourage us to think about how devs work with native JS capabilities and build the spec for them, not build the spec for us and hope JS devs will follow. To get some of my own thoughts out about this:
I think making it easier for developers to consume WebAuthn API via JSON inputs and outputs would go a long way in encouraging adoption without forcing developers to A) figure out WebAuthn serialization for themselves, or B) incorporate another dependency like Github's webauthn-json or my @simplewebauthn/browser.
I'd argue JSON over CBOR as the former is the lowest-common denominator data schema, especially in the world of advanced JavaScript projects like Single-Page Applications. JSON can be natively worked with without needing to incorporate any dependencies, and without having numbers handy I'd say almost all front end JS projects make JSON-based REST or GraphQL API calls. This means most JS devs are comfortable thinking about data structures purely as JSON, and have no idea what CBOR-encoding is nor would see the benefits in it when JSON has "worked so well" for them. Not to mention CBOR encoding/decoding would require their own dependencies, so you'd be trading one kind of dependency for another; definitely "one step forward, one step back".
Whatever direction an effort like this takes, I think the end goal should be to make WebAuthn easier for developers to consume, especially in the browser side of things. If we can accomplish that then adoption will follow. Right now WebAuthn is a PITA to implement in large part because ArrayBuffer's just aren't common in front end JS development. Not to mention there's a lack of native methods to convert to/from Base64URL in the browser which further complicates things when the spec seemingly assumes such "standard library" APIs are available (😂/😭) I think we can tackle this with a smart addition to PublicKeyCredential so long as we keep an eye on how we can make WebAuthn more practical to consume.
I think making it easier for developers to consume WebAuthn API via JSON inputs and outputs would go a long way in encouraging adoption without forcing developers to A) figure out WebAuthn serialization for themselves, or B) incorporate another dependency like Github's webauthn-json or my @simplewebauthn/browser.
I'd argue JSON over CBOR as the former is the lowest-common denominator data schema, especially in the world of advanced JavaScript projects like Single-Page Applications. JSON can be natively worked with without needing to incorporate any dependencies, and without having numbers handy I'd say almost all front end JS projects make JSON-based REST or GraphQL API calls. This means most JS devs are comfortable thinking about data structures purely as JSON, and have no idea what CBOR-encoding is nor would see the benefits in it when JSON has "worked so well" for them. Not to mention CBOR encoding/decoding would require their own dependencies, so you'd be trading one kind of dependency for another; definitely "one step forward, one step back".
We have a lot of values which would be named base64url property values at that point, e.g.
numerous identifiers
the challenge
the client JSON (since it has to be byte-for-byte preserved)
the actual signed data
all extension requests and responses (which you are pretty much guaranteed to need to handle due to some clients injecting Credential Properties)
My reasoning for CBOR over JSON:
Because JSON cannot differentiate text from base64url-encoded binary, the selection of JSON would require a semantic knowledge of the message (including future additions) in order to process. This increases the maintenance of such serialization and deserialization.
The selection of JSON may also push for duplication of non-encoded forms, for example including what today is getPublicKey() as a duplicated JWK within the serialized JSON response. This particular example duplication of security information and increases the risk of an implementation accidentally relying on data which is not integrity protected.
I don't feel additional forms of data are necessary. For browser Javascript, we do not need a JSON form to introspect because we have the actual WebAuthn API. For things which a browser needs to understand, we should still focus on raising that information through the API, rather than through serialized forms.
For the relying party infrastructure processing the data however, we necessitate binary processing already by the nature of the protocols being written in terms of U2F-legacy binary and CBOR binary messages. Semantic transformation to other forms breaks integrity. Base64 encoding binary data does not make the relying party job easier.
Whatever direction an effort like this takes, I think the end goal should be to make WebAuthn easier for developers to consume, especially in the browser side of things. If we can accomplish that then adoption will follow. Right now WebAuthn is a PITA to implement in large part because ArrayBuffer's just aren't common in front end JS development. Not to mention there's a lack of native methods to convert to/from Base64URL in the browser which further complicates things when the spec seemingly assumes such "standard library" APIs are available (😂/😭) I think we can tackle this with a smart addition to PublicKeyCredential so long as we keep an eye on how we can make WebAuthn more practical to consume.
Agreed. While a serialized form does not create any mandate, one could see how what is client javascript libraries today might get pared down to either send the serialized form in request/responses directly, or composed within additional API messages which provide something like an authentication workflow.
I'll take this on. I'll try and get a draft PR up before too long, I know it'll need a lot of TLC but I think it'd be a worthwhile addition to the spec.
CDDL normally has a single output data item, so there may be multiple descriptions needed if we define specific request/responses for create and get. I'm hardly a CDDL expert, though.
I'll take this on. I'll try and get a draft PR up before too long, I know it'll need a lot of TLC but I think it'd be a worthwhile addition to the spec.
The WebIDL spec already allows for interfaces to provide a toJSON() method. So I could see us here doing something like adding a toJSON() operation to the AuthenticatorAttestationResponse and AuthenticatorAssertionResponse interfaces. Those methods would return a JSON object for the attribute members of those interfaces, with ArrayBuffer valued attributes converted to base64url encoded strings.
WebIDL doesn't have similar "fromJSON" provisions AFAIK. But if we wanted to allow instantiation of PublicKeyCredentialCreation/RequestOptions from a server-supplied JSON object, we could e.g. define PublicKeyCredential.publicKeyCredentialCreation{Creation,Request}OptionsFromJson(), with basically the inverse conversion rules of toJSON(). I.e., callers pass a JSON object with the respective members, and the method returns an equivalent dictionary with ArrayBuffer-valued attribute values parsed from their base64url encoding.
While toJSON() in WebIDL may be convention, I don't believe we could use the default implementation without changes to WebIDL or ECMAScript.
In particular, the ask has been for this value to be Base64 (or I presume Base64URL) encoded, but such an encoding would need to be defined upstream by one of these two specifications for us to leverage a Default toJSON() implementation from WebIDL.
We would probably want guidance from WebIDL that our declaration of a fromJSON() would not conflict with WebIDL in the future.
This would decrease the duplication of description languages, although WebIDL would expect us to define the dictionary formats of the current interface types.
Either way (WebIDL or CDDL), we have to resolve issue that CredentialCreationOptions/CredentialRequestOptions can not host static methods like fromJSON() - they are dictionaries, not interfaces.
While toJSON() in WebIDL may be convention, I don't believe we could use the default implementation without changes to WebIDL or ECMAScript.
In particular, the ask has been for this value to be Base64 (or I presume Base64URL) encoded, but such an encoding would need to be defined upstream by one of these two specifications for us to leverage a Default toJSON() implementation from WebIDL.
I don't think there's a requirement that if you define a toJSON operation, it has to use the default operation. For example: https://w3c.github.io/push-api/#dom-pushsubscription-tojson. We would define our own implementation without upstream changes.
We would probably want guidance from WebIDL that our declaration of a fromJSON() would not conflict with WebIDL in the future.
This would decrease the duplication of description languages, although WebIDL would expect us to define the dictionary formats of the current interface types.
Either way (WebIDL or CDDL), we have to resolve issue that CredentialCreationOptions/CredentialRequestOptions can not host static methods like fromJSON() - they are dictionaries, not interfaces.
My suggestion is to hang them off of PublicKeyCredential, the same way we do with isUserVerifyingPlatformAuthenticatorAvailable(). That way they also won't be generic fromJSON(), but rather publicKeyCredentialCreationCreationOptionsFromJSON() for example, so there is little risk of them conflicting with anything Web IDL might do in the future IMHO.
As I'm reading this, you are expressing an opinion that WASM is a "demo" or a "toy" language, and not something you need to seriously consider in the surface area of webauthn and how it interacts with a browser.
I'm sorry if my message was interpreted that way. I'm trying to verify any requirements you may have.
If it helps, WASM instructions or Javascript code consuming authentication assertions within the browser has limited utility. You are making an authentication assertion into a locally held and easily user introspectable box. Whether you are protecting e.g. an IndexedDB database by a locally prompted password or WebAuthn, the data is still a local database, exposed one pane over via developer tools.
Remote infrastructure, whether running on top of WASM or a virtual or native machine architecture would be normally where you would produce challenges and verify the assertion. The choice of execution architecture here should not have an impact over say, the choice of programming language.
There have been proposals to add e.g. a way to unlock a symmetric key with WebAuthn, which changes this equation significantly - but I'd argue serializing this symmetric key (or making it exportable in general) is probably a bad idea.
I think you are over thinking this. Just imagine that instead of JS, replace it with WASM. The architecture is still:
Server -- http --> browser -> JS/WASM -> navigator.credentials
Just replace the dynamic JS parts with WASM, and you get what what I'm asking.
I am extremely confused by what you are asking here, because I think you are confused about what I'm requesting.
To ask tersely - you asked for considerations. I asked for what those considerations would be.
Okay, to be explicit.
Today, when you perform a browser fetch request to a webauthn endpoint of a server, you receive a JSON response. Deserialising that JSON into the WASM or JS context, it is not possible to create a Uint8Array. As a result, the structure has an array of bytes, but in a different format.
This means that any RP today MUST create dynamic components that MUST execute in the browser, that MUST alter the content of any structure which is intended to be passed into navigator.credentials apis. This is commonly achieved by base64url encoding and decoding the fields.
So there a number of potential ways to tackle this:
Provide a "common" javascript blob/file that can be consumed that does the base64 decode/encode as required.
Convince browsers to implement a platform api which allows a JS/WASM object that does the decode/encode as required.
Linking and binding to an external piece of javascript, which likely exists in the npm ecosystem may not be easy. In fact, just providing this common js blob does not even need the webauthn group involved, you could setup a project on github today to do this.
and 3. both require webauthn to step in and convince browsers to extend their navigator.credentials apis, and these apis can already be consumed from JS and WASM equally through platform bindings.
Both of which would be "breaking" changes to what a browser provides, and are desperately needed both so that RP's no longer need JS/WASM to mangle incoming requests so that nav.cred can understand it, but also because a large number of parameters in Webauthn an unsigned which opens the door to a number of potential security issues which extensions poorly defend from.
There are five buckets of information, somewhat blended together
The unprotected request from the relying party
Client collected data, such as the origin requesting WebAuthn, and client-specified authenticator extensions like CredProtect
The response to the unprotected request by the authenticator, signed by the previously negotiated public credential (on get) or potentially signed by attestation (on create), containing some of the information from 1 & 2.
Non-integrity-protected client information on the response. This includes getTransport() and getClientExtensionResults()
Helper information and Helper API for extracting some information returned from 3 in a non-integrity-protected manner. This includes the credential [[identifier]], getAttestationObject(), and getPublicKey().
These pieces represent multiple actors and multiple sets of security considerations/attacker models. That is why I hope the helper information (like getPublicKey and getAuthenticatorData) are not serialized as part of responses, as correct validation becomes that much harder if someone does part of their processing on e.g. the non-integrity-verified copy authenticator data. I'd much rather tooling like Webauthn-RS generate their own Helper API as appropriate from the serialized responses.
I think this section of the comment doesn't apply to the JS/WASM discussion, but I have discussed before about this issue within this group as this has led to CVE's in the past. If this change was to be accepted in a manner where browsers would need to alter their platform apis for navigator.credential, then it would be viable to actually potentially correct this long standing defect in the webauthn specification such that the entire chain of communication is verified rather than small elements.
WASM is really neither here nor there, I suggest we constrain future discussion to JS because the question of how you invoke JS global APIs from WASM will never be the purview of this working group.
Reacted by Tim Cappalli, Nick Steele, Paulo Lopes and Arnaud Dagnelies
If you make a toJSON(), it would aleviate several of the current pain points to use this API and a great step forward. 👍
Actually, it is a mystery to me why the API currently returns "things" that cannot even be sent to the server directly, but require "post-processing" to do so.
And if you provide such a toJSON() method, please decode the whole since it is currently "doubly encoded" to avoid CBOR completely. So that you directly see the content of the attestation objects, have direct access to the public key, signatures and so on ....and not simply a base64 CBOR buffer, which besides of being obfuscated, tranfers the burden of CBOR decoding to the server.
So basically, what was initially suggested in the post there #1362 😁
Actually, it is a mystery to me why the API currently returns "things" that cannot even be sent to the server directly, but require "post-processing" to do so.
From #1362: " On the call of 2020-01-22 it was decided that the use of ArrayBuffers is reflecting W3C direction as we understand it and that revisiting that would be too much. [...]"
And if you provide such a toJSON() method, please decode the whole since it is currently "doubly encoded" to get rid of CBOR completely. So that you directly see the content of the attestation objects, have direct access to the public key, signatures and so on [...]
Getting rid of CBOR is not feasible. The security messages themselves are signed binary in a mix of U2F-inherited format and CBOR extensions/attestations.
Any translated version of the contents would no longer be integrity protected, and integrity protection is paramount to the server understanding authentication is being performed correctly. Any non-binary, non-CBOR form would be generated by the server after validating the binary responses had proper integrity and were correct answers to the challenges created by the server.
The getPublicKey() method, added in level 2, is meant to provide the public key on creation with the specified limitations. This includes not requesting attestation on registration, as you will need the non-modified binary message in order to verify said attestation.
On the client side, you have to transform it in proper JSON to even send it to the server.
And in order to get get the public key, you have to decode the CBOR stuff inside.
So, from the perspective of a web developer, I don't understand why being directly decoded would be a problem.
Any non-binary, non-CBOR form would be generated by the server after validating the binary responses had proper integrity and were correct answers to the challenges created by the server.
I haven't gone through the validation/verification part. Please take into consideration that an average developer has no idea about U2F and CBOR. What "we" are familiar with is to have a public key in order to verify a signature of some data. Almost always, these are just base64url encoded values sent around. So, in this spec, it feels highly unusual and strange that this unknown CBOR protocol plays such a crucial role ....actually, even after digging into the specs, I still don't know why the original CBOR encoded form would matter ...however with the spec being 165 pages long, it's of course extremely challenging to assimilate, so I probably missed the important part.
If you want to make something really great, then make a toJWT() method, to obtain a signed Json Web Token 🎉 😁 ...that would be super easy to transmit over the wire, is familiar to every web developer and verification would be a breeze since it is a well known web standard with a mature ecosystem. In short, it would be great!
On the client side, you have to transform it in proper JSON to even send it to the server.
And in order to get get the public key, you have to decode the CBOR stuff inside.
So, from the perspective of a web developer, I don't understand why being directly decoded would be a problem.
Right, but the original statement:
So that you directly see the content of the attestation objects, have direct access to the public key, signatures and so on ....and not simply a base64 CBOR buffer, which besides of being obfuscated, tranfers the burden of CBOR decoding to the server.
Implies that a full fledged transforms would be applied by this API, rather than simple base64 encoding and embedding the normal configurations and results into a JSON structure. Specifically, that such transforms would eliminate the server's burden for understanding the CBOR format of attestations and extensions.
There is not much capability for doing this between the client and server.
The server can certainly create its own simplified forms for business logic and policy evaluation after verifying the credential result, but the server needs to be able to evaluate based on unmodified data in order to do signature integrity checks.
Add onto this that translation between CBOR and JSON is limited, as CBOR is a superset of JSON. Translating CBOR to JSON means that only responses that the client fully understands would be available.
// @github/webauthn-json/browser-ponyfillfunctionsupported(): boolean;functionparseCreationOptionsFromJSON(json: JSON): CredentialCreationOptions;functionparseRequestOptionsFromJSON(json: JSON): CredentialRequestOptions;// You can call `.toJSON()` on the result or pass directly to `JSON.stringify()`.functioncreate(options: CredentialCreationOptions,): Promise<PublicKeyCredential>;// You can call `.toJSON()` on the result or pass directly to `JSON.stringify()`.functionget(options: CredentialRequestOptions): Promise<PublicKeyCredential>;
This ended up fairly simple thanks to @MasterKale's efforts, but I'd love to see if this also works for people in the wild, in case that can help shake out any issues before browsers implement the API.
(I was able to use it in the github.com codebase without issue.)
The ability to pass the object directly to JSON.stringify() feels very neat — something that developers might to "by accident" (instead of thinking about whether to call .toJSON() explicitly) but which is the ergonomic way to do it! I think it would be helpful for guides covering that part of the API to call out those mechanics: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#description
Reacted by Emil Lundberg, qdqqd and Matthew Miller
Activity
MasterKale commentedon Nov 15, 2021
Thank you for submitting this ticket, I had intended to file something similar ages ago but never managed to make time for it. In my mind I totally think
PublicKeyCredentialneeds to be expanded in this direction.I encourage us to think about how devs work with native JS capabilities and build the spec for them, not build the spec for us and hope JS devs will follow. To get some of my own thoughts out about this:
Whatever direction an effort like this takes, I think the end goal should be to make WebAuthn easier for developers to consume, especially in the browser side of things. If we can accomplish that then adoption will follow. Right now WebAuthn is a PITA to implement in large part because
ArrayBuffer's just aren't common in front end JS development. Not to mention there's a lack of native methods to convert to/from Base64URL in the browser which further complicates things when the spec seemingly assumes such "standard library" APIs are available (😂/😭) I think we can tackle this with a smart addition toPublicKeyCredentialso long as we keep an eye on how we can make WebAuthn more practical to consume.dwaite commentedon Nov 16, 2021
That would be my preference.
We have a lot of values which would be named base64url property values at that point, e.g.
My reasoning for CBOR over JSON:
Because JSON cannot differentiate text from base64url-encoded binary, the selection of JSON would require a semantic knowledge of the message (including future additions) in order to process. This increases the maintenance of such serialization and deserialization.
The selection of JSON may also push for duplication of non-encoded forms, for example including what today is getPublicKey() as a duplicated JWK within the serialized JSON response. This particular example duplication of security information and increases the risk of an implementation accidentally relying on data which is not integrity protected.
I don't feel additional forms of data are necessary. For browser Javascript, we do not need a JSON form to introspect because we have the actual WebAuthn API. For things which a browser needs to understand, we should still focus on raising that information through the API, rather than through serialized forms.
For the relying party infrastructure processing the data however, we necessitate binary processing already by the nature of the protocols being written in terms of U2F-legacy binary and CBOR binary messages. Semantic transformation to other forms breaks integrity. Base64 encoding binary data does not make the relying party job easier.
Agreed. While a serialized form does not create any mandate, one could see how what is client javascript libraries today might get pared down to either send the serialized form in request/responses directly, or composed within additional API messages which provide something like an authentication workflow.
emlun commentedon Nov 16, 2021
See also #1619:
and #1362:
MasterKale commentedon Nov 16, 2021
I'll take this on. I'll try and get a draft PR up before too long, I know it'll need a lot of TLC but I think it'd be a worthwhile addition to the spec.
dwaite commentedon Nov 17, 2021
A rough first pass at a CDDL (as a potential underpinning of this addition): https://gist.github.com/dwaite/6afb1856e092e02ae6ada85f3ff1655d
CDDL normally has a single output data item, so there may be multiple descriptions needed if we define specific request/responses for create and get. I'm hardly a CDDL expert, though.
kreichgauer commentedon Nov 22, 2021
The WebIDL spec already allows for interfaces to provide a
toJSON()method. So I could see us here doing something like adding atoJSON()operation to theAuthenticatorAttestationResponseandAuthenticatorAssertionResponseinterfaces. Those methods would return a JSON object for the attribute members of those interfaces, with ArrayBuffer valued attributes converted to base64url encoded strings.WebIDL doesn't have similar "fromJSON" provisions AFAIK. But if we wanted to allow instantiation of
PublicKeyCredentialCreation/RequestOptionsfrom a server-supplied JSON object, we could e.g. definePublicKeyCredential.publicKeyCredentialCreation{Creation,Request}OptionsFromJson(), with basically the inverse conversion rules oftoJSON(). I.e., callers pass a JSON object with the respective members, and the method returns an equivalent dictionary with ArrayBuffer-valued attribute values parsed from their base64url encoding.dwaite commentedon Nov 22, 2021
While
toJSON()in WebIDL may be convention, I don't believe we could use thedefaultimplementation without changes to WebIDL or ECMAScript.In particular, the ask has been for this value to be Base64 (or I presume Base64URL) encoded, but such an encoding would need to be defined upstream by one of these two specifications for us to leverage a
DefaulttoJSON() implementation from WebIDL.We would probably want guidance from WebIDL that our declaration of a
fromJSON()would not conflict with WebIDL in the future.This would decrease the duplication of description languages, although WebIDL would expect us to define the dictionary formats of the current interface types.
Either way (WebIDL or CDDL), we have to resolve issue that
CredentialCreationOptions/CredentialRequestOptionscan not host static methods likefromJSON()- they are dictionaries, not interfaces.kreichgauer commentedon Nov 22, 2021
I don't think there's a requirement that if you define a
toJSONoperation, it has to use the default operation. For example: https://w3c.github.io/push-api/#dom-pushsubscription-tojson. We would define our own implementation without upstream changes.My suggestion is to hang them off of
PublicKeyCredential, the same way we do withisUserVerifyingPlatformAuthenticatorAvailable(). That way they also won't be genericfromJSON(), but ratherpublicKeyCredentialCreationCreationOptionsFromJSON()for example, so there is little risk of them conflicting with anything Web IDL might do in the future IMHO.18 remaining items
Firstyear commentedon Jan 21, 2022
I think you are over thinking this. Just imagine that instead of JS, replace it with WASM. The architecture is still:
Just replace the dynamic JS parts with WASM, and you get what what I'm asking.
Okay, to be explicit.
Today, when you perform a browser fetch request to a webauthn endpoint of a server, you receive a JSON response. Deserialising that JSON into the WASM or JS context, it is not possible to create a Uint8Array. As a result, the structure has an array of bytes, but in a different format.
This means that any RP today MUST create dynamic components that MUST execute in the browser, that MUST alter the content of any structure which is intended to be passed into navigator.credentials apis. This is commonly achieved by base64url encoding and decoding the fields.
So there a number of potential ways to tackle this:
So let's consider this from the JS/WASM context.
I think this section of the comment doesn't apply to the JS/WASM discussion, but I have discussed before about this issue within this group as this has led to CVE's in the past. If this change was to be accepted in a manner where browsers would need to alter their platform apis for navigator.credential, then it would be viable to actually potentially correct this long standing defect in the webauthn specification such that the entire chain of communication is verified rather than small elements.
MasterKale commentedon Jan 24, 2022
WASM is really neither here nor there, I suggest we constrain future discussion to JS because the question of how you invoke JS global APIs from WASM will never be the purview of this working group.
dagnelies commentedon Feb 15, 2022
If you make a
toJSON(), it would aleviate several of the current pain points to use this API and a great step forward. 👍Actually, it is a mystery to me why the API currently returns "things" that cannot even be sent to the server directly, but require "post-processing" to do so.
And if you provide such a
toJSON()method, please decode the whole since it is currently "doubly encoded" to avoid CBOR completely. So that you directly see the content of the attestation objects, have direct access to the public key, signatures and so on ....and not simply a base64 CBOR buffer, which besides of being obfuscated, tranfers the burden of CBOR decoding to the server.So basically, what was initially suggested in the post there #1362 😁
dwaite commentedon Feb 15, 2022
From #1362: " On the call of 2020-01-22 it was decided that the use of ArrayBuffers is reflecting W3C direction as we understand it and that revisiting that would be too much. [...]"
Getting rid of CBOR is not feasible. The security messages themselves are signed binary in a mix of U2F-inherited format and CBOR extensions/attestations.
Any translated version of the contents would no longer be integrity protected, and integrity protection is paramount to the server understanding authentication is being performed correctly. Any non-binary, non-CBOR form would be generated by the server after validating the binary responses had proper integrity and were correct answers to the challenges created by the server.
The getPublicKey() method, added in level 2, is meant to provide the public key on creation with the specified limitations. This includes not requesting attestation on registration, as you will need the non-modified binary message in order to verify said attestation.
dagnelies commentedon Feb 15, 2022
Sorry for being dumb, but I still don't get it.
On the client side, you have to transform it in proper JSON to even send it to the server.
And in order to get get the public key, you have to decode the CBOR stuff inside.
So, from the perspective of a web developer, I don't understand why being directly decoded would be a problem.
I haven't gone through the validation/verification part. Please take into consideration that an average developer has no idea about U2F and CBOR. What "we" are familiar with is to have a public key in order to verify a signature of some data. Almost always, these are just base64url encoded values sent around. So, in this spec, it feels highly unusual and strange that this unknown CBOR protocol plays such a crucial role ....actually, even after digging into the specs, I still don't know why the original CBOR encoded form would matter ...however with the spec being 165 pages long, it's of course extremely challenging to assimilate, so I probably missed the important part.
If you want to make something really great, then make a
toJWT()method, to obtain a signed Json Web Token 🎉 😁 ...that would be super easy to transmit over the wire, is familiar to every web developer and verification would be a breeze since it is a well known web standard with a mature ecosystem. In short, it would be great!dwaite commentedon Feb 15, 2022
Right, but the original statement:
Implies that a full fledged transforms would be applied by this API, rather than simple base64 encoding and embedding the normal configurations and results into a JSON structure. Specifically, that such transforms would eliminate the server's burden for understanding the CBOR format of attestations and extensions.
There is not much capability for doing this between the client and server.
The server can certainly create its own simplified forms for business logic and policy evaluation after verifying the credential result, but the server needs to be able to evaluate based on unmodified data in order to do signature integrity checks.
Add onto this that translation between CBOR and JSON is limited, as CBOR is a superset of JSON. Translating CBOR to JSON means that only responses that the client fully understands would be available.
v2.0.0-alpha1
v2.0.0-alpha1
v2.0.0-alpha1
lgarron commentedon Jun 30, 2022
I've implemented @MasterKale's API from #1703 in https://github.com/github/webauthn-json as
v2.0.0-alpha3.This ended up fairly simple thanks to @MasterKale's efforts, but I'd love to see if this also works for people in the wild, in case that can help shake out any issues before browsers implement the API.
(I was able to use it in the
github.comcodebase without issue.)The ability to pass the object directly to
JSON.stringify()feels very neat — something that developers might to "by accident" (instead of thinking about whether to call.toJSON()explicitly) but which is the ergonomic way to do it! I think it would be helpful for guides covering that part of the API to call out those mechanics: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#descriptionv2.0.0
Add support for WebAuthn data class JSON serialization.
dwaite commentedon Nov 9, 2022
bump; is there a reason for this to be open after the merge of PR #1703 ?
MasterKale commentedon Nov 9, 2022
No, we should be able to close this now.