Penerbitan Digital Credentials API tersedia di Chrome 155

Dipublikasikan: 23 Oktober 2026

Di Chrome 155 dan yang lebih baru, penerbitan Digital Credentials API diaktifkan secara default, jadi Anda tidak lagi memerlukan token uji coba origin atau flag untuk menggunakannya. Digital Credentials API adalah lapisan transpor yang memungkinkan situs terhubung ke aplikasi dompet yang diinstal di perangkat seluler pengguna. Dengan penerbitan, penerbit dapat menambahkan kredensial baru (seperti tanda pengenal digital) langsung ke aplikasi dompet pengguna.

Latar belakang

Ekosistem identitas digital memiliki tiga pihak: penerbit, pemverifikasi (juga disebut pihak tepercaya), dan pemegang (aplikasi dompet). Pengguna sering menambahkan tanda pengenal digital ke aplikasi dompet mereka melalui penyediaan push, tempat pengguna memulai penerbitan dari situs atau aplikasi penerbit. Misalnya, seorang mahasiswa di situs universitasnya (penerbit) dapat menyimpan tanda pengenal mahasiswa digitalnya ke aplikasi dompet pilihannya (pemegang).

Agar model ini berhasil, penerbit memerlukan cara yang aman dan andal untuk memanggil aplikasi dompet guna menerbitkan ID. Sebelum API ini, setiap penerbit harus membuat cara sendiri untuk membuka aplikasi dompet yang bermitra dengannya, biasanya dengan skema URI kustom. Penerbit harus mengelola mekanisme terpisah untuk setiap aplikasi dompet, dan pengguna tidak memiliki cara yang konsisten untuk memilih aplikasi dompet.

Cara kerja penerbitan kredensial digital

Untuk menyederhanakan proses ini, Chrome mendukung penerbitan dengan Digital Credentials API W3C. Hal ini menambah kemampuan presentasi (membagikan data selektif yang diminta dari kredensial digital dengan pemverifikasi), yang dikirimkan di Chrome 141. Saat situs penerbit memanggil navigator.credentials.create() dengan anggota digital yang berisi permintaan penerbitan, Chrome akan meneruskan permintaan tersebut ke sistem operasi (di Android, Credential Manager). Sistem operasi kemudian menampilkan antarmukanya sendiri tempat pengguna memilih aplikasi dompet. API ini berfungsi dengan protokol standar industri seperti OpenID for Verifiable Credential Issuance (OpenID4VCI). Penerbitan mendukung dua alur: alur di perangkat yang sama di Android, dan alur lintas perangkat yang dimulai di desktop dan selesai di perangkat Android.

Alur di perangkat yang sama di Android

Di Android, Chrome meneruskan permintaan penerbitan ke Pengelola Kredensial Android, yang menampilkan daftar aplikasi dompet yang kompatibel di perangkat. Pengguna memilih wallet dan mengizinkan penambahan kredensial. Kemudian, aplikasi dompet akan mendapatkan kredensial dari penerbit menggunakan protokol penerbitan, seperti OpenID4VCI.

Alur lintas perangkat di desktop

Di desktop, Chrome menampilkan kode QR. Pengguna memindai kode dengan perangkat Android mereka dan menyelesaikan alur di perangkat tersebut, seperti yang dijelaskan di bagian sebelumnya. Perangkat menggunakan Bluetooth untuk mengonfirmasi bahwa perangkat tersebut saling berdekatan, sehingga Chrome meminta pengguna untuk mengaktifkan Bluetooth jika nonaktif. Chrome menggunakan mekanisme lintas perangkat yang sama untuk presentasi Digital Credentials API.

Menerapkan penerbitan menggunakan API

Untuk memulai alur penerbitan, panggil navigator.credentials.create() dan teruskan permintaan penerbitan Anda di dalam anggota digital. Lakukan panggilan ini dari pengendali klik atau pengendali gestur pengguna lainnya, karena panggilan memerlukan aktivasi pengguna sementara. Contoh berikut menggunakan penawaran kredensial OpenID4VCI dengan alur kode yang telah diizinkan:

// 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);
});

Dalam contoh ini, showAlternativeIssuanceFlow() dan showIssuanceStatus() mewakili logika aplikasi Anda sendiri.

Untuk memanggil create() dari iframe lintas origin, halaman penyematan harus mengizinkan fitur kebijakan izin digital-credentials-create. Jika tidak, panggilan akan ditolak dengan NotAllowedError:

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

Perubahan sejak uji coba origin

Metode dan parameter API tidak berubah sejak uji coba origin. Namun, perubahan berikut dikirimkan antara Chrome 143 dan Chrome 155, dan beberapa di antaranya mungkin mengharuskan Anda mengupdate kode. Tabel berikut merangkum perubahan, dan bagian setelahnya menjelaskan setiap perubahan.

Area Uji coba origin (Chrome 143) Chrome 155
Ketersediaan Token uji coba origin atau flag chrome://flags/#web-identity-digital-credentials-creation Diaktifkan secara default
Aktivasi pengguna Diperlukan, tetapi tidak digunakan Diperlukan dan digunakan oleh setiap panggilan create() (Chrome 146)
Error pembatalan NetworkError NotAllowedError (Chrome 148)
ID protokol Chrome meneruskan ID apa pun ke sistem operasi ID yang tidak dikenali akan memicu peringatan penghentian penggunaan (Chrome 151)
Origin buram Diizinkan Diblokir dengan NotAllowedError (Chrome 151)
Pengujian otomatis Tidak ada dukungan bawaan Dompet virtual di Chrome DevTools Protocol (Chrome 152)

