Skip to content
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

Surface platform authenticator status in the create (and maybe get) response / help RPs track UV/PA/RK #1567

Open
lgarron opened this issue Feb 9, 2021 · 10 comments

Comments

@lgarron
Copy link
Contributor

lgarron commented Feb 9, 2021

The following are specified in the same place:

https://w3c.github.io/webauthn/#dictdef-authenticatorselectioncriteria

dictionary AuthenticatorSelectionCriteria {
    DOMString                    authenticatorAttachment;
    DOMString                    residentKey;
    boolean                      requireResidentKey = false;
    DOMString                    userVerification = "preferred";
};

However, there is no consistent way for the RP to check on these criteria:

Whether the registration is for a user-verifying authenticator

Embedded inside CBOR attestation.

Drawbacks:

  • Requires sending a non-trivial amount of code to read on the client (but not so bad to read on the server).

Whether the registration is a discoverable credential (resident key)

Available in a client extension.

Drawbacks:

  • Only implemented in Chrome 89 until recently), [not yet available on some platforms[(https://omahaproxy.appspot.com/).
  • If I understand correctly, the RP can only tell if the "required" semantics were passed to the authenticator, not what type of credential was created?
  • RPs have to remember to ask for this info (unless Note to encourage storage of registered credential details #1556 leads to a change). May of them will not know to ask for it, or think to ask for it, and it is generally good practice not to ship extra code to the client if you don't need it. RPs might not realize they needed to ask for an extension until it's too late.

Whether the registration is a platform authenticator

As far as I can tell, this information is not available from the response. The RP has to ask for it, and hope the client did the right thing.

EDIT based on comments below: This is implicitly revealed by a value of internal returned by getTransports().


Looking at this, I have the following thoughts:

  1. It would be nice to receive information whether the registration comes from a platform authenticator, at least in the case where the RP specifically asked for it.
  2. It would be nice if this information was provided to the RP in a consistent way, and ideally in a way that the RP is likely to save by default (i.e. not purely in an extension).
  • If it's undesirable reveal all three properties in all case, it is possible to e.g. place them all inside the same response object/map, but set them to null to indicated redacted info.
  1. It would be nice if all three properties were attested by the authenticator. I recognize this is probably a stretch.

I know there are historical reasons why the spec acts as it does. But it is bewildering to find out this information for an RP implementing WebAuthn the first time, and even I myself mistakenly believed for almost two years that the create response contains the platform authenticator status of the registration.

Quoting myself from #1565

This breaks "avoid needless complexity" and — if it could be fixed in the spec — "priority of constituencies".

Since it looks like the spec will have at least 3 levels and level 2 is still being finalized, it is clear that browsers are still working on their WebAuthn implementations. I think it is still feasible to include a [change] at this point and hope for it to land in browsers in a reasonable time frame

@lgarron lgarron changed the title Surface platform authenticator status in the create response / helping RPs track UV/PA/RK Surface platform authenticator status in the create response / help RPs track UV/PA/RK Feb 9, 2021
@lgarron
Copy link
Contributor Author

lgarron commented Feb 9, 2021

For what it's worth, my understanding is that authenticators can also change their properties over time. It would be nice to know for sure, and maybe to have a way for the RP to be able to tell if/when this happened. For example, updated info could be sent at auth time. However, this is not as useful for RPs if certain other features/bugs are addressed.

@Kieun
Copy link
Member

Kieun commented Feb 9, 2021

Whether the registration is a platform authenticator
As far as I can tell, this information is not available from the response. The RP has to ask for it, and hope the client did the right thing.

Regarding this issue, you can implicitly guess whether the generated credential is bound to the platform authenticator when returning the value as internal with getTransports call.

@akshayku
Copy link
Contributor

akshayku commented Feb 9, 2021

Whether the registration is for a user-verifying authenticator

If RPs require user verification, they specify userVerification as required.
RPs can always check for uv bit in the response to verify that user verification is performed.

Whether the registration is a discoverable credential (resident key)

The best we can do at this time is via the credProps extension. Regarding the implementation on one browser vs another, that is not a spec issue. Browser/OS vendors are teams with their own schedules and it always takes some time to get everything implemented. We will get there.

Whether the registration is a platform authenticator

API itself contains the attachment property. And the response has transports value.

@lgarron
Copy link
Contributor Author

lgarron commented Feb 10, 2021

The best we can do at this time is via the credProps extension. Regarding the implementation on one browser vs another, that is not a spec issue.

I probably don't understand the internals well enough; what limits browsers from reporting if a discoverable credential was created?

Regarding this issue, you can implicitly guess whether the generated credential is bound to the platform authenticator when returning the value as internal with getTransports call.

API itself contains the attachment property. And the response has transports value.

Ah, thanks, i had forgotten about that. That leaves me with 2 thoughts:

  1. How safe is it to assume that internal means platform authenticator? Do they mean the same thing, or can either refer to something that is not covered by the other? Could the spec provide a guarantee here?

  2. If it's safe to include such data, is it desirable that the API only allows indirect access to authenticator UV/PA/RK, and using different opt-in mechanisms? As an RP implementer, I would expect to ask for those in one place, and receive info about them in one place.

As discussed in #1556 , many devs will probably not collect such data until it's too late. We don't currently collect transport data for GitHub (I think it wasn't commonly available in browsers last we visited this), and doing so would entail 1) adding more code to webauthn-json for everyone, and 2) deciding where to check and store transport data.

It would be much more ergonomic if the value could be extracted from the default API response like user verification.

@Kieun
Copy link
Member

Kieun commented Feb 10, 2021

I think the best effort for the attachment (transport) at this moment is asking for the specific attachment when creating the call by showing different UXs depending on the attachment for the user. And, that attachment value and returned value of getTransports for the future references should be stored.
The detailed transport is just for RPs to help browsers to find the corresponding authenticators easily. If RP wants to do something with transport to decide UX flow, it's better idea to rely on attachment only (platform or cross-platform).

@akshayku
Copy link
Contributor

How safe is it to assume that internal means platform authenticator?

"Internal" means platform authenticator. However, mobiles can also act like a roaming authenticator. So in that case, in addition to "internal", they will also include other transports. Overall it is a hint for the platform, and RP should store it and pass it back to the platform. However, they should not rely on exact implementation behavior, as those are actually hints.

is it desirable that the API only allows indirect access to authenticator UV/PA/RK, and using different opt-in mechanisms?

I would be against allowing certain authenticators and not others, if that's what you are asking. In a way, specifying attachment=platform property limits one to platform authenticators, but that was for a special case for registration. For authentication, intentionally, there is no attachment property as a platform can be interacted via other mechanisms.

@nadalin nadalin added this to the Futures (catch-all) milestone Feb 10, 2021
@nsatragno
Copy link
Member

what limits browsers from reporting if a discoverable credential was created?

That's exactly what credProps does!

@nadalin nadalin assigned agl and unassigned akshayku Feb 10, 2021
@equalsJeffH
Copy link
Contributor

equalsJeffH commented Feb 10, 2021

on 2021-02-10 call:
@ve7jtb summarizes that this is begging the question of having a hybrid call, e.g.:pass in known credIDs, and create new one if those don't work (ie yield an assertion): "assert or create". (perhaps that is more what issue #1568 is about)

In any case we are uncertain of the motivation behind this.

@nicksteele will ask for clarification.

@lgarron lgarron changed the title Surface platform authenticator status in the create response / help RPs track UV/PA/RK Surface platform authenticator status in the create (and maybe get) response / help RPs track UV/PA/RK Feb 10, 2021
@equalsJeffH
Copy link
Contributor

Summarizing: there are (admittedly imperfect) answers to all three of the original post's "criteria" in the above discussion. Additionally, the RP techniques and webauthn API changes proposed in issue #1637 will (we hope) ameliorate the concerns expressed in this issue.

@emlun
Copy link
Member

emlun commented Sep 24, 2024

I would argue that most of these are addressed at this point:

Whether the registration is for a user-verifying authenticator

This is now sort-of available via getAuthenticatorData() followed by a static byte index ([32]) and bitmask (& 0b100), no CBOR library needed. Only if the RP requests userVerification: "preferred" or "required", but maybe that's close enough.

Whether the registration is a discoverable credential (resident key)

As mentioned above, this is available in the credProps extension output.

Whether the registration is a platform authenticator

[...]

  1. It would be nice to receive information whether the registration comes from a platform authenticator, at least in the case where the RP specifically asked for it.

This is now available as the PublicKeyCredential.authenticatorAttachment attribute.

  1. It would be nice if this information was provided to the RP in a consistent way, and ideally in a way that the RP is likely to save by default (i.e. not purely in an extension).

Not really addressed. Perhaps L4 could move credProps.rk to a property on AuthenticatorAttestationResponse, like getTransports(), but on the other hand that would also just mean there's yet another place the RP needs to look for this information.

  1. It would be nice if all three properties were attested by the authenticator. I recognize this is probably a stretch.

Not addressed. I personally don't think these properties are important enough to be worth this effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants