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:
- Di komputer, buka situs penerbit demo.
- Klik tombol Add.
- 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:
- Baca panduan developer dari Web Identity & Credentials Adoption Community Group W3C.
- Baca spesifikasi Kredensial Digital W3C.
- Baca spesifikasi OpenID for Verifiable Credential Issuance 1.0.
- Pelajari kode sumber demo CMWallet, aplikasi dompet demo open source untuk Android.
- Pelajari cara aplikasi dompet Android menangani permintaan penerbitan dari Credential Manager.
- Coba situs penerbit demo dengan CMWallet demo yang diinstal di perangkat Android Anda.
- Pelajari demo konstruktor permintaan Kredensial Digital untuk melihat tampilan payload permintaan.
Beri masukan
Untuk melaporkan bug atau meminta fitur, laporkan masalah di Pelacak bug Chromium.