Aktivasi pengguna digunakan

Mulai Chrome 146, panggilan create() dengan anggota digital akan menggunakan aktivasi pengguna sementara, seperti yang diwajibkan oleh spesifikasi. Selama uji coba origin, Chrome memeriksa aktivasi pengguna, tetapi tidak menggunakannya.

Oleh karena itu, setiap panggilan create() memerlukan gestur pengguna sendiri, misalnya, klik tombol. Tanpa aktivasi pengguna, promise akan ditolak dengan NotAllowedError. Setelah panggilan, window.open() dan API lain yang memerlukan aktivasi pengguna tidak dapat menggunakan gestur yang sama.

Penolakan pembatalan dengan NotAllowedError

Mulai Chrome 148, promise yang ditampilkan create() akan ditolak dengan NotAllowedError saat pengguna membatalkan alur, misalnya, dengan menutup pemilih dompet di Android atau menutup dialog kode QR di desktop. Promise juga menolak dengan NotAllowedError jika tidak ada aplikasi dompet yang dapat menangani permintaan. Selama uji coba origin, kasus ini ditolak dengan NetworkError.

Jika kode Anda memeriksa NetworkError untuk mendeteksi pembatalan, perbarui kode tersebut untuk memeriksa NotAllowedError.

ID protokol yang tidak dikenal akan memicu peringatan

Spesifikasi ini menentukan satu ID protokol penerbitan, openid4vci-v1, untuk OpenID4VCI 1.0. Chrome 155 mengenali openid4vci-v1, dan juga openid4vci. Karena openid4vci bukan bagian dari spesifikasi, sebaiknya gunakan openid4vci-v1.

Chrome meneruskan permintaan dengan ID protokol apa pun ke platform. Namun, mulai Chrome 151, DevTools menampilkan peringatan penghentian penggunaan saat halaman memanggil create() dengan ID protokol yang tidak dikenali. Chrome bermaksud memblokir permintaan dengan ID protokol yang tidak dikenal. Untuk mengetahui statusnya, lihat entri Pemfilteran protokol yang lebih spesifik di Digital Credential API.

Untuk menguji perilaku ini, aktifkan chrome://flags/#enable-experimental-web-platform-features. Jika flag ini diaktifkan, create() akan mengabaikan permintaan dengan ID protokol yang tidak dikenali dan menolak dengan TypeError jika tidak ada permintaan yang tersisa. Selain itu, DigitalCredential.userAgentAllowsProtocol() menampilkan true hanya untuk protokol yang dikenali. Tanpa flag, alat ini hanya memeriksa apakah ID memiliki format yang benar. Jadi, jangan hanya mengandalkan userAgentAllowsProtocol() untuk deteksi fitur. Tangani NotSupportedError seperti yang ditunjukkan dalam contoh.

Origin opaque diblokir

Mulai Chrome 151, create() akan menolak dengan NotAllowedError jika dokumen dengan origin buram memanggilnya, seperti iframe dengan sandbox tanpa token allow-same-origin. Selama uji coba origin, Chrome tidak memblokir panggilan ini.

Menguji dengan dompet virtual

Mulai Chrome 152, Anda dapat menguji alur penerbitan tanpa perangkat Android atau aplikasi dompet. Perintah DigitalCredentials.setVirtualWalletBehavior eksperimental di Chrome DevTools Protocol (CDP) mengimplementasikan dompet virtual yang ditentukan spesifikasi untuk pengujian otomatis. Dompet virtual dapat merespons dengan data yang Anda berikan, menolak permintaan seolah-olah pengguna membatalkan alur, atau membiarkan permintaan tertunda untuk menguji waktu tunggu dan pembatalan.

Pengujian Puppeteer berikut menetapkan dompet virtual untuk merespons permintaan openid4vci-v1, lalu mengklik tombol yang memulai penerbitan:

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

Adopsi industri

Kami melihat adopsi penerbitan Digital Credentials API. Misalnya, lembaga keuangan Jerman, Sparkasse, menggunakan Digital Credentials API untuk mengizinkan pemegang akun menyimpan kredensial usia terverifikasi ke Google Wallet. Pemegang akun kemudian dapat menggunakan kredensial ini untuk memverifikasi usia mereka secara online dan secara langsung.

Cobalah

Sebelum menguji penerbitan Digital Credentials API, pastikan Anda memiliki hal berikut:

  • Update ke Chrome 155 atau yang lebih baru.
  • Instal aplikasi dompet yang didukung di perangkat Android Anda, misalnya, demo CMWallet.
  • Bluetooth diaktifkan di kedua perangkat (khusus alur lintas perangkat).

Untuk menguji alur lintas perangkat:

  1. Di komputer, buka situs penerbit demo.
  2. Klik tombol Add.
  3. Pindai kode QR dengan perangkat Android Anda dan ikuti petunjuk di layar.

Untuk menguji alur perangkat yang sama, buka situs penerbit demo di Chrome pada perangkat Android Anda.

Resource developer

Untuk mulai mengintegrasikan penerbitan Digital Credentials API ke situs Anda, gunakan referensi berikut:

Beri masukan

Untuk melaporkan bug atau meminta fitur, laporkan masalah di Pelacak bug Chromium.