Ausstellung von digitalen Ausweisen über die Digital Credentials API in Chrome 155 verfügbar

Veröffentlicht: 23. Oktober 2026

Ab Chrome 155 ist die Ausgabe der Digital Credentials API standardmäßig aktiviert. Sie benötigen also kein Ursprungstest-Token oder Flag mehr, um sie zu verwenden. Die Digital Credentials API ist eine Transportschicht, über die Websites mit Wallet-Apps verbunden werden können, die auf dem Mobilgerät des Nutzers installiert sind. Mit der Ausstellung können Aussteller neue Berechtigungsnachweise (z. B. digitale amtliche Ausweise) direkt in die Wallet-App eines Nutzers einfügen.

Hintergrund

Das Ökosystem für digitale Identitäten besteht aus drei Parteien: Ausstellern, Prüfern (auch vertrauende Seiten genannt) und Inhabern (Wallet-Apps). Nutzer fügen ihrer Wallet-App häufig einen digitalen Ausweis per Push-Bereitstellung hinzu. Dabei startet der Nutzer die Ausstellung auf der Website oder in der App des Ausstellers. Ein Student kann beispielsweise auf der Website seiner Universität (Aussteller) seinen digitalen Studentenausweis in seiner bevorzugten Wallet-App (Inhaber) speichern.

Damit dieses Modell erfolgreich ist, benötigt der Aussteller eine sichere und zuverlässige Möglichkeit, die Wallet-App aufzurufen, um den Ausweis auszustellen. Vor dieser API musste jeder Aussteller eine eigene Methode zum Öffnen der Wallet-Apps entwickeln, mit denen er zusammenarbeitete, in der Regel mit benutzerdefinierten URI-Schemas. Aussteller mussten für jede Wallet-App einen separaten Mechanismus verwalten und Nutzer hatten keine einheitliche Möglichkeit, eine Wallet-App auszuwählen.

So funktioniert die Ausstellung digitaler Berechtigungsnachweise

Um diesen Prozess zu optimieren, unterstützt Chrome die Ausstellung mit der W3C Digital Credentials API. Dies ergänzt die Präsentationsfunktionen (Freigabe angeforderter, ausgewählter Daten aus einem digitalen Berechtigungsnachweis für einen Prüfer), die in Chrome 141 eingeführt wurden. Wenn eine Ausstellerwebsite navigator.credentials.create() mit einem digital-Mitglied aufruft, das eine Ausstellungsanfrage enthält, leitet Chrome die Anfrage an das Betriebssystem weiter (unter Android an den Credential Manager). Das Betriebssystem zeigt dann eine eigene Oberfläche an, auf der der Nutzer eine Wallet-App auswählt. Die API funktioniert mit branchenüblichen Protokollen wie OpenID for Verifiable Credential Issuance (OpenID4VCI). Die Ausstellung unterstützt zwei Abläufe: einen Ablauf auf demselben Gerät unter Android und einen geräteübergreifenden Ablauf, der auf einem Computer beginnt und auf einem Android-Gerät endet.

Ablauf auf demselben Gerät unter Android

Unter Android leitet Chrome die Ausstellungsanfrage an den Credential Manager von Android weiter, der eine Liste der kompatiblen Wallet-Apps auf dem Gerät anzeigt. Der Nutzer wählt ein Wallet aus und stimmt dem Hinzufügen des Berechtigungsnachweises zu. Die Wallet-App ruft dann den Berechtigungsnachweis vom Aussteller über das Ausstellungsprotokoll ab, z. B. OpenID4VCI.

Geräteübergreifender Ablauf auf dem Computer

Auf dem Computer wird in Chrome ein QR‑Code angezeigt. Der Nutzer scannt den Code mit seinem Android-Gerät und schließt den Vorgang auf diesem Gerät ab, wie im vorherigen Abschnitt beschrieben. Die Geräte verwenden Bluetooth, um zu bestätigen, dass sie sich in der Nähe voneinander befinden. Chrome fordert den Nutzer daher auf, Bluetooth zu aktivieren, falls es deaktiviert ist. Chrome verwendet denselben geräteübergreifenden Mechanismus für die Präsentation der Digital Credentials API.

Ausstellung mithilfe der API implementieren

