Add more details on wallet structure to README#43
Conversation
| * **Presentation Assembly**: The wallet extracts the requested claims, builds a cryptographically secure **Session Transcript** to bind the response to the specific connection, signs the response using the private key stored in secure hardware, packages the payload, and returns it to the calling verifier. | ||
|
|
||
| ### 2. Credential Issuance | ||
| Handles credential issuance requests from issuers. When a user initiates getting a credential from an issuer by scanning a QR code or opening a link, the issuer can trigger a system intent that launches the credential creation and storage process: |
There was a problem hiding this comment.
Not exactly right - issuer calls the Android Credential Manager API to initiate the issuance call.
There was a problem hiding this comment.
Still seems a bit off.. How about something like this:
Normally a user can trigger credential issuance in two ways:
- Issuer initiated flow: the user triggers a request to issue a VDC from an issuer application or website. For example, an issuer.gov website may offer its users an option to "Add your passport to your wallet". The issuer calls the Credential Manager issuance API to make an OpenID4VCI Credential Offer request. To handle such requests a wallet must first integrate with Credential Manager to register its metadata. Credential Manager will display relevant options for a user to select. After the user selects a wallet option, the wallet application will be invoked and then the wallet can proceed with the steps needed to complete the issuance.
- Wallet initiated flow: the user requests to add a VDC from their wallet application. For example, a wallet may offer a button to "Add your passport". In this case, the wallet maintains its supported issuer list and metadata. It does not need to integrate with the Android Credential Manager to complete this function.
CMWallet supports the issuer initiated flow, allowing arbitrary type of credentials in the SD-JWT VC or mdoc format.
| │ | ||
| [Room DB] ◄── Save issued credential ◄── Hardware-backed attestation process ◄── Request credential from Issuer | ||
| ``` | ||
| * **Issuer triggers intent**: The issuer triggers Android's `CREATE_CREDENTIAL` system intent, launching `CreateCredentialActivity`. |
There was a problem hiding this comment.
Let's just link to the Android DAC doc, or copy content over
There was a problem hiding this comment.
Do you mean the below section or this line in particular? I think it's still useful to have text here - the DAC page can still be the maintained source of truth.
There was a problem hiding this comment.
I added some more detailed suggestion in the comment above. We should update the sections Issuer triggers intent and Progress bottom to correctly reflect the issuance flow
| └── matcher-rs/ # Rust implementation of wasm matcher | ||
| ``` | ||
|
|
||
| ### Detailed Directory Mapping |
There was a problem hiding this comment.
Do we need this part? Worry that it may become quickly outdated
There was a problem hiding this comment.
This is intended to help users map each of the concepts covered to the directories in which they're implemented. Do we think the core files might change in the future? Even if new features are added the core files should likely remain the same - WDYT?
There was a problem hiding this comment.
Fine with me either way; but I hope the structure above is good enough for most of the time.
| ``` | ||
| [Holder(wallet) app] ──► Registers metadata with Credential Manager | ||
|
|
||
| [Verifier app] ──► Requests digital credential claim(s) ──► Credential Manager matches claims and displays options to user ──► User selects credential ──► Holder is invoked ──► Holder returns signed presentation to verifier |
| * **Presentation Assembly**: The wallet extracts the requested claims, builds a cryptographically secure **Session Transcript** to bind the response to the specific connection, signs the response using the private key stored in secure hardware, packages the payload, and returns it to the calling verifier. | ||
|
|
||
| ### 2. Credential Issuance | ||
| Handles credential issuance requests from issuers. When a user initiates getting a credential from an issuer by scanning a QR code or opening a link, the issuer can trigger a system intent that launches the credential creation and storage process: |
There was a problem hiding this comment.
Still seems a bit off.. How about something like this:
Normally a user can trigger credential issuance in two ways:
- Issuer initiated flow: the user triggers a request to issue a VDC from an issuer application or website. For example, an issuer.gov website may offer its users an option to "Add your passport to your wallet". The issuer calls the Credential Manager issuance API to make an OpenID4VCI Credential Offer request. To handle such requests a wallet must first integrate with Credential Manager to register its metadata. Credential Manager will display relevant options for a user to select. After the user selects a wallet option, the wallet application will be invoked and then the wallet can proceed with the steps needed to complete the issuance.
- Wallet initiated flow: the user requests to add a VDC from their wallet application. For example, a wallet may offer a button to "Add your passport". In this case, the wallet maintains its supported issuer list and metadata. It does not need to integrate with the Android Credential Manager to complete this function.
CMWallet supports the issuer initiated flow, allowing arbitrary type of credentials in the SD-JWT VC or mdoc format.
| ### 2. Credential Issuance | ||
| Handles credential issuance requests from issuers. When a user initiates getting a credential from an issuer by scanning a QR code or opening a link, the issuer can trigger a system intent that launches the credential creation and storage process: | ||
| ``` | ||
| [Issuer app] ──► Triggers system intent: CREATE_CREDENTIAL ──► calls Credential Manater's CreateCredentialActivity |
| * **Matchers (WASM matching)**: In order to match a verifier's requested claims with registered metadata, Credential Manager runs the wallet's compiled WebAssembly (WASM) matching module (e.g., `openid4vp1_0.wasm`) in an offline, secure system sandbox. The matcher evaluates the verifier's query against the stored credentials without revealing any private user details to the calling app. Credential Manager comes with a default matcher if none are specified. | ||
| * **Holder invocation**: If a matching credential is found, Android displays the card to the user. Clicking the card invokes the holder and launches `GetCredentialActivity`. CMWallet launches an additional `BiometricPrompt` during invocation for additional user consent. | ||
| * **Presentation Assembly**: The wallet extracts the requested claims, builds a cryptographically secure **Session Transcript** to bind the response to the specific connection, signs the response using the private key stored in secure hardware, packages the payload, and returns it to the calling verifier. | ||
|
|
There was a problem hiding this comment.
Two additional notes:
- Multi-credential presentation: Credential Manager also supports requesting multiple credentials (e.g. age + payment) in a single request.
- UI Flavors: The credential selector UI automatically adapts to different use cases, such as verification or payment confirmation, displaying the most appropriate layout for the request.
| │ | ||
| [Room DB] ◄── Save issued credential ◄── Hardware-backed attestation process ◄── Request credential from Issuer | ||
| ``` | ||
| * **Issuer triggers intent**: The issuer triggers Android's `CREATE_CREDENTIAL` system intent, launching `CreateCredentialActivity`. |
There was a problem hiding this comment.
I added some more detailed suggestion in the comment above. We should update the sections Issuer triggers intent and Progress bottom to correctly reflect the issuance flow
| ``` | ||
| * **Issuer triggers intent**: The issuer triggers Android's `CREATE_CREDENTIAL` system intent, launching `CreateCredentialActivity`. | ||
| * **Progress bottom sheet**: The wallet displays a Compose bottom sheet showing a progress bar while it parses the Credential Offer. | ||
| * **Key Generation and Attestation**: The wallet generates a secure cryptographic EC P-256 key pair in the phone's hardware-backed **Android KeyStore**. It creates a signed **DPoP Proof** and an **Android Keystore Key Attestation** to prove the key is tied to a genuine physical device. |
| ``` | ||
| * **Issuer triggers intent**: The issuer triggers Android's `CREATE_CREDENTIAL` system intent, launching `CreateCredentialActivity`. | ||
| * **Progress bottom sheet**: The wallet displays a Compose bottom sheet showing a progress bar while it parses the Credential Offer. | ||
| * **Key Generation and Attestation**: The wallet generates a secure cryptographic EC P-256 key pair in the phone's hardware-backed **Android KeyStore**. It creates a signed **DPoP Proof** and an **Android Keystore Key Attestation** to prove the key is tied to a genuine physical device. |
There was a problem hiding this comment.
CMWallet supports Android key attestation for credential binding keys. It provides a direct Android hardware backed key attestation and is the recommended key proof approach on Android.
| ## Directory & Module Guide | ||
|
|
||
| ``` | ||
| CMWallet/ |
There was a problem hiding this comment.
Should also talk about the testdata folder that supports generating SD-JWT VC / mdoc for testing.
| └── matcher-rs/ # Rust implementation of wasm matcher | ||
| ``` | ||
|
|
||
| ### Detailed Directory Mapping |
There was a problem hiding this comment.
Fine with me either way; but I hope the structure above is good enough for most of the time.
No description provided.