Uitgifte van de Digital Credentials API wordt geleverd in Chrome 155

Gepubliceerd: 23 oktober 2026

In Chrome 155 en hoger staat de uitgifte van de Digital Credentials API standaard aan. Je hebt dus geen origin trial-token of vlag meer nodig om deze te gebruiken. De Digital Credentials API is een transportlaag waarmee websites verbinding kunnen maken met wallet-apps die op het mobiele apparaat van de gebruiker zijn geïnstalleerd. Met uitgifte kunnen kaartuitgevers nieuwe inloggegevens (zoals digitale ID's) rechtstreeks toevoegen aan de Wallet-app van een gebruiker.

Achtergrond

Het ecosysteem voor digitale identiteit bestaat uit 3 partijen: uitgevers, verificateurs (ook wel vertrouwende partijen genoemd) en houders (wallet-apps). Gebruikers voegen vaak een digitale ID toe aan hun Wallet-app via pushregistratie, waarbij de gebruiker de uitgifte start vanaf de website of app van de uitgever. Een student op de website van de universiteit (uitgever) kan bijvoorbeeld de digitale studentenkaart opslaan in de gewenste Wallet-app (houder).

Voor dit model heeft de uitgever een beveiligde en betrouwbare manier nodig om de Wallet-app aan te roepen om de ID uit te geven. Vóór deze API moest elke kaartuitgever een eigen manier ontwikkelen om de wallet-apps te openen waarmee deze samenwerkte, meestal met aangepaste URI-schema's. Uitgevers moesten voor elke wallet-app een afzonderlijk mechanisme onderhouden en gebruikers hadden geen consistente manier om een wallet-app te kiezen.

Hoe de uitgifte van digitale inloggegevens werkt

Chrome ondersteunt uitgifte met de W3C Digital Credentials API om dit proces te stroomlijnen. Dit is een aanvulling op de presentatiemogelijkheden (gevraagde, selectieve gegevens van een digitale inloggegevens delen met een verificateur), die zijn geïntroduceerd in Chrome 141. Als een website van een kaartuitgever navigator.credentials.create() aanroept met een digital-lid dat een uitgifteverzoek bevat, geeft Chrome het verzoek door aan het besturingssysteem (op Android is dit Manager Inloggegevens). Het besturingssysteem toont dan de eigen interface waarin de gebruiker een wallet-app kiest. De API werkt met protocollen die de branchenorm zijn, zoals OpenID for Verifiable Credential Issuance (OpenID4VCI). Uitgifte ondersteunt 2 processen: een proces op hetzelfde apparaat op Android en een proces op meerdere apparaten dat begint op een desktop en eindigt op een Android-apparaat.

Proces op hetzelfde apparaat op Android

Op Android geeft Chrome het uitgifteverzoek door aan de Android Manager Inloggegevens, die een lijst met compatibele wallet-apps op het apparaat toont. De gebruiker selecteert een wallet en geeft toestemming om de inloggegevens toe te voegen. De Wallet-app krijgt de inloggegevens dan van de uitgever via het uitgifteprotocol, zoals OpenID4VCI.

Proces op meerdere apparaten op desktop

Op een desktop toont Chrome een QR-code. De gebruiker scant de code met het Android-apparaat en rondt het proces af op dat apparaat, zoals beschreven in het vorige gedeelte. De apparaten gebruiken bluetooth om te bevestigen dat ze zich dicht bij elkaar bevinden. Chrome vraagt de gebruiker dus om bluetooth aan te zetten als deze functie uitstaat. Chrome gebruikt hetzelfde mechanisme voor meerdere apparaten voor de presentatie van de Digital Credentials API.

Uitgifte implementeren met de API

Als u het uitgifteproces wilt starten, roept u navigator.credentials.create() aan en geeft u uw uitgifteverzoeken door binnen een digital-lid. Voer deze aanroep uit vanuit een klikhandler of een andere handler voor gebruikersgebaren, omdat de aanroep tijdelijke gebruikersactivering vereist. In het volgende voorbeeld wordt een OpenID4VCI-aanbieding voor inloggegevens gebruikt met het proces voor vooraf geautoriseerde codes:

// Call this function from a user gesture handler, for example, a button's
// click handler. The pre-authorized code is a short-lived, single-use code
// that your server generates for the signed-in user.
async function issueDigitalCredential(preAuthorizedCode) {
  // Check for Digital Credentials API and protocol support.
  if (!window.DigitalCredential ||
      !DigitalCredential.userAgentAllowsProtocol('openid4vci-v1')) {
    // Provide an alternative issuance method.
    showAlternativeIssuanceFlow();
    return;
  }

  // Construct a credential offer according to the OpenID4VCI
  // specification. This example uses the format that the
  // demo CMWallet supports.
  const credentialOffer = {
    credential_issuer: 'https://issuer.example',
    credential_configuration_ids: ['org.iso.18013.5.1.mDL'],
    grants: {
      'urn:ietf:params:oauth:grant-type:pre-authorized_code': {
        'pre-authorized_code': preAuthorizedCode
      }
    },
    // Metadata that the wallet uses to request and display the credential.
    credential_issuer_metadata: {
      credential_issuer: 'https://issuer.example',
      credential_endpoint: 'https://issuer.example/openid4vci/credential',
      nonce_endpoint: 'https://issuer.example/openid4vci/nonce',
      credential_configurations_supported: {
        'org.iso.18013.5.1.mDL': {
          format: 'mso_mdoc',
          doctype: 'org.iso.18013.5.1.mDL',
          // Bind the credential to a key that the wallet generates.
          cryptographic_binding_methods_supported: ['cose_key'],
          proof_types_supported: {
            jwt: { proof_signing_alg_values_supported: ['ES256'] }
          },
          credential_metadata: {
            display: [{ name: 'Mobile driving license', locale: 'en-US' }],
            // The claims that this credential contains. For a full list of
            // standard mDL claims, see the ISO/IEC 18013-5 specification.
            claims: [{
              path: ['org.iso.18013.5.1', 'family_name'],
              display: [{ name: 'Family name', locale: 'en-US' }]
            }
            // ... Add any other claims for your credential here.
            ]
          }
        }
      }
    },
    // Metadata of the authorization server that issues access tokens.
    authorization_server_metadata: {
      issuer: 'https://issuer.example',
      token_endpoint: 'https://issuer.example/openid4vci/token'
    }
  };

  try {
    const credential = await navigator.credentials.create({
      digital: {
        requests: [{
          // The protocol identifier for OpenID4VCI 1.0.
          protocol: 'openid4vci-v1',
          // Pass the offer as an object, not as a JSON string.
          data: credentialOffer
        }]
      }
    });

    // The wallet handled the request. credential.data is an object that
    // contains the wallet's protocol-specific response. It is not the issued
    // credential, and it does not necessarily mean that issuance is complete.
    // Your server knows when the wallet retrieves the credential from your
    // credential endpoint.
    // Implement your custom logic here as needed.
    showIssuanceStatus(credential);
  } catch (error) {
    switch (error.name) {
      case 'NotAllowedError':
        // The user canceled the flow, no wallet can handle the request, or
        // the call does not have transient user activation.
        break;
      case 'NotSupportedError':
        // The browser does not support Digital Credentials API issuance.
        // Fall back to your custom alternative flow logic.
        showAlternativeIssuanceFlow();
        break;
      case 'TypeError':
        // The request is malformed, for example, data is not an object.
        console.error('Invalid issuance request:', error);
        break;
      default:
        // For example, AbortError or NetworkError.
        console.error('Credential issuance failed:', error);
    }
  }
}

const addButton = document.querySelector('#add-to-wallet');
addButton.addEventListener('click', () => {
  // Your server adds a pre-authorized code for the signed-in user
  // to the button's data-pre-authorized-code attribute.
  issueDigitalCredential(addButton.dataset.preAuthorizedCode);
});

In dit voorbeeld staan showAlternativeIssuanceFlow() en showIssuanceStatus() voor je eigen app-logica.

Als je create() wilt aanroepen vanuit een cross-origin iframe, moet de insluitende pagina de functie voor het rechtenbeleid digital-credentials-create toestaan. Anders wordt de aanroep geweigerd met een NotAllowedError:

<iframe src="https://issuer.example" allow="digital-credentials-create">
</iframe>

Wijzigingen sinds de origin trial

De API-methoden en -parameters zijn niet gewijzigd sinds de origin trial. De volgende wijzigingen zijn wel doorgevoerd tussen Chrome 143 en Chrome 155. Voor sommige wijzigingen moet je je code updaten. In de volgende tabel staan de wijzigingen samengevat. In de gedeelten daarna wordt elke wijziging uitgelegd.

Gebied Origin trial (Chrome 143) Chrome 155
Beschikbaarheid Origin Trial-token of de vlag chrome://flags/#web-identity-digital-credentials-creation Standaard ingeschakeld
Gebruikersactivering Vereist, maar niet verbruikt Vereist en verbruikt door elke create()-aanroep (Chrome 146)
Annuleringsfouten NetworkError NotAllowedError (Chrome 148)
Protocol-ID's Chrome geeft een ID door aan het besturingssysteem Niet-herkende ID's activeren een beëindigingswaarschuwing (Chrome 151)
Ondoorzichtige oorsprongen Toegestaan Geblokkeerd met NotAllowedError (Chrome 151)
Geautomatiseerde tests Geen ingebouwde ondersteuning Virtuele portemonnee in het Chrome DevTools-protocol (Chrome 152)

Gebruikersactivering is verbruikt

Vanaf Chrome 146 verbruikt een create()-aanroep met een digital-lid de tijdelijke gebruikersactivering, zoals vereist door de specificatie. Tijdens de origin trial controleerde Chrome op gebruikersactivering, maar gebruikte deze niet.

Daarom heeft elke create()-aanroep een eigen gebruikersactivatie nodig, bijvoorbeeld een klik op een knop. Zonder gebruikersactivering wordt de promise afgewezen met een NotAllowedError. Na het gesprek kunnen window.open() en andere API's waarvoor gebruikersactivering is vereist, hetzelfde gebaar niet gebruiken.

Annulering afgewezen met NotAllowedError

Vanaf Chrome 148 wordt de promise die create() retourneert, afgewezen met een NotAllowedError als de gebruiker het proces annuleert, bijvoorbeeld door de portemonneekiezer op Android te sluiten of het dialoogvenster met de QR-code op de desktop te sluiten. De promise wordt ook afgewezen met een NotAllowedError als geen enkele Wallet-app het verzoek kan verwerken. Tijdens de origin trial werden deze gevallen afgewezen met een NetworkError.

Als je code een NetworkError controleert om een opzegging te detecteren, update je deze om in plaats daarvan een NotAllowedError te controleren.

Niet-herkende protocol-ID's activeren een waarschuwing

De specificatie definieert één ID voor het uitgifteprotocol, openid4vci-v1, voor OpenID4VCI 1.0. Chrome 155 herkent openid4vci-v1 en ook openid4vci. Omdat openid4vci geen deel uitmaakt van de specificatie, raden we je aan openid4vci-v1 te gebruiken.

Chrome geeft verzoeken met een protocol-ID door aan het platform. Vanaf Chrome 151 toont DevTools een beëindigingswaarschuwing als een pagina create() aanroept met een niet-herkende protocol-ID. Chrome is van plan verzoeken met niet-herkende protocol-ID's te blokkeren. Ga voor de status naar het item Specifiekere protocolfiltering in de Digital Credential API.

Zet chrome://flags/#enable-experimental-web-platform-features aan om dit gedrag te testen. Als deze markering aanstaat, negeert create() verzoeken met niet-herkende protocol-ID's en weigert het verzoeken met een TypeError als er geen verzoeken overblijven. Ook retourneert DigitalCredential.userAgentAllowsProtocol() true alleen voor herkende protocollen. Zonder de markering wordt alleen gecontroleerd of de ID de juiste indeling heeft. Vertrouw dus niet alleen op userAgentAllowsProtocol() voor functiedetectie. Verwerk NotSupportedError zoals in het voorbeeld.

Ondoorzichtige oorsprongen worden geblokkeerd

Vanaf Chrome 151 wordt create() geweigerd met een NotAllowedError als een document met een ondoorzichtige oorsprong deze aanroept, zoals een iframe in een sandbox zonder de allow-same-origin-token. Tijdens de origin trial blokkeerde Chrome deze aanroepen niet.

Testen met een virtuele portemonnee

Vanaf Chrome 152 kun je je uitgifteproces testen zonder Android-apparaat of een wallet-app. De experimentele opdracht DigitalCredentials.setVirtualWalletBehavior in het Chrome DevTools Protocol (CDP) implementeert de virtuele wallet die de specificatie definieert voor geautomatiseerde tests. De virtuele portemonnee kan reageren met de gegevens die u verstrekt, verzoeken weigeren alsof de gebruiker het proces heeft geannuleerd of verzoeken in behandeling laten om time-outs en annuleringen te testen.

De volgende Puppeteer-test stelt de virtuele wallet in om te reageren op openid4vci-v1-verzoeken en klikt daarna op de knop waarmee de uitgifte wordt gestart:

const client = await page.createCDPSession();
await client.send('DigitalCredentials.setVirtualWalletBehavior', {
  action: 'respond',
  protocol: 'openid4vci-v1',
  response: {}
});

// Clicking the button provides the user activation that create() requires.
await page.click('#add-to-wallet');

Gebruik in de branche

We zien dat de Digital Credentials API wordt gebruikt voor de uitgifte van digitale inloggegevens. De Duitse financiële instelling Sparkasse gebruikt de Digital Credentials API bijvoorbeeld om accounthouders geverifieerde leeftijdsgegevens te laten opslaan in Google Wallet. Accounthouders kunnen deze inloggegevens dan gebruiken om hun leeftijd online en persoonlijk te laten verifiëren.

Uitproberen

Voordat je de uitgifte van de Digital Credentials API test, zorg je dat je het volgende hebt:

  • Update naar Chrome 155 of hoger.
  • Installeer een ondersteunde wallet-app op uw Android-apparaat, bijvoorbeeld de demo CMWallet.
  • Bluetooth staat aan voor beide apparaten (alleen voor het proces voor meerdere apparaten).

Zo test je het proces voor meerdere apparaten:

  1. Open de demosite van de kaartuitgever op uw computer.
  2. Klik op de knop Toevoegen.
  3. Scan de QR-code met je Android-apparaat en volg de instructies op het scherm.

Als u het proces op hetzelfde apparaat wilt testen, opent u de demosites van de kaartuitgever in Chrome op uw Android-apparaat.

Bronnen voor ontwikkelaars

Gebruik de volgende bronnen om de uitgifte van de Digital Credentials API te integreren in je website:

Je feedback delen

Als je een bug wilt melden of een functie wilt aanvragen, dien je een probleem in via de Chromium-bugtracker.