OpenID4VCI
OpenID4VCI copied to clipboard
Add a mechanism for notifying the wallet about certain events
ODI4VCI would benefit from a mechanism that allows issuers to send notifications to the wallet or its backend to enable:
- The ability to notify the wallet of specific credential issuance process-related events, e.g., to reduce polling requests at the deferred issuance endpoint.
- The ability to inform the wallet or its backend about certain risk-related events, e.g., fraud, key compromise.
- The ability to notify the wallet of specific credential lifecycle-related events, e.g., a credential has been revoked independently from the status mechanism and associated TTL windows, new credential types can be requested, or the underlying credential dataset has changed, which is relevant for many credential types such as age-over-18, marriage, etc.
A potential solution could be based on the OIDF Shared Signals and related IETF standards work as presented at IIW. The slides can be found here.
The solution should support both push and pull notification mechanisms. While the pull mechanism is easier to implement, it has certain limitations. For example, if a wallet must maintain relationships with several issuers, polling event endpoints from those issuers introduces a significant load on the mobile device.
awesome!
the pull method is pratically what can be achieved using oauth status attestations, because the wallet instance automatically request and obtains the (relevant) updates about the status of its credentials
the push method raises to me some privacy concerns, since the wallet backed would be informed about which credential the wallet instance (holder) has obtained and their status
I'm really excited about your ideas anyway, since I'm wondering as well about how the shared signals may comes into place. In my context they may have sense between the VCI and the authentic sources. When an authentic sources changes the status of the data, previously used by a VCI for the issuance of a credential, the authentic source would signal this change (while the VCI should therefore revoke the credential).
the things I really like is that RISC seems quite ready for the main use cases I have in mind.
awesome!
the pull method is pratically what can be achieved using oauth status attestations, because the wallet instance automatically request and obtains the (relevant) updates about the status of its credentials
Yes, it can be but it would be good have to have a status method independent option even for this use case. Using the status method would require the wallet to poll some endpoint on a regular basis which might be an issue if wallets interact with a lot of issuers.
the push method raises to me some privacy concerns, since the wallet backed would be informed about which credential the wallet instance (holder) has obtained and their status
The idea would be that the event is encrypted to some ephemeral key the wallet holds, so the wallet backend is not aware of what is encoded in the event. There are ways the wallet backend can be implemented without compromising privacy. I agree that there is still a tradeoff but to scale such a solution a push model is still required and imo, it will be implemented anyways. If we can refer to a standard, we could at least give privacy guidance and benefit from all the other great things a standard can give you.
I'm really excited about your ideas anyway, since I'm wondering as well about how the shared signals may comes into place. In my context they may have sense between the VCI and the authentic sources. When an authentic sources changes the status of the data, previously used by a VCI for the issuance of a credential, the authentic source would signal this change (while the VCI should therefore revoke the credential).
the things I really like is that RISC seems quite ready for the main use cases I have in mind.
Yes, something like RISC seems useful. And I believe, if OIDF Shared Signals is used, any SET type can be communicated.
in-person WG mtg:
- problem statement sounds reasonable
- next steps are to discuss requirements and specific mechanisms
- need to discuss if push from issuer to the wallet works only when the wallet has a backend
- need to discuss if pull from the wallet to the issuer make sense too, given there is notifications endpoint
- @leecam suggested platform might be able to help?
- potentially need to update notifications endpoint with more signals.
@awoie
Using the status method would require the wallet to poll some endpoint on a regular basis which might be an issue if wallets interact with a lot of issuers.
Yes, the web operates with hundreds of HTTP requests in less than 1 second. For example, to load the content of this GitHub page, more than 110 HTTP requests were made for various resources like CSS, JS, SVG, etc. It's quite remarkable; that's just how the web functions. Likely, my Wallet won't hold more than 100 credentials, and the status assertions provided by these credentials will probably be preprocessed and stored in their cache, ready to be served as static content.
The idea would be that the event is encrypted to some ephemeral key the wallet holds, so the wallet backend is not aware of what is encoded in the event. There are ways the wallet backend can be implemented without compromising privacy.
Your point is valid; the Wallet Backend could indeed inspect the IPv4 address of the credential issuer (that makes the request), thereby gaining insight into the types of credentials the issuer is capable of issuing. Additionally, despite encryption, the Wallet Backend needs to identify the intended recipient of the payload to ensure it is delivered to the correct wallet instance. This process could inadvertently reveal to the Wallet Backend the types of credentials held by a particular wallet instance (and likely its user), all without the user's explicit consent.
Please accept my apologies for the paranoia, @awoie ; these concerns are among the reasons why I was compelled to create the status attestations, it was not an easy decision.
please indicate in the issue if you are interested in implementing a mechanism like this.
@Sakurann yes we would. we have a custom version of something similar already.
@awoie Thanks for creating this discussion topic. The use cases I have seen for the Shared signals framework is to exchange risk signals between companies and product backends.
For Issuer to wallet, we might want to take these considerations:
-
Wallets usually reside on mobile devices (phones) and exposing an https endpoint on them for a push functionality isn't a good idea. We might want to do Websocket or some other protocol that works well with mobile.
-
It might not be reliable for Issuers to send risk signals to the wallet app, I am not sure about what the wallet is supposed to do with that info, extra logic would have to be added to the wallet app to parse the risk signal and take action. In my opinion issuer itself should parse the risk signal and then send a push notification to implement an action e.g. revoke the user credentials.
-
(Update from Shayne Miel) Shared signal supports CAEP (about active application sessions) and RISC (about managed identities in some directory) schemas by default. Okta and Disney have defined a bunch of their own custom event types that get transmitted over SSF, and the SCIM working group has a proposal to use SSF to transmit SCIM events. https://openid.net/specs/openid-sharedsignals-framework-1_0-03.html https://sharedsignals.guide/#eventdefinitions
-
As the wallet will interact with various issuers, in most cases they will need to use 1 receiver per transmitter and will need a secure way to exchange a shared secret between the transmit and receiver pair. In the current interops and PoC's, they have to do it out-of-band and also need to think about secret rotation. Doing this on a large scale is a new problem to tackle.
-
Can you explain more about the wallet backend? I was under the impression that the issuer talks with the wallet directly. What is the nature of the wallet backend?
Here is an open-source implementation of the transmitter and receiver https://github.com/duo-labs/sharedsignals
@awoie Thanks for creating this discussion topic. The use cases I have seen for the Shared signals framework is to exchange risk signals between companies and product backends.
For Issuer to wallet, we might want to take these considerations:
- Wallets usually reside on mobile devices (phones) and exposing an https endpoint on them for a push functionality isn't a good idea. We might want to do Websocket or some other protocol that works well with mobile.
I agree that mobile devices cannot really expose an HTTPS endpoint but a wallet backend could. The challenge is to make this privacy preserving "enough" and this can be discussed what options we have available.
Regarding WebSockets, I'm not convinced that this will be a better solution but certainly a solution we should discuss. I'm concerned about the followoing: connection management (managing loads of open websockets of wallets), statefulness (retaining information about each open connection), battery lifetime and data usage of mobile devices and reconnection handling.
IMO, pull/polling will have to stay the fallback, WebSockets could be explored but I'm concerned about the points raised above. Having a wallet backend/notification endpoint chosen by the wallet can help mitigating these concerns but raise certain privacy challenges we would need to consider.
- It might not be reliable for Issuers to send risk signals to the wallet app, I am not sure about what the wallet is supposed to do with that info, extra logic would have to be added to the wallet app to parse the risk signal and take action. In my opinion issuer itself should parse the risk signal and then send a push notification to implement an action e.g. revoke the user credentials.
The examples on risk signals was related to wallet providers. IMO, throughout the wallet lifecycle, there might be signals where the recipient is the wallet instance and some where the recipient is the wallet provider. These signals could be encrypted to different keys to solve that issue, or two separate notification mechanisms could be provided for different types of signals.
- (Update from Shayne Miel) Shared signal supports CAEP (about active application sessions) and RISC (about managed identities in some directory) schemas by default. Okta and Disney have defined a bunch of their own custom event types that get transmitted over SSF, and the SCIM working group has a proposal to use SSF to transmit SCIM events. https://openid.net/specs/openid-sharedsignals-framework-1_0-03.html https://sharedsignals.guide/#eventdefinitions
I would be supportive to adopt the Shared signals work. We would need to identify where the gaps are. Currently, we have a very high-level conversation. Once we have nailed down the use cases, it will be easier to identify what the gaps in Shared signals are.
- As the wallet will interact with various issuers, in most cases they will need to use 1 receiver per transmitter and will need a secure way to exchange a shared secret between the transmit and receiver pair. In the current interops and PoC's, they have to do it out-of-band and also need to think about secret rotation. Doing this on a large scale is a new problem to tackle.
Agreed, we would need to do some thinking.
- Can you explain more about the wallet backend? I was under the impression that the issuer talks with the wallet directly. What is the nature of the wallet backend?
I think this depends on the role the wallet provider plays. One example that comes to mind is as follows: a user intentionally misuses a credential and commits fraud. The issuer detects this and wants to enforce deletion. In that case, the issuer might notify the wallet provider to initiate the deletion process. The wallet provider can then help the issuer contain the damage.
Here is an open-source implementation of the transmitter and receiver https://github.com/duo-labs/sharedsignals
Awesome, thanks.
a user intentionally misuses a credential and commits fraud. The issuer detects this and wants to enforce deletion
For this the Issuer should add a status management to the credential (CRL, status list, etc) to revoke it. This is the most effective way for this scenario.
We got feedback from some use cases where the credential creation process can take some time (like days). For this it would be great that the process can be delayed. Going first with OID4VP and then later doing a pre authorized code flow seems a bit "dirty".
Maybe the wallet can pass some information in the credential request to inform the issuer that it can use a notification endpoint like the wallet backend to notify when the credential is ready. If this is not supported by the issuer or the wallet is not sending it, it can go via the pull approach of the deferred credential endpoint. While polling is easy to implement, it will only work when the app is in foreground. So a push notification mechanism is the preferred way from an iOS or Android perspective.
The credential can be encrypted, but it still has the privacy problems that a wallet backend knows which wallet is getting credentials (from the sender it only receives the IP address, but no identity of the issuer). The wallet needs to pass some kind of secret in the credential request the issuer can then use to authenticate against the issuer and route it to the correct wallet.
@awoie and I have worked on a proposal for this, but there are some open points:
when adding a new events endpoint, it would allow the Wallet to pull events that are connected to a specific access token.
IMHO the most relevant event is the "credential is ready" event. So the issuer would just inform the Wallet "there are new events" and the Wallet has to fetch these from the events endpoint.
The good part about this "general notification" approach is that there are no critical information shared to the notification provider or a wallet backend (and we do not need to encrypt the payload).
However we have the extra step to fetch the events form the endpoint and then go to the deferred endpoint. So passing the relevant information like transaction id is ready to be fetched. It case of credential issuance there is no security issue with this since the access token you need at the deferred endpoint.
However we could define a parameter if the issuer should pass the event information directly into the notification or if it should be a generic notification. Then each Wallet can decide how to deal with this.
While polling is easy to implement, it will only work when the app is in foreground. So a push notification mechanism is the preferred way from an iOS or Android perspective.
I think this is conflating layers. The wallet backend can poll and send push notifications. As all the solutions we have involve the wallet backend, I think there's no reason to reject polling for this reason. (There are other reasons to have an alternative to the current polling mechanism though - I think the key point is to allow the backend to be involved without a significant reduction in privacy.)
While polling is easy to implement, it will only work when the app is in foreground. So a push notification mechanism is the preferred way from an iOS or Android perspective.
I think this is conflating layers. The wallet backend can poll and send push notifications. As all the solutions we have involve the wallet backend, I think there's no reason to reject polling for this reason. (There are other reasons to have an alternative to the current polling mechanism though - I think the key point is to allow the backend to be involved without a significant reduction in privacy.)
I don't really understand why this would conflate layers.
Are you suggesting that the wallet backend will instead poll the issuer? How would that scale? Especially for other event types which we have already identified. It basically means, the wallet backend has to poll all the issuers constantly.
If there is a specific privacy concern with the push model, this privacy concern is even amplified with the model you suggested.
I think it's worth noting that the solution being proposed for push notification does not require the wallet backend to be aware of which issuers have credentials in the wallet, whereas any reasonable wallet backend polling mechanism would require that. Even with wallet backend polling, this mechanism is a nice improvement for efficiency when we are talking about multi-day polls, as you should probably to back-off to something reasonable. This is especially true for things like credential updates (such as address, age_over attributes etc).
The good part about this "general notification" approach is that there are no critical information shared to the notification provider or a wallet backend (and we do not need to encrypt the payload).
I think my preference for general notifications goes beyond hiding critical information. Wallets must not rely on notifications succeeding. By not including information in the notification, we make it more likely that polling behavior and push behavior are supported consistently within the wallet, architecturally. These sorts of errors are hard to detect outside of production at scale, so it seems good to architecturally help wallets do the right thing. Given that we are talking about multi-day latencies, the extra network round-trip once we are at the wallet is a negligible cost IMO. Requiring Issuers to support two mechanisms also seems less than ideal.
Events Endpoint: I think the other event that would be nice to provide standardised would be 'credential_updated, version = (monotonically increasing version], cred_id = identifier', so allow wallets to know they should refresh a batch of credentials.
Other events that we have used are delete/suspend/re-auth (all just for user experience), but I do think these are less critical and possibly managable through other means.
I think it's worth noting that the solution being proposed for push notification does not require the wallet backend to be aware of which issuers have credentials in the wallet, whereas any reasonable wallet backend polling mechanism would require that. Even with wallet backend polling, this mechanism is a nice improvement for efficiency when we are talking about multi-day polls, as you should probably to back-off to something reasonable. This is especially true for things like credential updates (such as address, age_over attributes etc).
It depends how OID4VCI is implemented. If it is primarily on the smartphone, the wallet backend is not involved in the polling, but only receiving the signal from the issuer and notifying the smartphone.
The good part about this "general notification" approach is that there are no critical information shared to the notification provider or a wallet backend (and we do not need to encrypt the payload).
I think my preference for general notifications goes beyond hiding critical information. Wallets must not rely on notifications succeeding. By not including information in the notification, we make it more likely that polling behavior and push behavior are supported consistently within the wallet, architecturally.
In case of credential creation we already have a polling mechanism via the deferred endpoint. The same for credential status by checking the status list in an interval. So there is no critical scenario when a notification gets lost. How credential update is implemented is still open to be discussed. But going via the events endpoint will add extra traffic to fetch the events.
A couple of thoughts
- My guess is that events are not necessary for every credential. Different credential types have different life cycles in different ecosystems. Consider adding hints be sent to the wallet with respect to if any of this is necessary for a particular credential from this issuer
- I have security concerns about the endpoint simply being set by the wallet
proposal included below
For now the proposal only includes the event of credential ready. Update and revocation can be added later by appending the event types
@sloops77 I have defined the structure of the API, but the Wallet needs to pass the endpoint to the issuer as a typical callback function. Of course there is no guarantee that the Wallet will pass the correct endpoint. But since it's up to the issuer how to proceed with unsuccessful requests I do not see any problems. Can you please give more details for your concerns?
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: Thecredential_readyevent informs the Wallet that atransaction_idpreviously received in a Credential Response will now yield a valid Deferred Credential Response, instead of anissuance_pendingerror. 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 the Receiver via the Wallet Notification Endpoint, typically 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. See 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. How the Wallet obtains thisnotification_stateand how it maps thenotification_stateto 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 Receiver, verification and revocation is out of scope of the specification.endpoint: REQUIRED. URL of the Receiver's Wallet Notification Endpoint. See Event Notifications Flow for usage details.expiry: OPTIONAL. A numeric value indicating the expiration time of thetokenand associatedendpoint, expressed in seconds. The Issuer MUST NOT send notifications to theendpointafter this expiration time has passed.
Unrecognized fields in notify MUST be ignored by the Credential Issuer.
Example:
{
"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's Wallet Notification 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:
// 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:
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.
Wallet Notification Endpoint
This endpoint is used by the Receiver to consume the notification request from the Issuer.
The endpoint MUST be protected with a Authorization Bearer token passed in the HTTP Authorization header that was received from the Wallet upon notification registration.
Notification Request
An Issuer makes a Notification Request to the Wallet Notification Endpoint by sending the following parameters in the entity-body of an HTTP POST request using the application/json media type:
notification_state: as specified during registration
Any additional parameters MUST be ignored if not understood.
Below is a non-normative example of Notification Request:
POST /notify HTTP/1.1
Host: wallet-backend.com
Content-Type: application/json
Authorization: Bearer endiekjsdliuhrljhbs9a8Ddknkamjbvsjgajgafoijlijkg
{
"notification_state": "djdk39djsn"
}
Successful Notification Response
When the Receiver has successfully received the Notification Request from the Issuer, it MUST response 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/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 Wallet Notification Endpoint returns an Authorization Error Response, such as defined in Section 3 of [RFC6750].
When the notification_state value is missing, the HTTP response 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 Receiver is returning a 5xx error or times out, it is up to the Issuer how to proceed.
Extending Security Considerations
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 Wallet Notification 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 Wallet 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 Receiver 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 Wallet 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 Wallet Notification Endpoint is provided and operated by a Receiver, e.g., a Wallet Backend, not the Wallet itself. As such, implementers MUST clearly document and understand the trust relationships and interfaces between Wallet, Receiver, and Credential Issuer.
Extending Privacy 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 Wallet Notification Endpoint with the Issuer. Wallet Providers acting as Receivers 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 acting as Receivers 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 as Receivers 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 Wallet Notification Endpoint Lifecycle
The Wallet SHOULD register a Wallet 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 Requests 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.
This approach makes sense to me. I support adding this.
As one of the co-authors of this proposal, I also support this proposal.
I'm generally supportive of the feature and most of the mechanism.
I strongly disagree with the approach of performing the notification endpoint registration in credential request. I don't think that is correct from a lifecycle perspective and makes it difficult to extend it to statuses (or really any other events) in the future. IMO there should be an explicit registration endpoint, and credential requests can then be associated with that prior registration.
( have many thoughts on the privacy/security sections but probably best addressed as comments in a PR)
I agree with Gareth - my current perspective would also be that the registration of the endpoint should probably be an explicit step (e.g., its own endpoint discovered via metadata).
Using a dedicated endpoint is fine for me. It would also allow to define some kind of unregister endpoint. But then developers need to make sure that it get registered before the first event, like creation, can be fired.
I'm interested to know what the advantage of building our own mechanism is instead of relying on the shared signals framework?
Discussed (briefly) on today's WG call: There have been some arguments made that this is a non-breaking change and that we don't have any implementation experience yet, so it would be better to delay it to 1.1 given we have very strict timelines for getting 1.0 published and the extra time would give us the bandwidth to collect implementation feedback.
If anyone has strong reasons why it should be in 1.0, please speak up.
Generally I am very supportive of this feature I think it is highly important for lifecycle management. A couple of quick comments on the proposal so far
- Consider extensibility around securing the wallets notification endpoint: Bearer tokens are a nice and simple way to secure and endpoint, however depending on their implementation they might need to be refreshed, or rotated. Another possible mechanism to consider is relying on a sender based authentication mechanism instead where the issuer signs the request it sends to the notification endpoint which is verified by the JWKS hosted by the issuer. This signature could just be a JWT that is stuck in the header OR the payload of the notification request could become a JWT. Or another option might be to consider HTTPS based signatures.
- Some other events might be worthwhile standardising like
requested_deletion,credential_update_available(which is related to #472)
Disccsed on 1st May WG call: Moving to 1.1 seems okay. It is important but it is just additive (no breaking changes so doesn't need to be in 1.0) and polling needs to be implemented anyway.