Mirko Mollik
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # Motivation The Issuer should be able to inform a Wallet about newly issued credentials by sending notifications directly to the Wallet using an endpoint provided by the Wallet—typically exposed by the Wallet Provider. By adopting a push-based notification mechanism, the system becomes significantly more efficient, particularly for mobile scenarios where the Wallet may be running in the background and conserving resources. This approach ensures timely updates without the overhead of continuous polling. However, the notification mechanism SHOULD NOT be considered a complete replacement for periodic checks performed by the Wallet, when feasible. Since there is no guarantee that a notification will be reliably delivered—due to network issues or background limitations—periodic polling remains an important fallback to ensure no process is stuck or any updates are missed. # Additions to OID4VCI The following additions enable the Issuer to notify the Wallet about credential lifecycle events through push notifications. Instead of polling an event endpoint, the Issuer sends notifications directly to an endpoint provided by the Wallet. This improves efficiency, especially in mobile contexts where minimizing background activity is important. This proposal includes: - A new optional Issuer Metadata parameter indicating support for credential lifecycle notifications. - New optional parameters in the credential request allowing the Wallet to register for lifecycle notifications for the requested credentials. - A notification endpoint provided by the Wallet, which acts as a webhook for the Issuer to notify about lifecycle events. ## Event Types To ensure interoperability across different Credential Issuers and Wallets, the following event types are defined: - `credential_ready`: The `credential_ready` event informs the Wallet that a `transaction_id` previously received in a Credential Response will now yield a valid Deferred Credential Response, instead of an `issuance_pending` error. The Wallet should now attempt to retrieve the credential. ## Passing Notification Registration If the Issuer declares support for notification functionality in its metadata, the Wallet can include the following parameter in the Credential Request: - `notify`: OPTIONAL. An object providing the Issuer with information needed to send notifications to a Receiver, typically to a Wallet Backend. - `events`: REQUIRED. An array of Event objects that the Wallet registers to receive notifications for. Each Event object MUST include the following parameters: - `type`: REQUIRED. A string identifying the event type the Wallet wants to receive. Note: The type of the event will not be included by the Issuer in the Notification sent to the Receiver’s endpoint. See [Event Types](#event-types) for the list of supported event types. - `notification_state`: REQUIRED. An opaque string value chosen by the Wallet, which the Issuer includes in the payload when sending notifications to the Receiver’s endpoint. How the Wallet obtains this `notification_state` from the Receiver and how it maps the `notification_state` to the event type and credential issuance lifecycle is out of scope for this specification. - `token`: REQUIRED. A bearer token used by the Issuer to authorize with the Receiver. The exact implementation of the token creation, exchange between Wallet and Wallet Backend, verification and revocation is out of scope of the specification. - `endpoint`: REQUIRED. URL of the Receiver's notification endpoint. See [Event Notifications Flow](#event-notifications-flow) for usage details. - `expiry`: OPTIONAL. A numeric value indicating the expiration time of the `token` and associated `endpoint`, expressed in seconds. The Issuer MUST NOT send notifications to the `endpoint` after this expiration time has passed. Unrecognized fields in `notify` MUST be ignored by the Credential Issuer. **Example:** ```json { "events": [ { "type": "credential_ready", "notification_state": "djdk39djsn" } ], "token": "endiekjsdliuhrljhbs9a8Ddknkamjbvsjgajgafoijlijkg", "endpoint": "https://wallet-backend.com/notify" } ``` ## Extending Credential Issuer Metadata Parameters Add the following to the Issuer Metadata: - `event_types`: OPTIONAL. An array listing supported event types (e.g., `credential_ready`). This must be present if the Issuer supports notifications. ## Event Notifications Flow Once the Wallet provides the necessary `notify` information, the Issuer can push notifications to the designated Receiver endpoint (e.g., a Wallet Backend). It is RECOMMENDED that the Receiver includes the received Wallet-provided `notification_state` in the notification payload that is sent to the Wallet to enable the Wallet to correlate the notification with the corresponding event type and credential issuance session. **Example flow:** The following is a non-normative example of a Credential Request with the new `notify` parameter: ```json // other credential request parameter omitted for readability ... "notify":{ "events": [ { "type": "credential_ready", "notification_state": "djdk39djsn" } ], "token": "endiekjsdliuhrljhbs9a8Ddknkamjbvsjgajgafoijlijkg", "endpoint": "https://wallet-backend.com/notify" } ``` Based on this example, the issuer will send the following request: ```http POST /notify HTTP/1.1 Host: wallet-backend.com Content-Type: application/json Authorization: Bearer endiekjsdliuhrljhbs9a8Ddknkamjbvsjgajgafoijlijkg { "notification_state": "djdk39djsn" } ``` The Receiver is expected to forward this to the Wallet via mechanisms like Firebase Cloud Messaging (FCM), including the `notification_state` as payload. The Wallet uses the received `notification_state` to identify the event type and credential issuance session it should act on. ## Notification Endpoint This endpoint is used by the Wallet Backend to consume the notifcation request from the Issuer. The endpoint MUST be protected with a Authorization Bearer token passed in the header. The Issuer MUST use the `token` provided upon registration for the Bearer token value. The JSON paylod MUST include the following parameter: - `notification_state`: as specified during registration Any additional must be ignored if not understood. ### Successful Notification Response When the Wallet Backend has successfully received the Notification Request from the Issuer, it MUST repsonse with an HTTP status code in the 2xx range. Use of the HTTP status code 204 (No Content) is RECOMMENDED. Below is a non-normative example of response to a successful Notification Request: ```http HTTP/1.1 204 No Content ``` ### Notification Error Response If the Notification Request does not contain an Authorization Token or contains an invalid Authorization Token, the Notification Endpoint returns an Authorization Error Response, such as defined in Section 3 of [RFC6750]. When the `notification_state` value is missing, the HTTP repsonse MUST use the HTTP status code 400 (Bad Request) and set the content type to `application/json` with the following parameters in the JSON-encoded response body: - `error`: REQUIRED. The value of the error parameter SHOULD be one of the following ASCII [USASCII] error codes: - `invalid_event_request`: The Notification Request is missing a required parameter, includes an unsupported parameter or parameter value, repeats the same parameter, or is otherwise malformed. In case the Wallet Backend is returning a 5xx error or times out, it is up to the Issuer how to proceed. ## Extend security chapter ### 12.8 Notification Security The introduction of push-based notifications between Credential Issuers and Wallets adds new communication paths that must be secured to maintain the integrity, confidentiality, and trustworthiness of the overall issuance process. The following considerations apply: #### 12.8.1 Endpoint Authentication and Authorization Issuers MUST authenticate to the Wallet’s notification endpoint using an authorization token included in the notify.token parameter. This token MUST be treated as a bearer credential and MUST only be transmitted over secure channels. The Wallet or Wallet Backend MUST validate this token and reject requests from unauthenticated sources. #### 12.8.2 Transport Security All communication to the notification endpoint MUST occur over HTTPS with TLS 1.2 or higher to protect against man-in-the-middle and passive eavesdropping attacks. This aligns with existing TLS requirements in this specification and ensures both confidentiality and message integrity. #### 12.8.3 Endpoint Confidentiality The Wallet MUST treat the notify.endpoint URL as sensitive information and SHOULD NOT expose it to third parties or persist it unnecessarily, to avoid enabling unauthorized actors to target the endpoint. #### 12.8.4 Replay Attack Mitigation Issuers SHOULD include a unique identifier or timestamp in each notification payload. The Wallet SHOULD track recent identifiers and reject duplicates to protect against replay attacks. This can be implemented through session-level nonce tracking or message deduplication. #### 12.8.5 Authorization Scope Isolation Tokens used to access the notification endpoint SHOULD be scoped to a specific issuance session and SHOULD NOT grant broader access to Wallet functionality. These tokens SHOULD expire after a reasonable period or after a defined number of uses to reduce misuse risk. #### 12.8.6 Notification Delivery Failures The Issuer SHOULD implement retry logic using exponential backoff when a notification delivery fails due to transient errors. However, it MUST avoid infinite retries. After a fixed number of failed attempts, the Issuer MAY log the failure and rely on fallback mechanisms like Wallet polling. #### 12.8.7 Rate Limiting and Abuse Prevention The Wallet or Wallet Backend SHOULD implement rate limiting to defend against accidental or malicious overload. Notifications from a given Issuer SHOULD be subject to throttling and abuse detection to prevent denial-of-service scenarios. #### 12.8.8 Notification Payload Validation The Wallet MUST validate incoming notification payloads to ensure they conform to expected structure and values. Malformed or unexpected payloads MUST be rejected. Any parsing or transformation operations SHOULD be designed to avoid injection attacks. #### 12.8.9 Token Storage and Protection The authorization token for the notification endpoint MUST be stored securely by the Issuer and treated as a credential. It SHOULD NOT be logged or included in URLs. Wallets MUST assume the token can be misused if leaked and treat it with similar protections as access tokens. #### 12.8.10 Trust Model Clarity The specification assumes that the notification endpoint is provided and operated by the Wallet Provider, not the Wallet itself. As such, implementers MUST clearly document and understand the trust relationships and interfaces between Wallet, Wallet Backend, and Credential Issuer. ## Extending privavy consideration ### 14.8 Notification Privacy Push-based notifications introduce new data flows and metadata exchange between Credential Issuers, Wallets, and potentially Wallet Backends. These mechanisms must be designed with strong privacy guarantees to protect users and their credentials from tracking, profiling, or unintended data exposure. The following considerations apply: #### 14.8.1 Data Minimization The notification payload is limited to the minimal data required for the Wallet—specifically, an opaque identifier chosen by the Wallet for a particular event type within a specific credential lifecycle session—to identify the associated event type and issuance process. Personally identifiable information (PII), credential data, or unique user identifiers MUST NOT be included in the notification message. #### 14.8.2 User Consent and Transparency Wallets MUST obtain explicit user consent before registering a notification endpoint with the Issuer. Wallet Providers SHOULD present clear information to the user explaining that the Wallet may receive asynchronous updates from an Issuer and what data such updates contain. This aligns with the existing [14.1 User Consent] requirement. #### 14.8.3 Anonymity and Linkability Notification endpoints MAY allow an Issuer to infer relationships between issuance sessions and Wallet instances. Wallet Providers SHOULD consider mechanisms to avoid making endpoints user-identifiable across Issuers or issuance sessions, for example by rotating endpoint URLs or tokens per transaction. This mitigates risks of cross-issuer linkability or user profiling. #### 14.8.4 Notification Routing Through Third Parties If the notification is delivered via a Wallet Backend or push messaging service (e.g., Firebase Cloud Messaging), the involvement of third parties introduces potential data sharing. Wallet Providers MUST assess the privacy policies and practices of such intermediaries and ensure that no unnecessary data is exposed. They SHOULD avoid routing credential-specific metadata through these services whenever possible. #### 14.8.5 Notification Endpoint Lifecycle The Wallet SHOULD register a notification endpoint only for the duration necessary to receive relevant events. Endpoints SHOULD be invalidated after use or upon expiration to minimize the risk of correlation and tracking. #### 14.8.6 Avoiding Persistent Identifiers Persistent identifiers (e.g., user IDs, Wallet instance IDs) MUST NOT be included in the event request or the payload. Issuers SHOULD NOT infer or attempt to associate notification events with specific users unless strictly required and consented to. #### 14.8.7 Observability by Issuers While notifications improve efficiency, they also increase visibility for Issuers into the Wallet’s behavior (e.g., how long it takes the Wallet to react). Wallets SHOULD ensure that internal state transitions are not externally observable beyond what is needed for credential retrieval. #### 14.8.8 Log Management and Data Retention Credential Issuers and Wallet Providers MUST treat notification data as sensitive and SHOULD apply strict retention policies. Logs that include endpoint URLs, tokens, or session identifiers SHOULD be encrypted and retained only as long as needed for audit or troubleshooting purposes. #### 14.8.9 Regulatory Compliance Wallet Providers and Issuers SHOULD evaluate whether the use of notification infrastructure constitutes personal data processing under regulations such as GDPR. If so, appropriate legal bases (e.g., consent, legitimate interest) must be established, and data subject rights must be supported.

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully