Credenco 🇳🇱
Credenco: Issuer and Verifier for the France Identité Playground¶
🇳🇱 Credenco builds the Business Wallet: infrastructure that lets organisations issue, hold and verify credentials. We contribute both an Issuer and a Verifier to the EUDIW Unfold Playground, so you can test both directions in one session against a wallet you already carry.
First time here? If you carry France Identité, the age check under Demo scenarios works with it as it stands, in about a minute. Every other flow needs the Credenco Personal Wallet, because France Identité holds its own credentials rather than ours; Which wallet you need below tells you where to get it. The full tour is issue the three test credentials and then rent a car with them, about ten minutes end to end. Everything runs cross-device with a QR code or same-device with a wallet link, and needs no account. The whole demo is available in French: append
?lang=frto any link on this page.
Playground base URL: https://api.playground.france-identite.gouv.fr/credenco/demo/ (also self-hosted at https://playground.credenco.com/)
At a glance¶
| Field | Value |
|---|---|
| Roles | Issuer and Verifier. You bring your own wallet |
| Profiles | DIIP v2/v3 and v4/v5, and HAIP |
| Protocols | OpenID4VCI and OpenID4VP |
| Query language | DCQL on DIIP v4/v5 and HAIP; Presentation Exchange on DIIP v2/v3 |
| Formats | SD-JWT VC (dc+sd-jwt / vc+sd-jwt), JWT VC, and ISO/IEC 18013-5 mdoc (mso_mdoc) |
| Client identification | x509_san_dns on the age check; decentralized_identifier elsewhere. See Playground specifics |
| Response modes | direct_post and direct_post.jwt, set per query. See Playground specifics |
| Revocation | Supported: IETF Token Status List (StatusList2021 for older credentials; no Bitstring Status List). The demo credentials on this page are issued without one |
| Credential types | Issued: Personal ID, driving licence, bank account, and a Wayfare reservation. Verified: those, plus the France Identité age-verification mdoc |
| Interaction modes | Cross-device (QR code) and same-device (wallet link) |
| Languages | English and French, plus Dutch, German, Finnish, Norwegian, Portuguese and Swedish. Append ?lang=fr to any link |
| Operator | Credenco B.V., Netherlands |
| Status | Sandbox, suitable for integration testing |
Why Credenco¶
Both directions, one session. Plenty of entries here issue and verify. What the Wayfare scenario adds is the return leg: it verifies identity, age and licence category, takes payment by presenting a bank-account credential, and then issues the reservation back into the wallet, inside the same session, without sending you anywhere else to collect it.
One credential definition, every profile. DIIP is the Decentralized Identity Interoperability
Profile, and together with HAIP it decides how a request is shaped: DCQL and dc+sd-jwt on
DIIP v4/v5 and HAIP, Presentation Exchange and vc+sd-jwt on DIIP v2/v3. One credential
definition can therefore be tested against wallets on different profiles without a redeploy.
From concept to production. Every flow below carries a maturity badge, so you can see
what is production-grade and what is still on its way there. Pilot runs in a real pilot
programme; Concept is built and demonstrable but not yet hardened against other
implementations. We publish both, because what is possible today tells you more than a list
of only the finished parts.
Conformance¶
These are the test results for the Credenco Business Wallet, the engine behind this playground, not the front end.
- DIIP v5 conformance, reached through the FIDES Integrated Test Bed for both issuance
and presentation. It is a first-class profile in the stack: it selects RFC 8414 metadata
discovery, the
credentialsresponse shape and DCQL. - WE BUILD Interoperability Test Bed, all test cases passed, as one of the first wallet providers in the consortium to get there. We are a member of the Large-Scale Pilot for the European Business Wallet.
- Trust resolution runs against ETSI trusted lists and a locally maintained issuer list. EBSI is supported for DID registration, which is a separate concern from resolving trust at verification time.
These are test bed results, not certification. As of August 2026 no certified EUDI Wallet Solution exists and we make no claim to be one.
Supported standards¶
- OpenID for Verifiable Credential Issuance
- OpenID for Verifiable Presentations, with DCQL for credential queries
- JAR (RFC 9101) signed request objects
- IETF SD-JWT VC for the credential format
- IETF Token Status List for revocation
Trust material and metadata. The credential offer carries the issuer URL, so a wallet resolves the rest on its own. These are the paths it will find, all unauthenticated:
| What | Path |
|---|---|
| Issuer metadata | /public/{wallet}/{issuer}/.well-known/openid-credential-issuer |
| Issuer metadata, RFC 8414 form | /.well-known/openid-credential-issuer/public/{wallet}/{issuer} |
| Authorization server metadata | /public/{wallet}/{issuer}/.well-known/oauth-authorization-server |
| JWT VC issuer metadata | /.well-known/jwt-vc-issuer/public/{wallet}/{issuer} |
| Issuer JWKS | /public/{wallet}/{issuer}/jwks |
| Verifier JWKS | /api/oidc/jwks/{wallet} |
There is no .well-known/jar-issuer and no OpenID Federation endpoint. Our request objects
carry the signing certificate in the x5c header instead.
Playground specifics¶
Versions. On DIIP v4/v5 and HAIP we speak the OpenID4VP 1.0 wire format: DCQL queries,
a vp_token keyed by query id, a scheme-prefixed client_id, and a signed request object
fetched by request_uri. One deviation is worth naming up front. Encrypted responses still
advertise the pre-1.0 authorization_encrypted_response_alg and
authorization_encrypted_response_enc parameters rather than the 1.0
encrypted_response_enc_values_supported. DIIP v2/v3 stay on the pre-1.0 Presentation
Exchange profile.
On the issuance side the draft follows the profile: OpenID4VCI draft 11 on DIIP v2, draft 13 on v3, draft 15 on v4, and 1.0 on v5 and HAIP.
Not implemented on any profile: transaction_data, request_uri_method as a request
parameter, and verifier_info. If your wallet is pinned to a particular draft, tell us
before you test and we will say plainly whether it will work.
Fetching the request object. GET and POST on the request_uri both return the
signed request object. The POST semantics of OpenID4VP are not implemented yet, though:
wallet_metadata and wallet_nonce in the body are ignored and no wallet_nonce claim
comes back. If your wallet uses POST to get nonce binding, it will not get it yet.
Response modes. Both are implemented. An encrypted response is a JWE with ECDH-ES
on P-256 and A256GCM content encryption.
Which mode a request carries is decided per query rather than globally. The France
Identité age check goes out as direct_post.jwt, because that wallet only answers
encrypted requests; every other scenario on the page goes out as direct_post. If you
need the encrypted mode on another scenario, contact us: it is a setting on the request,
not a rebuild.
Client identification. The France Identité age check carries
client_id: x509_san_dns:..., with its self-signed certificate travelling in the x5c
header of the request object; the SAN matches the request host, so no whitelisting is
needed. The other scenarios carry client_id: decentralized_identifier:did:web:... and
will move to x509_san_dns with the certificate published under Certificate below,
DNS SAN demopidprovider.acc.credenco.com.
Trust setup for visiting wallets. There are two separate trust anchors here, and they are not the same certificate.
To trust our presentation requests, no whitelisting is needed for the age check: its
certificate travels in the x5c header of the request object. For the other scenarios,
the reader certificate published under Certificate below applies once they move to
x509_san_dns; it is self-signed and carries no chain.
To trust the credentials we issue, use the X.509 chain our issuer carries in the x5c
header of each credential, which lets a wallet anchor trust in a chain rather than a DID.
That chain is not reproduced here; it is available on request.
Demo scenarios¶
Carrying France Identité? Start with the age check below, one minute. The rest of the page is one funnel, not a menu: issue three credentials, then spend them at a rental service that actually asks for them. You can also run a presentation on its own.
Prove you are over 18 with France Identité. The one scenario on this page that needs
no Credenco credentials: present the age-verification attestation from your France
Identité wallet, and nothing else. The request goes out as direct_post.jwt, since
France Identité only answers encrypted requests.
Try it → Pilot

