wicg / digital-credentials Goto Github PK
View Code? Open in Web Editor NEWDigital Credentials, like driver's licenses
Home Page: https://wicg.github.io/digital-credentials/
License: Other
Digital Credentials, like driver's licenses
Home Page: https://wicg.github.io/digital-credentials/
License: Other
Jevons Paradox is an economic principle which introduces the concept that availability and efficiency of providing a resource (in this case data from a driver's license) can often times lead to increased consumption of the resource. This spec should be addressing whether this additional consumption provides an overall net positive gain for the web platform or if this will cause further harm to marginalized communities of people.
While many people may consider this a given of any web api, in the specific case of a driver's license we're increasing access to sensitive PII in a verified way about a user. This raises ethical questions which may be in violation of the ethical web principles and privacy principles defined by TAG. Therefore it begs the question to what degree should the web platform be contributing to this phenomena and should this API be standardized in the first place?
More specifically, I think we need to specifically address what societal impact this additional API will bring to the further marginalization of vulnerable communities and whether the acceptance of this API into the web platform is worth the tradeoffs for those additional harms. By increasing access to sensitive, verified PII we're inadvertently also making it easier to justify the requirement of providing this data in order to access specific web services. While in some cases, many would consider this acceptable such as lawmakers in Louisiana[1] it will also introduce a slippery slope where many web services will request this data from a user in a way that stretches the boundary of "legitimate usage" of data. I'm sure we can all think of many more dystopic use cases that could be introduced because of the increased access to this data. For example, I'm sure there will be at least one government that contemplates requiring all users to provide this information to social networks so they can subpoena dissenting voices on social networks like Twitter and surveil or silence them because of this required deanonymization. Is that direction we're prepared to take the web in by introducing this API?
This was originally posted here: WICG/mobile-document-request-api#6
I don't want this to be lost, so am moving it over here.
After sitting on this idea a bit I think the direction we should look to technologically here is how we utilize intentional friction in order to reduce the likelihood of abuse. As an example, if we make it so easy to conduct a liveness test with this API then we'll also encourage liveness checks to be done at every authentication check. However, if it has a high level of friction to conduct a liveness check it may be only used for registration and important 2FA step ups.
Sept 2023
This HOWTO will guide you through to with with the prototype of the API in Chrome and Android. It is a bit cumbersome at the moment because it is in its early stage of incubation (e.g. protected by flags). If you run into problems, feel free to ping @leecam or @samuelgoto on slack.
chrome://flags
, search for digital credentials
and enable that flagYou should now be able to test the Identity Credential with our sample apps to verify your setup:
IC Purse
adb install -t <path-to-apk>
App Verifier
adb install -t <path-to-apk>
Add Self Signed Document
Request via Credential Manager
. This should invoke the Credential Selector UX showing the available documents that match the request. At this point you see the mDL you provisioned above.You can use this website and reader app to test and verify your wallet application. You should see your credentials alongside credentials from our sample wallet.
If you got this far, you should have something that looks more or less like the following:
https://www.youtube.com/watch?v=mZeSVNK0jlw
You can build a website that uses the JS API to request documents on the web.
// Gets a CBOR with specific fields out of mobile driver's license as an mdoc
const {response} = await navigator.credentials.get({
identity: {
providers: [{
holder: {
selector: {
format: ["mdoc"],
retention: {days: 90},
doctype: "org.iso.18013.5.1.mDL",
fields: [
"org.iso.18013.5.1.document_number",
"org.iso.18013.5.1.portrait",
"org.iso.18013.5.1.driving_privileges",
"org.iso.18013.5.1.aamva.organ_donor",
],
},
params: {
nonce: "gf69kepV+m5tGxUIsFtLi6pwg=",
readerPublicKey: "ftl+VEHPB17r2 ... Nioc9QZ7X/6w...",
}
}
}],
}
});
You can also build a native app verifier by calling the following API:
TODO(@leecam): write the instructions on how to use the CredMan API for requesting digital credentials
You can build our samples as a starting point and have a play.
# cd ~/.m2/repository
# unzip idsdk.zip
You should now be able to use the use the demo apps as before
Note: Remember to only use the two app package names you shared with us. We allow-listed them to use this API while the API is still under development so that we can control backwards incompatible breaking changes.
implementation 'com.google.android.gms:play-services-identity-credentials:0.0.1-eap01'
The credential registration happens here:
https://github.com/google/identity-credential/blob/android-credential-manager/appholder/src/main/java/com/android/mdl/app/document/DocumentManager.kt#L88
Note: This API will be provided as part of the Credential Manager Jetpack Library. Unfortunately we can’t share this with you directly quite yet. Instead you’ll use some slightly lower-level APIs. Jetpack just provides more developer friendly wrappers over the API you’ll be using today. It's still fairly straightforward but note that when this API is released the public API will be exposed via Cred Man.
The incoming request parameters are provided to your wallet app as a JSON string. This JSON string is provided by the calling RP application. The specification of this JSON is currently being defined by the W3C, but this API doesn’t concern itself with its contents. It is the responsibility of your wallet app to parse this request and form the response.
Chrome and our test apps provide the JSON in the following form. This is just a simple request format to demonstrate the API, this will likely evolve in the W3C working group. This is the RedBox in David’s ISO presentation.
{
"providers": [
{
"responseFormat": "mdoc",
"selector": {
"fields": [
{
"name": "doctype",
"equal": "org.iso.18013.5.1.mDL"
},
{
"name": "org.iso.18013.5.1.portrait"
},
{
"name": "org.iso.18013.5.1.family_name"
},
{
"name": "org.iso.18013.5.1.given_name"
},
{
"name": "org.iso.18013.5.1.document_number"
},
{
"name": "org.iso.18013.5.1.expiry_date"
},
{
"name": "org.iso.18013.5.1.issue_date"
},
{
"name": "org.iso.18013.5.1.age_over_18"
},
{
"name": "org.iso.18013.5.1.aamva.DHS_compliance"
},
{
"name": "org.iso.18013.5.1.aamva.EDL_credential"
}
]
},
"params": {
"nonce": "ZWuRXfcV7-iRkZH4puWnRA==",
"requesterIdentity": "BOHjVu78FDoBZdxmSn6EOfcC1Eam8c9XCKjblABWpt4="
}
}
]
}
The provider API allows you to define the matching logic used by your wallet to decide which documents/credentials to show in Credential Selection UI for a given json request.
This matcher logic is defined as a wasm module that you register with the system as follows
val registrationRequest = RegistrationRequest(
credentials = yourMetaData, // A binary blob that we pass to your matcher
matcher = yourMatcherBinary, // The wasm module
type = "com.credman.IdentityCredential" // has to set to this
)
val client = IdentityCredentialManager.Companion.getClient(context)
client.registerCredentials(registrationRequest)
Android will execute your wasm matcher in a sandbox upon receiving a request from an RP application or website. The matcher binary will be provided with the credential data blob you provide as part of registration, the incoming request json from the calling RP and the calling app information (calling packagename or origin). The matcher's job is to parse the incoming request and to populate the entries in the selector UX.
As per above, we will provide more developer friendly APIs in jetpack towards the end of the year. This includes default matchers and helper classes. So most wallets won’t need to deal with writing their own matcher unless they have some complex matching logic or want to support a new credential type.
For this proof of concept you can use the matcher from our demo app. You can place it in your assets folder in your app. You can find it here:
https://github.com/google/identity-credential/tree/android-credential-manager/appholder/src/main/assets
There are 3 helper classes that you can copy and paste into your wallet app, they can be found here:
https://github.com/google/identity-credential/tree/android-credential-manager/appholder/src/main/java/com/android/mdl/app/credman
These helpers use the provided matcher and build up the credential data in a structure the matcher understands.
You can use these helpers to register a simple credential as follows:
val fields = mutableListOf<IdentityCredentialField>()
// Add the doc type field
fields.add(IdentityCredentialField(
name = "doctype",
value = "fakedoc",
displayName = "Document Type",
displayValue = "Fake doc type"
))
// Add a name field
fields.add(IdentityCredentialField(
name = "firstname", // field name is required for matching the fields in the json
value = "Erika", // the vaule is optional.
displayName = "First Name", // required to show the matched fields in the selector
displayValue = "Erika" // the vaule is optional.
))
// Create the entry
val entry = listOf(IdentityCredentialEntry(
id = 1, // will be passed to your app if the credential is picked by the user
format = "mdoc",
title = "Erika's's Driving License",
subtitle = "California DMV",
icon = BitmapFactory.decodeResource(context.resources, R.mylogo),
fields = fields.toList(),
disclaimer = null,
warning = null,
))
// Create the registry with the list of entries
val registry = IdentityCredentialRegistry(listOf(entry))
// Register using the stock matcher
val client = IdentityCredentialManager.Companion.getClient(context)
client.registerCredentials(registry.toRegistrationRequest(context))
Once you implement the above registration flow, you can test the web app, your credentials should appear in the selector (assuming they have the required fields to be considered a match).
This API attempts to provide a huge amount of flexibility for the wallet application. The goal is to just handle credential selection and wallet invocation. All Android requires is that the wallet (via the matcher) provides enough information about the credential and the requested attributes that we can render a selector. This information allows the user to make an informed choice about which document to proceed with.
Once a credential is selected by the user Android will intent into the wallet app, where it can show its own UI to gather consent from the user, e.g by showing a biometric prompt. Our sample app doesn’t show any UI, but we suggest your app shows at least a biometric prompt.
You need to add a new Activity to your app with the following intent handler in the manifest
com.google.android.gms.identitycredentials.action.GET_CREDENTIALS
Here is an example:
<activity
android:label="@string/app_name"
android:name=".GetCredentialActivity"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="androidx.identitycredentials.action.GET_CREDENTIALS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Android will invoke this Activity if your credential is selected by the user. You should use it to obtain user consent and form the response.
Again helper libs will do most of this heavy lifting in the future but for now you’ll be exposed to a bit of the plumbing.
Our sample Activity is here: https://github.com/google/identity-credential/blob/android-credential-manager/appholder/src/main/java/com/android/mdl/app/GetCredentialActivity.kt
In your onCreate method you should obtain the request:
// The JSON from the calling app
val request = extractGetCredentialRequest(intent)
// the credential ID of the selected credential (registered above)
val credentialId = intent.getLongExtra(EXTRA_CREDENTIAL_ID, -1)
// The calling app info
val callingAppInfo = extractCallingAppInfo(intent)
You should parse the request and generate the response for the selected credential.
The response is provided as a ByteArray. Our demo apps place a base64 encoded string of encrypted response in this byte array. (at some point we’ll change this to a string)
This string is passed directly back to the calling app. Again Android does not concern itself with the format of the request or the response. We leave it to the wallet to understand the format of the request and generate the response.
The response is provided as follows (again helpers in the future will hide some of these gory details):
val bundle = Bundle()
// you need to generate the encodedCredentialDocument
bundle.putByteArray("identityToken", Base64.encodeToString(encodedCredentialDocument, Base64.NO_WRAP or Base64.URL_SAFE).toByteArray())
val credentialResponse = com.google.android.gms.identitycredentials.Credential("type", bundle)
val response = GetCredentialResponse(credentialResponse)
val resultData = Intent()
setGetCredentialResponse(resultData, response)
setResult(RESULT_OK, resultData)
finish()
The best way is probably to look at the sample code :)
The logic starts here: https://github.com/google/identity-credential/blob/android-credential-manager/appholder/src/main/java/com/android/mdl/app/GetCredentialActivity.kt#L151
Much of the heavy lifting is performed in this class:
https://github.com/google/identity-credential/blob/android-credential-manager/identity-android/src/main/java/com/android/identity/android/mdoc/util/CredmanUtil.kt
Its a standard mdoc device response CBOR, encrypted with HPKE. The main change is the session transcript, which is generated here:
https://github.com/google/identity-credential/blob/android-credential-manager/appholder/src/main/java/com/android/mdl/app/GetCredentialActivity.kt#L158
Note: We always set the calling package name to "com.android.mdl.appreader" in our sample apps, so you’ll need to do this too until we fix this hack.
"type" (in certain Verifiable Credential formats) is used to identify syntax and semantics of the Claims in the Credential between the Wallet and the Verifier. It is missing from Verifiable Credentials example, but is present in the Reconciliation example, so I assume the omission was not intentional.
Surfaced as a core discussion topic on the first call (2023-10-04).
Ex: browser APIs vs OpenID4VP vs other protocols
Probably the most straightforward way would be to split something identity-specific off of the existing navigator.credentials.get()
, which would then be used for non-identity stuff. navigator.credentials.getIdentity()
maybe?
In order to reduce harmful over-requesting of 3P attested information it would be useful to have a registry of origins allowed to request credentials. If the origin is not listed then the site would not be able to prompt the user for permission of the credential.
The default lists will need to be maintained. Two proposals for this registry would be W3C or country specific privacy commissioners who publish them in a way that the browser services can load and store them.
Should we also allow users to be able to override them and if so what is the proper UX for this? If so would it make sense to do this as a part of the permissions UX currently implemented or as a UX with more friction?
This isn't really in scope for the web platform API itself, it is more for the OS platform plumbing, but wanted to have the discussion.
Will (some) identity wallets need context from the TLS session in the browser (or even the app platform in the case of a native app verifier), such as certificate attributes or awareness that a verifier (or issuer) presented with a Qualified Website Authentication Certification (QWAC)?
Opaque, protocol-specific request strings don't allow site authors to indicate why and how each field in the request will be used, or to provide the context for a user to make a reasonable decision.
We could also open similar issues on the other specifications (although I'm not sure those organizations do work in public or would be interested in accepting feedback at this stage). But since the request is coming from the web site and in the context of a rich HTML page, this API is exactly the place to enforce that requests are legitimate and explained to the user.
(for dc2-proposal)
Surfaced as a core discussion topic on the first call (2023-10-04).
Do we expect W3C VCs and mdocs to coexist or one or the other (multi-format)?
Are there others?
As part of PR 57, @samuelgoto wrote:
We don't have to do this all at once, but I'm wondering if something like a requestDigitalCredential may be a better (more specific ) method name in comparison to requestidentity ... again, because this is going to collide with Chrome's implementation of the IdentityCredential which FedCM uses.
We should consider some alternatives or decide if we are ok with requestIdentity()
.
Based on commentary in this issue about the complexity in PeX and it being viewed as too complicated for a presentation request language (I agree):
https://bitbucket.org/openid/connect/issues/1917/moving-to-a-credential-format-specific
The charter should consider the design approach taken in the Credential Handler API (CHAPI) and the Verifiable Presentation Request (VPR) work. Namely, that the design is meant to be protocol and query language agnostic. That is, it is designed to support mdoc query languages, VC query languages, and different protocols for mdoc, VCs, and other market vertical formats:
Demonstration of being query language agnostic:
https://w3c-ccg.github.io/vp-request-spec/#query-and-response-types
Demonstration of being protocol agnostic:
https://w3c-ccg.github.io/vp-request-spec/#interaction-types
While the examples are out of date, the design pattern still holds (and it looks like the discussion in the OpenID community is converging on the same design pattern that was established by VPR many years ago).
Fundamentally, the query languages and protocols for moving the newest types of digital credentials over the Web, NFC, and QR Codes are very new and unsettled. Trying to lock one in at this moment in time, or in a WG over the next 1-2 years is premature. Thus, the safest design approach would be to allow for agility at both the query language layer and the protocol layer.
It would be great to add an CODEOWNERS file that would automatically assign various folks for review. This doesn't not preclude anyone in the community from doing a review (highly encouraged!) but it does mean that at least a few CODEOWNERS must give a ✅ before a pull request is merged.
For CODEOWNERS, we should have small range of experts (too many cooks can spoil the broth).
Inclusions in CODEOWNERS is on a volunteer basis, but requires commitment/responsibility from those folks to do the review (i.e., no good deed goes unpunished, you need to allocate time to do the reviews and those need to be done in a timely manner).
Surfaced as a core discussion topic on the first call (2023-10-04).
Sub topics:
for a verifiable credential example,if a credential format is specified (vc+sd-jwt
in your example), there is no need to provide a JSON.Path to different potential variations of how a claim name can be expressed, because "the path" where to find a claim name will be determined by the credential format and credential type.
Could a structure like below be sufficient?
// Gets a SD-JWT from a VC holder.
const {response} = await navigator.credentials.get({
identity: {
providers: [{
vc: {
nonce: "m5tGxUIsFtLi6pwg",
format: {
vc+sd-jwt: {
alg: ["EdDSA", "ES256"]
}
},
type: "UniversityDegreeCredential",
credentialSubject: {
family_name: {
intent_to_retain: false
},
birth_date: {
mandatory: true,
},
driving_privileges: {
}
}
}
}]
}
});
We need to come up with a registry governance and inclusion criteria.
For inclusion, at a minimum, there should be implementation support, and we talked about having some privacy checks too.
in the reconciliation example, nonce
is duplicated in mdoc
and federated
, and readerPublicKey
are included only in mdoc
. since nonce
and probably readerPublicKey
should be present in vc
too, those parameters should be treated as credential format specific.
So examples for MDocs and FedCM could look like below:
MDocs
// Gets a CBOR with specific fields out of mobile driver's license as an mdoc
const {response} = await navigator.credentials.get({
identity: {
providers: [{
nonce: "gf69kepV+m5tGxUIsFtLi6pwg=",
readerPublicKey: "ftl+VEHPB17r2 ... Nioc9QZ7X/6w...",
mdoc: {
retention: {
days: 90,
},
documentType: "org.iso.18013.5.1.mDL",
requestedElements: [
{ namespace: "org.iso.18013.5.1", name: "document_number" },
{ namespace: "org.iso.18013.5.1", name: "portrait" },
{ namespace: "org.iso.18013.5.1", name: "driving_privileges" },
{ namespace: "org.iso.18013.5.1.aamva", name: "organ_donor" },
],
}
}],
}
});
FedCM
// Gets a JWT from a OIDC provider.
const {response} = await navigator.credentials.get({
identity: {
providers: [{
nonce: "m5tGxUIsFtLi6pwg",
federated: {
configURL: "https://university.edu/students",
clientId: "123"
}
}]
}
});
Surfaced as a core discussion topic on the first call (2023-10-04).
Sub topics:
How can we best support a single UI for selecting from either wallet or federated credentials? Eg. for proving age or organization affiliation.
Split off from #10, no longer a v1-blocking concern for Chrome.
Surfaced as a core discussion topic on the first call (2023-10-04).
Surfaced as a core discussion topic on the first call (2023-10-04).
Need for a common vocabulary / terminology for these discussions (e.g. encoding, formats, schemes, etc)
During the discussions regarding the establishment of a W3C working group, several questions have emerged about integrating verifiable credentials, mdocs, and federated assertions into a unified interface and API surface. To better understand how users are likely to engage with these credentials, it may be useful to frame the discussion in terms of a user story or journey. Doing so could help us achieve greater alignment on this approach.
A mobile driver's license is a clear example of an identity credential that can serve as proof of age. However, there are also situations where a federated identity provider could offer verified age information through an OIDC ID token. Likewise, a request for proof of employment could be fulfilled by either a verifiable credential from a wallet or an assertion from LinkedIn via OIDC.
Developers typically rely on OIDC ID tokens as a familiar assertion format that enjoys broad industry support. In some cases, the trust established with the identity provider may be sufficient to satisfy verifiers. Additionally, the end user may already have a session established with the IdP and prefer not to retrieve a wallet-based credential from their phone. Alternatively, the user may be hesitant to directly share information from their driver's license with a verifier.
For this example, we can imagine a credential picker-style experience that assists the user in presenting the appropriate age or employment proof to the verifier, based on the user's level of comfort and the verifier's requirements.
We should start looking at how to fold in the dictionaries of mDoc request into the spec.
Figure out time / attendees, etc. Will track details here.
The abstract, scope, and (currently missing) Introduction could use a some work once we get more agreement on what we are doing.
@marcoscaceres will work with @TallTed on that.
There are use cases that we have in the W3C Verifiable Credentials Working Group that consist of presenting multiple Verifiable Credentials in a single Verifiable Presentation:
https://www.w3.org/TR/vc-use-cases/#citizenship-by-parentage
Other examples of this pattern include:
In each of these cases, you want to bind these VCs together in the same presentation and doing multiple exchanges creates usability issues.
The current design of the Identity Credentials API is focused on requesting and presenting a single credential, which leads to usability and security concerns when an exchange requires multiple credentials. The group should consider if it is possible to support exchanging multiple credentials in a single exchange as that is what other systems (like CHAPI) are able to do today.
In today's sessions we mentioned that we can look at how FedCM and Passkeys already work.
A third source of inspiration could be https://www.w3.org/TR/secure-payment-confirmation/ which allows the user to pass creditcard / payment details to a web page.
To me, it seems like throwing an exception if the user did not choose to share their mdoc / does not have one on their device is an awkward pattern (especially in Javascript with no exception types). Preferably, a call to credentials.get()
should return an empty response if a user chose not to share an mdoc instead
Psuedocode:
try {
const credential = await credentials.get(...);
if (credential.hasResponse()) {
// handle credential response
}
// do nothing
} catch (e) {
// handle truly unexpected errors
}
Given that we found that "identity credentials" had been squatted by another spec (fedcm maybe?), can we rename this repo to "digital-credentials"?
The proposal talks about "Digital Credential".
One piece of feedback we've heard is that it seems premature to unify different credential types into IdentityCredential
if all they're really sharing is a nonce
and response
and if the IdentityCredentialRequestOptions
is simply a list of unrelated queries.
On the one hand, the main reason we want to unify is so that we can enable credential-picker UIs which list different types of identity credentials all together. This doesn't actually require any unification beyond a common API call (or some other way to group multiple calls into a single UI transaction).
On the other hand, there are actually things we expect to be in common, so perhaps it's worth trying to sketch that out in more detail. In particular, is it useful to think of different layers in the identity-verifying application stack and ask if abstraction can help simplify the design of some components (including the browser itself). Eg. if we add abstraction across selective disclosure, filtering and/or UI presentment of disparate credentials, does that provide sufficient concrete benefit to justify the abstraction?
2023-11-01 meeting: add some text about precedence for multiple elements of the request array.
https://github.com/WICG/identity-credential/blob/main/digital-credentials-2-proposal.md
Hi all,
I have been told a couple of times the fundamental issue this group wants to solve is to find an alternative to custom schemes for invoking wallets. I agree with that objective as custom schemes are less secure than app/universal links and really brittle.
To understand what is needed one needs to take a look on what custom schemes are used for today in this context. In OpenID 4 VC we use custom schemes on the interfaces between verifiers & wallets and issuers & wallets to discover & invoke a wallet in cases where there could be multiple wallets serving the same purpose, typically in a certain ecosystem.
One example will be the EU's eIDAS wallet ecosystem. All the EUDI wallets will provide the same feature set through the same interfaces with the same formats as defined in the regulation and further detailed in ARF and implementing acts. As a verifier, I would like to talk to them without the need to write specific code for every of those wallets. I also need a mechanism to invoke one of the EUDI Wallets installed on the user's device. Custom schemes are today the only way to do that.
So in my opinion, if we want to replace custom schemes, we at least need to provide a mechanism resolving an alias representing a coherent set of wallets into one or more wallets for a certain user and device.
However, all the proposals submitted in this group go much further as they invent new protocols/APIs for requesting and presenting credentials. Why is that? There are protocol for that in the market already, e.g. OpenID 4 VC, RestAPI, DIDComm, CHAPI, ...
I think the first increment (one could call it MVP) should be an API resolving a symbolic name (e.g. "EUDIW") to URLs (or other types of addresses as used by the respective protocols). The benefit for the ecosystem is obvious, existing implementations of the before mentioned protocols could be improved very quickly. I would love if the user had the choice what wallet to use in case multiple wallets are installed on the device, it would be great if the user could install a wallet on demand instead of sending the flow to dev nil if no matching app is installed, user could open wallets with much more confidence as there would be some mechanism (like for app/universal links) to make sure only legit apps could claim a certain alias. Awesome!
A second step could be to define a browser APIs for credentials. However, to come up with a compelling solution, such an API (in my opinion) must cover the following features:
Please be aware the second step might introduce a lot of challenges regarding scalability of the system, security, privacy, and regulation.
The alias approach does not pose any of those problems.
best regards,
Torsten.
It would be nice to have a diagram showing how parts of the model relate to each other.
FedCM and VC examples do not contain readerPublicKey
. Does that mean those responses are not expected to be encrypted? or in the case of FedCM, IdP is supposed to use publicKey of the RP it has obtained during pre-registration..?
There are a few issues that have been marked "pending close" without it being clear why they're being marked as such:
This comes across as arbitrary closing of issues instead of what's probably happening, which is that the issue was discussed on a call and that resulted in some rough consensus on a conclusion like: "Rough consensus is to do X."
Please document why the issue is being closed with a simple conclusion before closing issues. A sentence or two will do in most cases.
Adding
IdentityCredential includes CredentialUserData;
would make it so Identity Credentials may be put into the Credential Store, so they can be stored client side and presented in a "credential chooser" as shown here. Some types may want this, while others may not, so it is worth considering what combinations to permit. Currently this permits none.
Surfaced as a core discussion topic on the first call (2023-10-04).
In this, publicKey
is part of the top-level parameter.
dictionary IdentityRequestProvider {
required DOMString protocol; // See "Protocol Registry" below
required DOMString request;
required DOMString publicKey;
}
Should publicKey
be (opaquely, optionally and per protocol) part of request
instead of IdentityRequestProvider
?
Issue to help coordinate IIW sessions for next week.
/cc @samuelgoto
Surfaced as a core discussion topic on the first call (2023-10-04).
Right now, we had proposed passing around DOM strings for public keys... However, CryptoKey
serves as a nice primitive we already have in the platform from Web Crypto.
I think we can reuse the crypto.subtle.subtle.importKey()
method to get the CryptoKey
, which we can then pass into requestIdentity()
as part of the IdentityRequestOptions
.
One common use case that we've supported in the Credentials CG work, and CHAPI (Credential Handler API), for a while now is the ability to invoke web-based wallets to respond to a request. There is a lot of focus on high-assurance use cases these days (government-issued digital identity tied to hardware security keys on mobile phones and app attestations). This raises the bar for what a "digital wallet" is to a degree that is much higher than a number of other use cases in the VC ecosystem (education VCs, pseudonymous age-over assertions, pseudonymous digital coupons, etc.). It is also possible for a web-based wallet to deliver VCs that are signed by HSM-based keys. For these reasons, CHAPI supports the invocation of both web-based digital wallets and native digital wallets (as evidenced by multiple implementations in the latest JFF Plugfest 3).
Whatever this work ends up becoming, there needs to be a consideration for both web-based wallets and native wallets through the same interface.
CHAPI went through great effort to integrate with both native and web wallets, as do other similar APIs like PaymentRequest. At the moment we've focused here mostly on native wallet integration.
At a minimum I think we need to convince ourselves that a V1 API could be compatibly extended to support web-based wallets.
nonce should be mandatory to be included in the returned Verifiable Presentation and binds it to a transaction. (nonce might not be explicitly mentioned in the W3C vc-data-model, but it is because how to transport VCs is out of scope of that document).
(I included nonce in the example in the Issue #5)
It would be good if we had a template with check that we need to do before we can merge a Pull Request.
This is what we use for Web Manifest:
https://github.com/w3c/manifest/blob/main/.github/PULL_REQUEST_TEMPLATE.md
This is what the WHATWG uses:
https://github.com/whatwg/html/blob/main/PULL_REQUEST_TEMPLATE.md
What's important is that we try to implement (and add some tests for) as much as we can as we spec this out.
The CM spec's Extensions points outlines the following things to do to integrate. Adding as a todo list:
This document provides a generic, high-level API that’s meant to be extended with specific types of credentials that serve specific authentication needs. Doing so is, hopefully, straightforward.
Define appropriate:
[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors). [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) is appropriate for credentials that remain effective forever and can therefore simply be copied out of the credential store
[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors). [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) is appropriate for credentials that need to be re-generated from a credential source.
[[Store]](credential, sameOriginWithAncestors) methods on ExampleCredential's interface object.
Long-running operations, like those in PublicKeyCredential's [[Create]](origin, options, sameOriginWithAncestors) and [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) operations are encouraged to use options.signal to allow developers to abort the operation. See DOM §3.3 Using AbortController and AbortSignal objects in APIs for detailed instructions.
ExampleCredential's [[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) internal method is called with an origin (origin), a CredentialRequestOptions object (options), and a boolean which is true iff the calling context is same-origin with its ancestors. The algorithm returns a set of Credential objects that match the options provided. If no matching Credential objects are available, the returned set will be empty.
Define the value of the ExampleCredential interface object's [[type]] slot:
Define the value of the ExampleCredential interface object's [[discovery]] slot:
Extend (using partial dictionary) CredentialRequestOptions with the options the new credential type needs to respond reasonably to get().
Extend (using partial dictionary) CredentialCreationOptions with the data the new credential type needs to create Credential objects in response to create().
You might also find that new primitives are necessary. For instance, you might want to return many Credential objects rather than just one in some sort of complicated, multi-factor sign-in process. That might be accomplished in a generic fashion by adding a getAll() method to CredentialsContainer which returned a sequence<Credential>
, and defining a reasonable mechanism for dealing with requesting credentials of distinct types.
Surfaced as a core discussion topic on the first call (2023-10-04).
Could you add @hlozi, @hober, & @martijnharing to the repository owners please? Thanks!
It might sound a little like bike-shedding, but I am concerned in seeing API methods called requestIdentity
, as it seems to suggest that what you will get back is the user's complete identity.
If successfully, responsibly deployed, the vast majority of uses of this API should return responses with particular properties or claims or proofs from a credential, but not what the developer might think of as the user's identity.
How can we design an API that makes it clear that sites should ask for only what they need, and not over-ask?
(this is for dc2-proposal but I don't have label permission)
I do not think it is a good idea to use identity credentials for authentication. and I worry that allowing to combine federated
and mdoc
or vc
in the same API like shown in the Reconciliation section fosters exactly that.
In Federation, it is the Issuer (IdP) who authenticates the user (proof of authentication is ID Token, SAML assertion, etc.). For example in the ID Token, iss and sub claims are mandatory and are used to express that iss authenticated the end-user identifier as sub. ID Token does have data about the end-user, but it is only meaningful because it is combined with an authentication proof: "Issuer authenticated the user and is providing some values relying party can use"
Identity Credentials (placeholder term for both mdocs and VCs) are different. There, user authentication is optional and if performed, it is the Wallet (not the credential issuer) that authenticates the user when presenting issuer-signed credentials. So a user identifier assigned by the issuer does not have any meaning for the verifier as it does not bound to authentication - the sub claim in the issuer-signed credential is optional (in fact mdocs do not have an equivalent to a sub claim in the ID Token; in W3C VCs it is used to discover the keys to validate the signature by the user's key). the value of the identity credential is orthogonal to user authentication, "Wallet is proving that a certain issuer-signed credential has not been tampered with and is being presented by a legitimate user". with identity credential presentation, there is a need for a separate proof of authentication - can be Passkey, Self-Issued ID Token, etc.
maybe it is a good idea to have a same API for federation and mdoc/vc, but allowing to combine federation and mdoc/vc in one API call is concerning.
Hope this makes some sense..
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.