Closed telamon closed 11 months ago
Glad you brought this up.
I attempted to save adopters from the headache of when to probe by doing it "on-demand"
but after closer inspection it seems I just caused the headache elsewhere.
The methods createDID()
and probeDIDs()
are straightforward.
The difference is that the DID becomes settled/known after AuthMethod
was used instead of after the probe.
The end result is identical to original implementation but at a lower cost of complexity and a clearer API.
(I think yes :+1: )
I considered the following scenarios: | authenticator state | browser state | user-choice | Action | button presses | Outcome |
---|---|---|---|---|---|---|
* | unknown | New ID | createDID(); getAuthMethod(did) |
2 | success | |
has key | known | New ID | forget();createDID(); getAuthMethod(did) |
2 | success | |
has key | known | Login | getAuthMethod(did) |
1 | success | |
has key | unknown | Login | probeDIDs(); getAuthMethod(candidates) |
2 | success | |
empty | unknown | Login | probeDIDs(); |
1 | fail |
Given the new methods; I would update the example in the README.md
to:
// New identity
const did = await createDID('label')
await storeSomehow(did)
const authMethod = await getAuthMethod({ did })
// Returning user
const did = await getSomehow()
let authMethod
if (did) { // previous DID found
authMethod = await getAuthMethod({ did })
} else { // new device detected
const dids = await probeDIDs()
authMethod = await getAuthMethod({ dids })
}
const session = await DIDSession.authorize(authMethod, { resources: [...] })
await storeSomehow(session.did.id) // Save for later
Thanks for the suggested api. A few questions/notes:
createDID('label')
, what is the purpose of the parameter?session.did.parent
, not session.did.id
(the latter is just the session key)@oed 2,3 gotcha!
1: The label is the name of the credential, it's what's displayed in OS-popups on discoverable ops:
if probe returns two fully qualified did-strings, does that mean we export one false DID? Not sure what to call it but gut tells me to ask if we should be proactive about preventing accidental storage/transmission of not-yet-settled DIDs.
const recoveryToken = await probe()
const authMethod = getAuthMethod({ did, recoveryToken })
Is this a concern?
1 . Makes sense. What happens if there are two keys with the same label?
4 . Ok, makes sense to call it something like recoveryToken
as you suggest.
5 . I wonder if we should also add another option in getAuthMethod
that would allow you to pass a function as follows:
function selectDID(did1: string , did2: string): Promise<did>
const authMethod = getAuthMethod({ selectDID })
Calling getAuthMethod
would result in one signature to sign the CACAO, then the user could resolve the correct DID in whichever way they want.
(webauthn does not export functions to remove/relabel credentials, so we can't really do much more here.)
probe()
and sign()
does not matter for recovery).
The cons of conditional callbacks is that they are more difficult to debug/trigger, and affects only those who wish to use passkeys in a decentralized manner.Thinking "There should be one clear way to do it.": I cast my vote on the manual probe instead of callback; (makes more sense, causes less developer strain shrug)
I would prefer if we could do both probe and callback approaches.
For example in Ceramic we could store a document after the first time we authenticate. This would allow a developer to query documents for the two DIDs and if it finds one of them it knows which is the correct DID.
Add support for passkeys/webauthn
Status:
wip
Description
This PR adds support for using hardware tags and OS authenticators .
How Has This Been Tested?
Definition of Done
Before submitting this PR, please make sure:
References:
R&D Notes / Worklog