Issue three test credentials. A Personal ID (name, date of birth, nationality,
address), a driving licence including the categories you may drive, and a bank account.
All three are SD-JWT VC, issued over OpenID4VCI. The data is fictional. You receive the credentials
of Klaas Jansma, so nothing about you is stored anywhere.
Try it → Pilot
Wayfare car rental, end to end. A rental service we built to show what a booking looks
like when the customer already carries verified credentials. No account, no form. You pick
a car, prove four things about yourself, pay by presenting the bank-account credential
instead of typing an IBAN, and the reservation is issued back into your wallet, which
is then all you need at the desk.
Try it → Pilot
Prove who you are and that you may drive. The OpenID4VP exchange on its own, without
the rental around it: one request asking for the Personal ID and the driving licence
together. The page lists exactly which attributes came back. Both are mandatory, so issue
them first. Try it → Pilot
What the verifier learns, and what it does not. Because the credentials are SD-JWT VC,
the holder answers with a subset rather than handing over a document. The Personal ID carries
age_over_18 and age_over_21 next to birth_date, so a verifier that only needs to know
whether someone is old enough can ask for the predicate and never see the date. The licence
works the same way: category B without the full history. The answer stays signed by the
issuer, so disclosing less costs nothing in assurance. After each presentation the page lists
which attributes came back, so the holder sees it too and not only we do.
The rental, screen by screen¶
The whole funnel in eight screens, in the order you will see them yourself. The playground
and Wayfare are shown in English; both also run in French (?lang=fr), and the wallet
follows your phone's language.
Issue the test credentials. The page tracks which of the three you already hold; each card starts its own issuance.

