Skip to content

Mobile DPoP FIDO Authn

Michael Schwartz edited this page Jul 30, 2024 · 19 revisions

A design for a first party mobile application that leverages dynamic client registration (DCR), DPoP access tokens, and FIDO user authenticaiton. In Jans Auth Server, we would end up having at least three long lived records: one for the person, one for each device (client), and one for each FIDO credential.

This spec leverages the following IETF drafts

mobile-dpop

title Mobile Authentication with DPoP and FIDO
autonumber 
actor Person
participant App
participant Device
participant Device Keystore
participant Auth Server
participant Fido2 Server
participant API
participant App Store

fontfamily mono
autonumber 1

participant ChangeMe1
critical Download App
Person->App Store: Search for App
Device<->App Store: Install App
end 

critical Dynamic Client Registration
Person->App: Start App
App<->Device: Get Device info
Device<->Device Keystore: Generate keys
Device->Auth Server: /register : Send public key\nfor client authn + app attestation
Auth Server->Auth Server: validate\napp attestation
alt attestation good
Auth Server->Device: client registration response
else attestation bad
Auth Server->Device: 400 {"error":"bad_attestation",\n"error_description": "Server verification of app attestation failed"}
end
end

alt Enrollment (First time using app)

Person<->App: uid / pw\n(future: NFC card,\n or verifiable credential)
App->Auth Server: POST /authz-challenge \n  {"acr_values":"pw-enroll",\n  "client_id":"1234",\n  "scope":"authz-challenge"}
Auth Server->Auth Server: validate pw
App<->Fido2 Server: FIDO biometric enrollment
Auth Server->App: code
end
 
alt Call API
App->Auth Server: POST /authz-challenge \n  {"acr_values":"fido2",\n  "client_id":"1234",\n  "scope":"authz-challenge"}
Auth Server->App: 403 Forbidden\n  {"error": "authorization_required",\n   "device_session":"uY29tL2F1dGhlbnRpY"}
loop authn required because id_token invalid
App->Device: Android / iOS\nFIDO API
Person<->Device: present biometric
App->Fido2 Server: /fido 2: Find user by keyHandle+RP, check fido2 response signature
Fido2 Server-> App: Mint token with type fido2
App->Auth Server: POST /authz-challenge\n  {"acr_values":"fido2",\n  "client_id":"1234",\n  "scope":"xyz",\n  "device_session":"uY29tL2F1dGhlbnRpY",\n  "fido2_token":"9d2d-848919ce89c9"}
Auth Server->Auth Server: Verify fido2 token
Auth Server->App: code
end
App->Auth Server: /token\ncode + private key authn
Auth Server->App: Issue DPoP access_token
App->API: access_token
end


https://sequencediagram.org

DPoP Detailed Sequence Diagram

title DPoP sender-constraint access_token and refresh_token

autonumber 1
note right of RP: Authorization Code Flow
RP->AS: Request authorization with dpop_jtk
AS->AS: dpop_jkt saved for authorization code
AS->RP: Return authorization code

note right of RP: Token Request
RP->AS: Request token with DPoP JWT
AS->AS: Validates DPoP JWT
AS->AS: Validates dpop_jkt against DPoP JWT if it's authz code

AS->AS: Creates access_token bound to public key cnf/jkt
note right of AS: if AT is bearer cnf/jkt is available via introspection 
AS->RP: Returns DPoP-bound access_token with cnf/jkt (response token_type=DPoP)
RP->RS: Request resource with access_token and DPoP JWT (with "ath" - AT hash)
RS->RS: Validates access_token against DPoP (public key match cnf/jkt)
RS->RS: Validates DPoP against access_token (access_token hash in DPoP "ath")
RS->RP: Return protected resource

DPOP-sequence

sequencediagram.org

Clone this wiki locally