← All posts

Blog

Product Update #34

October 20, 2026

Key Attestation, Wallet2 Batch Issuance, Mandatory PAR, and more

TL;DR

  • New release - Key Attestation, Wallet2 Batch Issuance, Mandatory PAR, and more
  • walt.id Verifier x Google Wallet – Demo showcasing the request of a digital credential from the Google Wallet

Community Stack (1.2.0)

Below are the highlights available through 1.2.0 of the identity lib. Check out the full change log for 1.2.0 here. Want to learn more about the identity lib in general? Check out our intro video.

1.2.0

Features

Require Key Attestations in Issuer2

Issuer2 can now verify a key attestation carried in a JWT proof or sent as a standalone attestation proof. Set the trusted attester once in keyAttestationConfig with a public JWK or trusted X.509 CA certificates, and use key_attestations_required to make an attestation mandatory for a credential configuration. OAuth client attestation stays a separate configuration.

Learn more

Batch Issuance in Wallet2

Choose which offered credentials to receive and request several copies of one, each bound to its own holder key. Copies of one credential go out in a single Credential Request with several JWT proofs, while different credentials stay separate requests. Without a selection, Wallet2 still receives every granted credential once with a single holder binding.

Learn more

Enforce Pushed Authorization Requests (PAR) in Issuer2

Set enforcePushedAuthorizationRequests to true in issuer-service.conf and wallets must post the authorization parameters to the PAR endpoint before opening the authorization endpoint. Direct authorization requests are rejected. The default is false, so existing issuers keep allowing both.

Learn more

Choose the Signing Key for Signed Metadata in Issuer2

Pick the key and certificate chain Issuer2 uses to sign its Credential Issuer metadata. The same signedMetadata configuration now also signs OAuth authorization server metadata. Leave it out and Issuer2 keeps signing Credential Issuer metadata with its token key.

Learn more

Fixes and Improvements

  • Verifier2 accepts an IETF Token Status List signed by the same x5c leaf certificate as the credential, in addition to matching DID and https issuers. #2272
  • Verifier2 reuses a fetched status list while its Cache-Control: max-age is current. #2327
  • W3C credentials whose @context mixes URLs with inline JSON-LD objects, as Gaia-X credentials do, no longer fail on import or VC Data Model 2.0 issuance. #2344
  • DCQL type_values now match W3C types after JSON-LD @context expansion, so a query for an expanded IRI matches a compact type such as gx:LegalPerson. Compact values such as VerifiableCredential still match. #2345
  • Wallet2 accepts jwt_vc_json-ld and jwt_vc credentials again. JWT-secured W3C credentials stay stored as jwt_vc_json. #2378
  • A presentation is signed with the holder key stored on that credential. Sending a different key fails before the verifier sees the proof, while one OpenID4VP request can still ask for several credentials bound to different keys. #2336
  • Issuer2 credential responses are marked Cache-Control: no-store, and iOS wallets bypass Foundation’s HTTP cache for credential responses. #2299
  • Authorization and credential request timestamps are always encoded, so requestedAt is no longer dropped by a same-tick clock comparison. #2371
  • Issuer2 Swagger examples for transaction-code and runtime-override offers match the JSON the API accepts. #2334
  • X.509 certificate and PKCS#10 CSR signatures are interpreted with the algorithm the object declares. #2322
  • A trust store can hold several CAs with the same subject DN and different keys. Path validation selects the CA by key, and certificates are no longer stored only by serial number. #2349
  • ktor-authnz uses one Valkey connection for session and token stores. Failed LDAP and Web3 logins return 401 and failed logins are rate limited. Opaque tokens end with their session, a used TOTP code is refused inside its validity window, and new OIDC accounts get a random account id instead of sub. #2310
  • Reopening a mobile wallet initializes DID resolvers again, so a signed DID presentation request works after a process restart. #2314
  • When a presentation error cannot be reported safely, the original OpenID4VP error is preserved instead of being replaced by the reporting failure. #2317
  • TestFlight builds of the native and Compose wallet demos are no longer killed on suspend for holding a SQLCipher shared-memory lock. #2346
  • A superseded Android biometric signing check is cancelled off the main thread, so activity recreation no longer closes an in-flight HTTP call. #2341
  • The Compose web wallet can target the Enterprise Wallet API with WALLET_API_FLAVOR and WALLET_API2_PUBLIC_URL. The open-source API remains the default. #2335
  • The Compose and native iOS demo wallets can attach a test key attestation for the known ITB and EUDI test issuers. This is demo-only. #2351

