Дата публикации: 23 октября 2026 г.
В Chrome 155 и более поздних версиях выпуск Digital Credentials API включен по умолчанию, поэтому для его использования больше не нужен токен эксперимента с источником или флаг. Digital Credentials API – это транспортный уровень, который позволяет сайтам подключаться к приложениям-кошелькам, установленным на мобильном устройстве пользователя. С помощью API Google Wallet эмитенты могут добавлять новые удостоверения (например, цифровые удостоверения личности) прямо в приложение "Google Кошелек" пользователя.
Фон
В экосистеме цифровых удостоверений личности есть три стороны: эмитенты, верификаторы (также называемые полагающимися сторонами) и держатели (приложения-кошельки). Пользователи часто добавляют цифровое удостоверение личности в приложение кошелька с помощью добавления карты в Google Pay в банковском приложении. При этом пользователь начинает выпуск на сайте или в приложении эмитента. Например, студент на сайте своего университета (эмитента) может сохранить свое цифровое студенческое удостоверение личности в предпочитаемом приложении кошелька (держателя).
Чтобы эта модель работала, эмитенту нужен безопасный и надежный способ вызывать приложение кошелька для выпуска удостоверения. До появления этого API каждому эмитенту приходилось создавать собственный способ открытия приложений-кошельков, с которыми он сотрудничал, обычно с помощью пользовательских схем URI. Эмитентам приходилось поддерживать отдельный механизм для каждого приложения-кошелька, а у пользователей не было единого способа выбрать приложение-кошелек.
Как работает выпуск цифровых удостоверений
Чтобы упростить этот процесс, Chrome поддерживает выпуск с помощью W3C Digital Credentials API. Это дополняет возможности презентации (передачу запрашиваемых выборочных данных из цифрового удостоверения личности проверяющему), которые появились в Chrome 141. Когда сайт эмитента вызывает navigator.credentials.create() с элементом digital, содержащим запрос на выпуск, Chrome передает запрос операционной системе (на Android – Менеджеру учетных данных). Затем операционная система показывает собственный интерфейс, в котором пользователь выбирает приложение-кошелек. API работает с отраслевыми стандартными протоколами, такими как OpenID for Verifiable Credential Issuance (OpenID4VCI).
Выпуск поддерживается в двух сценариях: на одном устройстве Android и на нескольких устройствах (начинается на компьютере и заканчивается на устройстве Android).
Процесс на одном устройстве Android
На устройствах Android Chrome передает запрос на выпуск Менеджеру учетных данных, который показывает список совместимых приложений-кошельков на устройстве. Пользователь выбирает кошелек и дает согласие на добавление удостоверения. Затем приложение кошелька получает удостоверение от эмитента с помощью протокола выпуска, например OpenID4VCI.
Процесс на нескольких устройствах на компьютере
На компьютере Chrome покажет QR-код. Пользователь сканирует код с помощью устройства Android и завершает процесс на этом устройстве, как описано в предыдущем разделе. Устройства используют Bluetooth, чтобы подтвердить, что они находятся рядом друг с другом, поэтому Chrome просит пользователя включить Bluetooth, если он выключен. Chrome использует тот же механизм взаимодействия между устройствами для представления Digital Credentials API.
Как реализовать выпуск карт с помощью API
Чтобы начать процесс выпуска, вызовите navigator.credentials.create() и передайте запросы на выпуск в элементе digital. Вызов должен выполняться из обработчика кликов или другого обработчика жестов пользователя, поскольку для вызова требуется временная активация пользователя. В следующем примере используется предложение учетных данных OpenID4VCI с предварительно авторизованным кодом:
// 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);
});
В этом примере showAlternativeIssuanceFlow() и showIssuanceStatus() заменяют логику вашего приложения.
Чтобы вызвать create() из перекрестного iframe, на странице, где оно размещено, должно быть разрешено правило доступа digital-credentials-create. В противном случае вызов отклоняется с ошибкой NotAllowedError:
<iframe src="https://issuer.example" allow="digital-credentials-create">
</iframe>
Изменения по сравнению с экспериментом с источником
Методы и параметры API не изменились с момента эксперимента с источником. Однако в версиях Chrome 143–155 были внесены изменения, некоторые из которых могут потребовать обновления кода. В таблице ниже приведены изменения, а в разделах после нее – пояснения к каждому из них.
| Область | Эксперимент с источником (Chrome 143) | Chrome 155 |
|---|---|---|
| Доступность | Токен эксперимента с источником или параметр chrome://flags/#web-identity-digital-credentials-creation |
Включен по умолчанию |
| Активация пользователя | Обязательно, но не используется | Обязательный параметр, который используется при каждом вызове create() (Chrome 146). |
| Ошибки отмены | NetworkError |
NotAllowedError (Chrome 148) |
| Идентификаторы протоколов | Chrome передает операционной системе любой идентификатор | Нераспознанные идентификаторы вызывают предупреждение о прекращении поддержки (Chrome 151) |
| Непрозрачные источники | Разрешено | Заблокировано с помощью NotAllowedError (Chrome 151) |
| Автоматизированное тестирование | Нет встроенной поддержки | Виртуальный кошелек в Chrome DevTools Protocol (Chrome 152) |
Активация пользователя использована
Начиная с Chrome 146 вызов create() с элементом digital использует временную активацию пользователем, как того требует спецификация. Во время эксперимента с источником Chrome проверял активацию пользователем, но не использовал ее.
В результате для каждого вызова create() требуется отдельный жест пользователя, например нажатие кнопки. Без активации пользователем промис отклоняется с ошибкой NotAllowedError. После вызова window.open() и другие API, требующие активации пользователем, не могут использовать тот же жест.
Отклонение отмены с помощью NotAllowedError
Начиная с Chrome 148, промис, возвращаемый create(), отклоняется с ошибкой NotAllowedError, когда пользователь отменяет процесс, например закрывает окно выбора кошелька на Android или диалоговое окно с QR-кодом на компьютере. Если ни одно приложение кошелька не может обработать запрос, обещание также отклоняется с ошибкой NotAllowedError.
Во время эксперимента с источником такие случаи отклонялись с ошибкой NetworkError.
Если ваш код проверяет NetworkError, чтобы обнаружить отмену, измените его так, чтобы он проверял NotAllowedError.
Нераспознанные идентификаторы протоколов вызывают предупреждение
В спецификации определен один идентификатор протокола выдачи, openid4vci-v1, для OpenID4VCI 1.0. Chrome 155 распознает openid4vci-v1 и openid4vci. Поскольку openid4vci не входит в спецификацию, мы рекомендуем использовать openid4vci-v1.
Chrome передает платформе запросы с любым идентификатором протокола. Однако начиная с Chrome 151 в Инструментах разработчика будет показываться предупреждение о прекращении поддержки, если страница вызывает create() с нераспознанным идентификатором протокола. В Chrome планируется блокировать запросы с нераспознанными идентификаторами протоколов. Статус можно посмотреть в разделе Более точная фильтрация протоколов в Digital Credential API.
Чтобы протестировать это поведение, включите параметр chrome://flags/#enable-experimental-web-platform-features. Если этот флаг включен, create() игнорирует запросы с нераспознанными идентификаторами протоколов и отклоняет их с ошибкой TypeError, если запросов не осталось. Кроме того, DigitalCredential.userAgentAllowsProtocol() возвращает true только для распознанных протоколов. Если флаг не установлен, проверяется только корректность формата идентификатора.
Поэтому не полагайтесь только на userAgentAllowsProtocol() для обнаружения функций.
Обработайте NotSupportedError, как показано в примере.
Непрозрачные источники заблокированы
Начиная с Chrome 151, create() отклоняет запрос с ошибкой NotAllowedError, когда его вызывает документ с непрозрачным источником, например изолированный iframe без токена allow-same-origin.
Во время эксперимента с источником Chrome не блокировал эти вызовы.
Тестирование с помощью виртуального кошелька
Начиная с Chrome 152 вы можете тестировать процесс выпуска без устройства Android или приложения кошелька. Экспериментальная команда DigitalCredentials.setVirtualWalletBehavior в Chrome DevTools Protocol (CDP) реализует виртуальный кошелек, который спецификация определяет для автоматического тестирования. Виртуальный кошелек может отвечать на запросы, используя предоставленные вами данные, отклонять запросы, как если бы пользователь отменил процесс, или оставлять запросы в ожидании, чтобы проверить тайм-ауты и прерывания.
В следующем тесте Puppeteer виртуальный кошелек настраивается так, чтобы отвечать на запросы openid4vci-v1, а затем нажимается кнопка, которая запускает выпуск:
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');
Внедрение в отрасли
Мы видим, что Digital Credentials API используется для выпуска цифровых удостоверений. Например, немецкая финансовая организация Sparkasse использует Digital Credentials API, чтобы владельцы аккаунтов могли сохранять подтвержденные данные о возрасте в Google Кошельке. После этого владельцы аккаунтов могут использовать эти учетные данные для подтверждения своего возраста онлайн и лично.
Попробовать
Прежде чем тестировать выдачу Digital Credentials API, убедитесь, что у вас есть:
- Обновите Chrome до версии 155 или более поздней.
- Установите на устройство Android поддерживаемое приложение кошелька, например демоверсию CMWallet.
- На обоих устройствах включен Bluetooth (только для переноса между устройствами).
Чтобы протестировать процесс на нескольких устройствах:
- Откройте демонстрационный сайт эмитента на компьютере.
- Нажмите кнопку Добавить.
- Отсканируйте QR-код с помощью устройства Android и следуйте инструкциям на экране.
Чтобы протестировать процесс на одном устройстве, откройте демонстрационный сайт эмитента в Chrome на устройстве Android.
Ресурсы для разработчиков
Чтобы начать интеграцию Digital Credentials API для выдачи удостоверений на вашем сайте, воспользуйтесь следующими ресурсами:
- Прочитайте руководство для разработчиков от W3C Web Identity & Credentials Adoption Community Group.
- Ознакомьтесь со спецификацией цифровых удостоверений W3C.
- Ознакомьтесь со спецификацией OpenID for Verifiable Credential Issuance 1.0.
- Изучите исходный код демоверсии CMWallet – демонстрационного приложения кошелька с открытым исходным кодом для Android.
- Узнайте, как приложения-кошельки для Android обрабатывают запросы на выпуск от Менеджера учетных данных.
- Попробуйте использовать демонстрационный сайт эмитента с демонстрационным приложением CMWallet, установленным на устройстве Android.
- Посмотрите демоверсию конструктора запросов цифровых удостоверений, чтобы узнать, как выглядит полезная нагрузка запроса.
Отправьте отзыв
Чтобы сообщить об ошибке или запросить добавление функции, создайте запрос в системе отслеживания ошибок Chromium.