Search code examples
webauthnauthenticatorfidoattestations

WebAuthn authenticator attestation response id and rawId


I would like to ask a question regarding id and rawId.

When implementing webauthn, in the authenticator attestation response, I see that we have both id and rawId . Reading the spec (https://www.w3.org/TR/webauthn-1/#dom-publickeycredential-rawid) , id is base64url(rawId)

{
  "type": "public-key",
  "id": "AV1--2gCLXLF9_5bGWDwZn6FP_OqAWfKY74mckatWMgN65o5OW8q2k9XVbYl8kAqPtpEoBlM0opKEjwDqYRBDIYbAl058O8ZQWS-r0M0L-9ikcu3tKuMxfFnRZ9gU6tnDH6QqzYwUg",
  "rawId": "AV1--2gCLXLF9_5bGWDwZn6FP_OqAWfKY74mckatWMgN65o5OW8q2k9XVbYl8kAqPtpEoBlM0opKEjwDqYRBDIYbAl058O8ZQWS-r0M0L-9ikcu3tKuMxfFnRZ9gU6tnDH6QqzYwUg",
  "response": {
    ...
  }
  ...
}

So here is my questions:

  • why we need id
  • why in the example above, my id is exactly like rawId?
    • does it's always the same? If it does, can we get rid of id in the response?
  • If I save the public key id to the database (later use that public key id to create the allowCredentials list), which one below should I follow?
    1. save id in the database, use id to create allowCredentials list
    2. save base64url(rawId) in the database, then use that base64 url encoded value to create allowCredentials list

Solution

  • Q1. Why we need id

    The answer to why we have both id and rawId is because it's by design in the spec:

    id is inherited from Credential, though PublicKeyCredential overrides Credential's getter, instead returning the base64url encoding of the data contained in the object’s identifier internal slot.
    https://www.w3.org/TR/webauthn-2/#iface-pkcredential

    Q2. why in the example above, my id is exactly like rawId? does it's always the same? If it does, can we get rid of id in the response?

    We get back raw bytes for rawId, which must be compared to the bytes encoded in id as part of the initial verification of the registration response, so technically we can't drop it.

    Besides, for whatever reason, if base64url encoding is inappropriate, RP might use unencoded raw value so rawId is returned as well.

    Q3. If I save the public key id to the database (later use that public key id to create the allowCredentials list), which one below should I follow?

    It's up to RP implementation, as said above, for whatever reason, if base64url encoding is inappropriate, RP might use unencoded raw value and encode it to whatever format RP prefers.

    I store id because it's already encoded into a format that easy to copy/paste and compare in logs when troubleshooting. Later we will use that id to create the allowCredentials and send it back to the authenticator. No need to do the extra work of base64url(rawId), use the id is perfectly fine.