Enterprise Stack (1.2.0)

Below are the new feature highlights available through 1.2.0 of the Enterprise Stack. Check out the full change log for 1.2.0 here. Want to learn more about the enterprise stack in general? Check out our intro video.

1.2.0

Features

Require Key Attestations in Issuer2

Issuer2 can now verify a key attestation carried in a JWT proof or sent as a standalone attestation proof, and a credential configuration can require one with key_attestations_required. Set the trusted attester in keyAttestationConfig as a public JWK, trusted X.509 root certificates, or a KMS verification key.

Learn more

Batch Issuance in Wallet2

One receive call can select offered credential configurations and request several copies, each bound to its own holder key. Copies of one credential go out as one Credential Request with several JWT proofs, while different configurations stay separate requests. A single holder binding remains the default.

Learn more

Enforce Pushed Authorization Requests (PAR) in Issuer2

Set requirePushedAuthorizationRequests to true when you create or update an Issuer2 service and wallets must post the authorization parameters to the pushed authorization endpoint first. Direct authorization requests are rejected with invalid_request. The default is false, so existing issuers keep allowing both.

Learn more

Choose the Signing Key for Signed Metadata in Issuer2

Choose the key that signs Credential Issuer metadata with signedMetadata: an inline JWK, an inline PEM key with a certificate chain, or a KMS key, optionally with x5c certificates from the X.509 store. The same configuration now also signs OAuth authorization server metadata. Leave it out and Issuer2 keeps signing Credential Issuer metadata with tokenKeyId.

Learn more

Maintenance Mode for Organizations and Tenants

Make an organization, or a single tenant, read-only for a time-boxed window while reads keep working. A window lasts 1 day by default and at most 30 days, and you can end it early. It is off unless the maintenance feature is enabled, and accounts holding organization-management-maintenance-override, which the all permission includes, can keep writing.

Learn more

Status List Lifetime and Rollover in the Credential Status Service

Set ttl in seconds on an IETF Token Status List configuration. The published token uses it, objects in S3, Azure Blob Storage and Google Cloud Storage carry a matching Cache-Control: public, max-age, and Verifier2 reuses a downloaded list until it elapses. Creating a status entry now returns statusListRef, the list that holds the new index, and after automatic rollover later index updates must use that list.

Learn more

Fixes and Improvements

  • Wallet2 pre-authorized receive on DocumentDB no longer fails with a storage error after the issuer has already returned the credential.
  • Concurrent receives into one Wallet2 wallet retry a contended credential write instead of failing an issuance that already succeeded.
  • A presentation is signed with the holder key the credential was issued to. A different key is rejected before it is sent.
  • Revoking or reading a status index after automatic rollover now works on the list that holds that index, not the base list that allocated earlier entries.
  • Verifier2 accepts an external IETF status list whose x5c leaf matches the credential. Lists hosted by this deployment stay allowed as well.
  • Issuer2 credential responses, including failures before the response writer, send Cache-Control: no-store.
  • Deleting an organization also removes its host aliases, role entries on accounts, events and Issuer2 OAuth state. The accounts remain and the eIDAS audit chain is kept.
  • Assigning a role to a user or API key requires every permission that role grants. Removing a deny rule requires the permission it withheld, while removing a grant does not.
  • Wallet2 receive defaults clientId to the wallet client id the wallet library uses, so an authorization-code exchange no longer fails with a client mismatch.
  • Issuer2 OpenAPI examples match the request bodies the API accepts.
  • Listing tenant accounts checks that the tenant path is inside the authenticated organization.
  • The admin organization list honors the advertised pagination parameters and rejects invalid ones.
  • Organization and tenant configuration updates validate organization ids and DID registry references and return the documented errors.
  • A migration scheduling bug found while documenting PostgreSQL is fixed, and database profile fields that the API never read are marked unused. Profile behavior is otherwise unchanged.

walt.id Verifier x Google Wallet

This demo shows interoperability between the walt.id Verifier API and Google Wallet.

Watch the video


Digital ID End-to-End Tutorial

A practical, end-to-end tutorial with the walt.id Community Stack, showing how Issuer, Wallet and Verifier work together to issue, hold and verify digital credentials. You will start the stack with Docker Compose, issue a W3C Open Badge Credential via OID4VCI, and request and verify it with OID4VP and verification policies.

Watch the video


PS: If you enjoy working with our tools, make sure to leave us a ⭐ on GitHub