In the CTAP spec (https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-client-to-authenticator-protocol-v2.0-id-20180227.html), we have the following tables:
WebAuthN authenticatorMakeCredentialoperation | CTAP聽authenticatorMakeCredential聽operation
--- | ---
requireUserPresence | Not present in the current version of CTAP. Authenticators are assumed to always check user presence.
requireUserVerification | options.uv or pinAuth/pinProtocol
WebAuthN聽authenticatorGetAssertion聽operation | CTAP聽authenticatorGetAssertion聽operation
--- | ---
requireUserPresence | options.up
requireUserVerification | options.uv or pinAuth/pinProtocol
That to me means userVerification/userPresence = uv/up.
Then we have this in the spec: https://www.w3.org/TR/webauthn/#getAssertion
Let _userPresence_ be a Boolean value set to the inverse of _userVerification_.
I interpret this sentence as userVerification includes userPresence. When userVerification is required, userPresence is also required implicitly. Hence, the response from the authenticator will only have the following two valid combinations between uv and up ({uv, up}):
However, in the CTAP spec, it looks like requiring uv doesn't necessary mean requiring up.
In section 5.2, Step 7:
Collect user consent if required. This step MUST happen before the following steps due to privacy reasons (i.e., authenticator cannot disclose existence of a credential until the user interacted with the device):
- If the "uv" option was specified and set to true:
- If device doesn鈥檛 support user-identifiable gestures, return the CTAP2_ERR_UNSUPPORTED_OPTION error.
- Collect a user-identifiable gesture. If gesture validation fails, return the CTAP2_ERR_OPERATION_DENIED error.
- If the "up" option was specified and set to true, collect the user鈥檚 consent.
- If no consent is obtained and a timeout occurs, return the CTAP2_ERR_OPERATION_DENIED error.
I interpret the above as the authenticator will check uv and up independently according to the request's parameters.
If user agents send the request as suggested by both spec when userVerification is required from the RP, then an authenticator could send a response that includes the {uv, up} as {1, 0}.
So this really confuses me. I think we need some clarifications on either the WebAuthN spec or the CTAP spec. I will suggest we change the WebAuthN spec to:
"Let _userPresence_ be a Boolean value set to the inverse of _userVerification_." => "Let _userPresence_ be true."
I agree this is suboptimal as currently written. As I recall, the construction of "Let _userPresence_ be a Boolean value set to the inverse of _userVerification_" was done in order to align WebAuthn with CTAP and get the desired behaviour, but looking back now at the CTAP archives it seems like I might just have misinterpreted those CTAP consent collection steps as exclusive branches instead of sequential steps.
I will suggest we change the WebAuthN spec to:
"Let _userPresence_ be a Boolean value set to the inverse of _userVerification_." => "Let _userPresence_ be true."
I support this suggestion, but I think we probably can't do this before L2.
While the text would benefit from some clarification about the terms, here is the situation.
Basic principles:
CTAP options that influence user presence:
CTAP options that influence user verification:
_So the only option RP can influence from WebAuthN is "UserVerificationRequirement" which is applicable for both webauthn create and get methods and controls user verification. User presence is always required from WebAuthN layer._
So below is the WebAuthN options that RP translates to CTAP: _In every case below, the actual request that is being sent to the authenticator (and whose response will be send back to the RP) MUST have "up" set to true as silent authentication is NOT allowed from the spec currently and user presence is always required._
_WebAuthN Method: Create_
UserVerificationRequirement: Required/Preferred:
UserVerificationRequirement: discouraged:
_WebAuthN Method: Get_
UserVerificationRequirement: Required/Preferred:
UserVerificationRequirement: discouraged:
I also agree with Emil and alanwaketan. This should be changed to "Let userPresence be true"
I think we want a substantial WG discussion of this before we foreclose the possibility of silent authentication in some circumstances. Particularly, silent authentication without user presence may be appropriate for device authentication in IoT applications.
wrt @selfissued's https://github.com/w3c/webauthn/issues/1123#issuecomment-460800238:
to try to clarify and set context: not supporting "silent authn" (i.e., a webauthn authn ceremony lacking any user interaction) in webauthn (i.e., "on the _Web_" specifically, i.e., above the authenticator API (e.g., CTAP) layer) has historically been justified on a _privacy_ basis. See the discussion regarding use cases and issues here, and here, and here from issue #199.
AFAICT, CTAP presently implicitly supports so-called "silent authentication" if authenticatorGetAssertion is called with both uv=false and up=false.
What might be the IOT-specific use cases ? Might they be addressed at the authenticator API level (e.g., CTAP) and not at the Web level?
Most helpful comment
I agree this is suboptimal as currently written. As I recall, the construction of "Let _userPresence_ be a Boolean value set to the inverse of _userVerification_" was done in order to align WebAuthn with CTAP and get the desired behaviour, but looking back now at the CTAP archives it seems like I might just have misinterpreted those CTAP consent collection steps as exclusive branches instead of sequential steps.
I support this suggestion, but I think we probably can't do this before L2.