DSR-RFC-02 Resource Access

Resource access can only be performed from the previously registered and fresh attested device.

1. High Level Flow

ressource_access

  1. Policy Decision Point regularly downloads, verifies, and installs the currently active policy from Policy Administration Point as well as context information from Policy Information Point.
  2. TrustClient requests an attestation from the platform APIs.
  3. Attestation results are transmitted to Device Management Service (GMS) in form of Device Attestation Token. Device Registration Service verifies the authenticity and integrity of the attestation and issues the Device Token
  4. TrustClient connects to the eHealth Service using TLS. Mutual authentication is performed using the client certificate issued in DSR-RFC-01
  5. Trust Clientsends the Device Token as bearer token bound to mTLS certificate or a OAuth2 Code to the eHealth Service’s PEP. PEP verifies the authenticity of the Device Token and extracts the device information.
  6. PEP uses device information and other available signals (e.g. HTTP request headers) as input to the PDP. PDP applies the policy against the device information and any other input provided to it by the PEP.
  7. Once PDP allowed the access by making the positive decision, the PEP lets the eHealth Service to continue and provide resources and other functionalities to the client.

2. Flow Details

@startuml DSR-RFC-02 Main Flow
autonumber "<b>[00]"
skinparam defaultFontSize 10
skinparam defaultFontName Helvetica
skinparam DefaultMonospacedFontName Courier
skinparam lengthAdjust none

activate TrustClient

participant GMS
box "Policy Enforcement"
participant PEP
participant PDP
end box
participant Backend as "eHealth\nService"

TrustClient -> GMS++: ""GET /nonce""
note right
Regular TLS
Server auth only
end note
GMS -> GMS: generate ""nonce""\nstore ""nonce"" in session
GMS -> TrustClient --: ""nonce""


TrustClient -> TrustClient: generate\n  ""pkceCodeVerifier""\n  ""pkceCodeChallenge""

alt#FEFFD5  2.1.1 Create Android Device Attest
TrustClient -> TrustClient: Provide JWS_attest_signed 
else 2.2.1 Create Apple Device Attest 
TrustClient -> TrustClient: Provide JWS_attest_signed 
end


TrustClient -> GMS ++ : ""JWS_attest_signed"" \n ""pkceCodeChallenge""  
note right
Mutual TLS
end note
GMS -> GMS: check if device ID is known\n(find device registration)
GMS -> GMS: check if publicKey fingerprint from mTLS is\n"sub" claim at JWS_attest_signed
GMS -> GMS: verify JWS_attest_signed  
GMS -> TrustClient: return auth_code

alt#FEFFD5 2.1.2 Verify Android Device Attest 
GMS -> GMS: Provide device_token 
else 2.2.2 Verify Apple Device Attest
GMS -> GMS: Provide device_token 
end

GMS -> GMS: sign device_token(privKey_GMS)
 
 ... some delay ...
 
TrustClient -> GMS: ""auth_code""\n""pkceCodeVerifier""
note right
Mutual TLS
end note
GMS -> GMS: verify\n ""auth_code""\n ""pkceCodeVerifier""
return ""device_token""
note right
PKCE can also be performed by PEP
end note

TrustClient -> PEP ++: request resource(""device_token"")
hnote over PEP: authenticate user
PEP -> PEP: verify ""device_token""
PEP -> PEP: create \n""policy_decision_input""

PEP -> PDP: request \n""policy_decision""
PDP -> PEP: ""policy_decision""