Scan, or stay on your phone. Every credential offer comes as a QR code for cross-device and a wallet link for same-device, and the page notices by itself when the credential lands.

Pick a car at Wayfare. No account, no form: the booking starts with the car, not with your data.

One request, three credentials. Wayfare says up front what it will verify: your name, that you are over 21, licence category B, and your address.

Verified, and nothing more. What came back is exactly the list from the request; the age arrives as over 21, not as a date of birth.

Pay by presenting, not typing. The bank-account credential replaces the IBAN form field.

The reservation is a credential too. Wayfare issues the booking straight back into your wallet, with a booking code to match.

What ends up in the wallet. Four cards: the three test credentials and the rental confirmation, which is all the desk needs to see.

Maturity¶
The badges are the ones defined under Why Credenco. Where a flow is not switched on for this playground, the note says what switches it on.
| Flow | Status | Note |
|---|---|---|
| Issue Personal ID (SD-JWT VC) | Pilot |
Works with wallets that match on our vct; see the caveat below |
| Issue driving licence (SD-JWT VC) | Pilot |
Not an ISO mDL |
| Issue bank account (SD-JWT VC) | Pilot |
Dutch-language claim names |
| Present Personal ID and driving licence | Pilot |
One query, both credentials mandatory |
| Wayfare end to end (verify → pay → issue reservation back) | Pilot |
A real, running service. Works with wallets that accept our issuer; see the caveat below |
| Verify an mdoc presentation | Pilot |
The full ISO check: DeviceResponse status, a session transcript bound to client_id and nonce, the device signature, element-level tamper detection, and the issuer chain up to a configured IACA |
| Verify a France Identité presentation | Pilot |
Verified live against the France Identité wallet in the Credenco Business Wallet, including the age-verification mdoc (eu.europa.ec.av.1), anchored on the France Identité IACA. Wired to the age check under Demo scenarios |
| Present an mdoc from our own wallet | Concept |
The Credenco Personal Wallet answers with a full ISO DeviceResponse: DeviceSigned with an ES256 device signature over the OpenID4VP session transcript, and element-level selective disclosure. Verified against our own verifier, not yet against other implementations |
| Issue an mdoc | Concept |
Signs an MSO with COSE_Sign1 and returns IssuerSigned, with the ISO 18013-5 Annex B document signer profile enforced. Not yet exercised against other wallets |
W3C Digital Credentials API (dc_api) |
Not built |
Scheduled as soon as someone needs it |
Two things to know before you write a matcher. Our credentials carry vct Pid and
urn:eu:credential:mdl:1, which are Credenco-scoped rather than the canonical
urn:eudi:pid:1 or eu.europa.ec.eudi.pid.1, so a verifier querying the canonical
identifiers finds no match. And the boolean-looking claims in the Personal ID are issued as
the JSON string "true", not as a boolean. Both are configuration rather than code. Tell us
what you need and we will change them.
Which wallet you need. The Credenco Personal Wallet (iOS, Android), which holds personal and organisational credentials alike. France Identité cannot hold ours: its OID4VCI External Issuance runs the other way, with France Identité as the issuer delivering an age-verification mdoc into third-party wallets, and there is no documented path for an outside issuer to write into it. That is the standard working as intended. A national identity wallet should not let just anyone write into it.
Certificate¶
The verifier X.509 certificate below is the one the remaining scenarios will carry when
they move to x509_san_dns. The age check needs no whitelisting: its certificate travels
in the x5c header of the request object. Client identification under Playground
specifics says where things stand today.
Subject: C=NL, O=Credenco B.V., CN=demopidprovider.acc.credenco.com
Valid: Aug 24 11:25:20 2026 GMT to Nov 26 11:25:20 2028 GMT
Key: EC P-256
DNS SAN: demopidprovider.acc.credenco.com
Full certificate (PEM):
-----BEGIN CERTIFICATE-----
MIICNDCCAdqgAwIBAgIUL7uvAR6b21Ve3ZO4gvs/StUxutYwCgYIKoZIzj0EAwIw
UDELMAkGA1UEBhMCTkwxFjAUBgNVBAoMDUNyZWRlbmNvIEIuVi4xKTAnBgNVBAMM
IGRlbW9waWRwcm92aWRlci5hY2MuY3JlZGVuY28uY29tMB4XDTI2MDgyNDExMjUy
MFoXDTI4MTEyNjExMjUyMFowUDELMAkGA1UEBhMCTkwxFjAUBgNVBAoMDUNyZWRl
bmNvIEIuVi4xKTAnBgNVBAMMIGRlbW9waWRwcm92aWRlci5hY2MuY3JlZGVuY28u
Y29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvwPL97vOD24ooCHCgJ9bXSbG
m8pamnHaAvpkZ8zjwSu2xBEluO4TKD8Y2rIdlEIfADCL2t6m0V17k3jlai5dnaOB
kTCBjjAdBgNVHQ4EFgQUjVa/18HDC6/Wr/8AXATus0Mss8cwHwYDVR0jBBgwFoAU
jVa/18HDC6/Wr/8AXATus0Mss8cwDwYDVR0TAQH/BAUwAwEB/zArBgNVHREEJDAi
giBkZW1vcGlkcHJvdmlkZXIuYWNjLmNyZWRlbmNvLmNvbTAOBgNVHQ8BAf8EBAMC
B4AwCgYIKoZIzj0EAwIDSAAwRQIhAJXdkE7gwUB0goFKbljYq0iIaMM3HnTSOLWU
+WDfPzNyAiAcM11GKhv1dVDqUfrHJO6woEdzlZdwpUMAlnxTAWU4Mg==
-----END CERTIFICATE-----
Troubleshooting¶
- "No credentials available" almost always means one of the required credentials is missing from your wallet. The presentation query asks for the Personal ID and the driving licence together and both are mandatory, so issue the one you skipped and try again. The page names the missing credential.
- "One or more credentials could not be verified" usually means your wallet will not accept credentials from an issuer it does not already know. Use the Credenco Personal Wallet; see Which wallet you need above.
- Start a new reservation rather than reloading a page you had already scanned on. Wayfare evaluates everything presented within one booking session, so an earlier attempt can keep a stale result on screen.
Get in touch¶
Happy to help with testing, integration questions, or a credential type that is not on this list. We read everything that comes in and we answer.
- Engineering support: Pieter Mortier, pieter.mortier@credenco.com
- Web: credenco.com
If something goes wrong, the fastest way to get it fixed is to tell us which flow you were in, which wallet app and version you used, your device and OS, and the session identifier shown on the page. With those five things we can usually reproduce it the same day.
With thanks to the France Identité team and the EUDIW Unfold initiative.