Rufen Sie navigator.credentials.create() auf und übergeben Sie Ihre Ausstellungsanfragen in einem digital-Mitglied, um den Ausstellungsablauf zu starten. Führen Sie diesen Aufruf über einen Klick-Handler oder einen anderen Nutzergesten-Handler aus, da für den Aufruf eine vorübergehende Nutzeraktivierung erforderlich ist. Im folgenden Beispiel wird ein OpenID4VCI-Anmeldedatenangebot mit dem vorautorisierten Codeablauf verwendet:

// 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 diesem Beispiel stehen showAlternativeIssuanceFlow() und showIssuanceStatus() für Ihre eigene Anwendungslogik.

Wenn Sie create() über einen ursprungsübergreifenden iFrame aufrufen möchten, muss die einbettende Seite die Berechtigungsrichtlinienfunktion digital-credentials-create zulassen. Andernfalls wird der Aufruf mit einem NotAllowedError abgelehnt:

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

Änderungen seit dem Ursprungstest

Die API-Methoden und -Parameter haben sich seit dem Ursprungstest nicht geändert. Die folgenden Änderungen wurden jedoch zwischen Chrome 143 und Chrome 155 eingeführt. Einige davon erfordern möglicherweise eine Aktualisierung Ihres Codes. In der folgenden Tabelle sind die Änderungen zusammengefasst. In den Abschnitten danach werden die einzelnen Änderungen erläutert.

Region Ursprungstest (Chrome 143) Chrome 155
Verfügbarkeit Ursprungstest-Token oder das Flag chrome://flags/#web-identity-digital-credentials-creation Standardmäßig aktiviert
Nutzeraktivierung Erforderlich, aber nicht verbraucht Erforderlich für jeden create()-Aufruf und von diesem genutzt (Chrome 146)
Fehler bei der Stornierung NetworkError NotAllowedError (Chrome 148)
Protokollkennungen Chrome übergibt alle Kennungen an das Betriebssystem Nicht erkannte Kennungen lösen eine Einstellungswarnung aus (Chrome 151)
Intransparente Ursprünge Zulässig Mit NotAllowedError blockiert (Chrome 151)
Automatisierte Tests Kein integrierter Support Virtuelle Wallet im Chrome-Entwicklertools-Protokoll (Chrome 152)

Nutzeraktivierung wird verbraucht

Ab Chrome 146 wird bei einem create()-Aufruf mit einem digital-Mitglied die vorübergehende Nutzeraktivierung verbraucht, wie in der Spezifikation gefordert. Während des Ursprungstests hat Chrome die Nutzeraktivierung geprüft, aber nicht genutzt.

Daher ist für jeden create()-Aufruf eine eigene Nutzergeste erforderlich, z. B. ein Klick auf eine Schaltfläche. Ohne Nutzeraktivierung wird das Promise mit einem NotAllowedError abgelehnt. Nach dem Aufruf können window.open() und andere APIs, die eine Nutzeraktivierung erfordern, nicht dieselbe Geste verwenden.

Stornierungsablehnungen mit NotAllowedError

Ab Chrome 148 wird das Promise, das create() zurückgibt, mit einem NotAllowedError abgelehnt, wenn der Nutzer den Vorgang abbricht, z. B. indem er die Wallet-Auswahl unter Android schließt oder das QR-Code-Dialogfeld auf dem Computer schließt. Das Promise wird auch mit einem NotAllowedError abgelehnt, wenn keine Wallet-App die Anfrage verarbeiten kann. Während des Ursprungstests wurden diese Fälle mit NetworkError abgelehnt.

Wenn Ihr Code nach einem NetworkError sucht, um einen Abbruch zu erkennen, aktualisieren Sie ihn so, dass er stattdessen nach einem NotAllowedError sucht.

Unbekannte Protokollkennungen lösen eine Warnung aus

In der Spezifikation wird eine einzelne Kennung für das Ausstellungsprotokoll, openid4vci-v1, für OpenID4VCI 1.0 definiert. Chrome 155 erkennt openid4vci-v1 und auch openid4vci. Da openid4vci nicht Teil der Spezifikation ist, empfehlen wir die Verwendung von openid4vci-v1.