Backend -[#8BC34A]> TrustClient: <font color="#8BC34A"><&circle-check*4.0>
   

/'
group Android
TrustClient -> TrustClient: trigger Play Integrity API(nonce_PlayIntegrityAPI),\n\tcreate keypair keypair_attest_derived(pubkey_mTLS),\n\tAttestCert_derived(nonce_attest_derived),\n\tcollect device_attributes_security
TrustClient -> TrustClient: create JWT_attest(\n\tTYPE_ANDROID,\n\tintegrity_verdict,\n\tAttestCert_derived,\n\tdevice_attributes_security,\n\tnonce)
TrustClient -> TrustClient: sign JWT_attest with keypair_attest_derived
end Android

group Apple
TrustClient -> TrustClient: trigger AppAttestAPI assertion(\n\tnonce_attest_derived | fingerprint(pubkey_mTLS)\n),\ncollect device_attributes_security
TrustClient -> TrustClient: create JWT_attest(\n\tTYPE_iOS,\n\tassertion,\n\tdevice_attributes_security,\n\tnonce)
TrustClient -> TrustClient: sign JWT_attest with keypair_attest_sign
end Apple
'/

@enduml

2.1 Android specifics

2.1.1 Create Android Device Attest

@startuml
autonumber "<b>['2.1.1' 00]"
skinparam defaultFontSize 10
skinparam DefaultMonospacedFontName Courier
skinparam lengthAdjust none

activate TrustClient

group Android
TrustClient -> TrustClient: trigger Play Integrity API(nonce_PlayIntegrityAPI),\n\tcreate keypair keypair_attest_derived(pubkey_mTLS),\n\tAttestCert_derived(nonce_attest_derived),\n\tcollect device_attributes_security
TrustClient -> TrustClient: create JWT_attest(\n\tTYPE_ANDROID,\n\tintegrity_verdict,\n\tAttestCert_derived,\n\tdevice_attributes_security,\n\tnonce)
TrustClient -> TrustClient: sign JWT_attest with keypair_attest_derived
end

2.1.2 Verify Android Device Attest

@startuml
autonumber "<b>['2.1.2' 00]"
skinparam defaultFontSize 10
skinparam DefaultMonospacedFontName Courier
skinparam lengthAdjust none

activate GMS

group Android
GMS -> GMS: extract\n\t""integrity_verdict""\n\t""AttestCert_derived""\n\t""device_attributes_security""
GMS -> GMS: verify\n\t""AttestCert_derived""\ncheck\n\t""AttestCert_derived is child""\n\t""of AttestCert_mTLS""
GMS -> GoogleServer ++: request\n\t""integrity_verdict(integrity_verdict)""
return return ""verdict_json""
GMS -> GMS: create\n\t""device_token(""\n\t""verdict_json,""\n\t""device_attributes_security,""\n\t""UUID_device <-> KVNR""\n\t"")""

end

2.2 Apple specifics

2.2.1 Create Apple Device Attest

@startuml
autonumber "<b>['2.2.1' 00]"
skinparam defaultFontSize 10
skinparam DefaultMonospacedFontName Courier
skinparam lengthAdjust none

activate TrustClient

group Apple
TrustClient -> TrustClient: trigger AppAttestAPI assertion(\n\tnonce_attest_derived | fingerprint(pubkey_mTLS)\n),\ncollect device_attributes_security
TrustClient -> TrustClient: create JWT_attest(\n\tTYPE_iOS,\n\tassertion,\n\tdevice_attributes_security,\n\tnonce)
TrustClient -> TrustClient: sign JWT_attest with keypair_attest_sign
end

2.2.2 Verify Apple Device Attest

@startuml
autonumber "<b>['2.2.2' 00]"
skinparam defaultFontSize 10
skinparam DefaultMonospacedFontName Courier
skinparam lengthAdjust none

activate GMS

group Apple
GMS -> GMS: extract assertion, device_attributes_security
GMS -> AppleCA ++ : verify assertion
return return result
group optional
  GMS -> AppleBackEnd ++: assess fraud risk
  return return assessment
end optional
GMS -> GMS: create device_token(\n\tassertion,\n\tdevice_attributes_security,\n\tUUID_device <-> KVNR\n)

end

Last modified December 3, 2023: resolved GMS - DMS ambiguity (b371f09)