Chrome leitet Anfragen mit einer beliebigen Protokollkennung an die Plattform weiter. Ab Chrome 151 wird in den Entwicklertools jedoch eine Einstellungswarnung angezeigt, wenn eine Seite create() mit einer nicht erkannten Protokoll-ID aufruft. Chrome beabsichtigt, Anfragen mit unbekannten Protokollkennungen zu blockieren. Den Status finden Sie im Eintrag Spezifischere Protokollfilterung in der Digital Credential API.

Aktivieren Sie chrome://flags/#enable-experimental-web-platform-features, um dieses Verhalten zu testen. Wenn dieses Flag aktiviert ist, ignoriert create() Anfragen mit nicht erkannten Protokollkennungen und lehnt sie mit TypeError ab, wenn keine Anfragen mehr vorhanden sind. Außerdem gibt DigitalCredential.userAgentAllowsProtocol() true nur für erkannte Protokolle zurück. Ohne das Flag wird nur geprüft, ob die Kennung wohlgeformt ist. Verlassen Sie sich also nicht allein auf userAgentAllowsProtocol(), um Funktionen zu erkennen. Behandeln Sie NotSupportedError wie im Beispiel gezeigt.

Nicht transparente Ursprünge werden blockiert

Ab Chrome 151 wird create() mit einem NotAllowedError abgelehnt, wenn ein Dokument mit einem undurchsichtigen Ursprung es aufruft, z. B. ein iFrame in einer Sandbox ohne das allow-same-origin-Token. Während des Ursprungstests hat Chrome diese Aufrufe nicht blockiert.

Mit einem virtuellen Wallet testen

Ab Chrome 152 können Sie den Ausgabeprozess ohne Android-Gerät oder Wallet-App testen. Der experimentelle Befehl DigitalCredentials.setVirtualWalletBehavior im Chrome-Entwicklertools-Protokoll (CDP) implementiert die virtuelle Wallet, die in der Spezifikation für automatisierte Tests definiert ist. Das virtuelle Wallet kann mit den von Ihnen bereitgestellten Daten antworten, Anfragen ablehnen, als hätte der Nutzer den Vorgang abgebrochen, oder Anfragen ausstehend lassen, um Zeitüberschreitungen und Abbrüche zu testen.

Im folgenden Puppeteer-Test wird die virtuelle Wallet so konfiguriert, dass sie auf openid4vci-v1-Anfragen reagiert. Anschließend wird auf den Button geklickt, der die Ausstellung startet:

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');

Branchenweite Übernahme

Wir sehen, dass die Digital Credentials API für die Ausstellung von digitalen Ausweisen genutzt wird. Das deutsche Finanzinstitut Sparkasse verwendet beispielsweise die Digital Credentials API, um Kontoinhabern das Speichern von verifizierten Altersnachweisen in Google Wallet zu ermöglichen. Kontoinhaber können diese Anmeldedaten dann verwenden, um ihr Alter online und vor Ort zu bestätigen.

Jetzt ausprobieren

Bevor Sie die Ausstellung der Digital Credentials API testen, benötigen Sie Folgendes:

  • Führen Sie ein Update auf Chrome 155 oder höher durch.
  • Installieren Sie eine unterstützte Wallet-App auf Ihrem Android-Gerät, z. B. die Demo-App CMWallet.
  • Bluetooth muss auf beiden Geräten aktiviert sein (nur bei geräteübergreifendem Ablauf).

So testen Sie den geräteübergreifenden Ablauf:

  1. Öffnen Sie auf Ihrem Computer die Demo-Website des Ausstellers.
  2. Klicken Sie auf Hinzufügen.
  3. Scanne den QR‑Code mit deinem Android-Gerät und folge der Anleitung auf dem Display.

Wenn du den Ablauf auf demselben Gerät testen möchtest, öffne die Demo-Ausstellerwebsite in Chrome auf deinem Android-Gerät.

Entwicklerressourcen

Wenn Sie die Ausstellung von digitalen Ausweisen über die Digital Credentials API in Ihre Website einbinden möchten, verwenden Sie die folgenden Ressourcen:

Feedback geben

Wenn Sie einen Fehler melden oder eine Funktion anfragen möchten, erstellen Sie ein Problem im Chromium-Bugtracker.