ID Partners ConnectID + the Digital Credentials API

The demo

Video walkthroughs

Screen recordings of each flow, with a narrated explanation of what is happening and what to watch for. Short, single-purpose clips rather than one long film.

Recording in progress

Each clip does one job and is short enough to drop into a deck on its own.

Where a clip shows something that later turns into a constraint, the note under it says so and links through.

Three clips are recorded and published, and the consent screen — the thing the site was built to show — is captured as a pair of phone frames in section 1 below. The remaining clips need a phone with a wallet on it, because the consent screen cannot be simulated, which is exactly why it is worth seeing.

#The journey, as far as a desktop can take it

A customer buying wine, told they need to prove their age, choosing a provider, and arriving at the Connector. Every hop is the real deployed system.

Watch for two things. The chooser, where four banks sit greyed beside one live tile: that is the moment a licence is presented to the user as an alternative to a bank, and it is the subject of the chooser implies an equivalence that does not hold.

And the line under the tiles, which states the whole argument before it happens: the wallet is about to name this site as the requester, not the shop that sent you here.

The clip stops where the wallet would take over. That is deliberate rather than a gap in the recording — an automated browser hangs at the API call in a way a real user's browser does not, and filming that would be recording a quirk of the test harness and presenting it as a finding. The next clip picks up where this one stops.

#What the signed request actually says

The consent screen above shows what the wallet displays. This clip shows what it was given: the request, decoded, with the relying party's federation identity as its first line and the trust chain summarised beneath.

Watch for: client_id is the shop's federation identity, not the Connector's origin, and the chain is anchored at the Trust Controller. That is the request the right-hand consent frame was rendered from. The request says Wattlebrook; the wallet shows Wattlebrook. The Connector ran the ceremony and is named in neither.

#The demo, in a minute

A tour of what was built: the three axes it tests, the scenario runner, and the capability matrix that records every run.

Watch for: the matrix is the deliverable, not the flow. Every cell is a combination of credential format, wire protocol and platform, and each is recorded with what actually happened — including the failures, which are findings in their own right rather than bugs to be tidied away.

#The experiment the browsers disagree about

The cross-origin iframe test, which states its prediction before it runs: Chrome should verify, Safari should fail.

Watch for: this is the architecture question, made concrete. The embedded model is the better design on governance grounds and it is the specification's own worked example for a broker. It also does not work the same way in both browsers today. See Chrome and Safari disagree about which origin counts.

The device runs on both platforms will settle it empirically, and either result is a recorded finding on an open W3C issue.

This is the image the site was built around, and it exists now. The same ceremony, the same credential, the same three claims requested — run twice on the Android wallet. The only thing that differs is who signed the request.

Android wallet consent sheet headed 'Unknown requester', listing family name, given names and licence number, with a red warning that the application requesting this data is unknown
Request signed by the Connector itself. The wallet has no way to know who is behind it. "Unknown requester", and a warning.
Android wallet consent sheet headed 'Wattlebrook Cellars · via ConnectID (demo Trust Controller)', listing the same three claims, with a note that the application requesting this data is trusted
Request signed by the Trust Controller for the relying party. The wallet walked the chain to the anchor and names the shop. The Connector is nowhere in the frame.

Read the two headings, then the two boxes at the bottom. That is the wallet thinks it is talking to the Connector solved on one platform, and the mechanism is the federation-signed request. Nothing else changed between the two runs.

Three things to say honestly about these frames. The consent sheet is the wallet framework's own interface, fed by a real trust-resolution hook that validated the chain on the device; the name is not painted on. The wallet is demo code built to trust the demo anchor — the banner at the top of the right-hand frame, cropped in this capture, says "cooperating by construction" — so this shows the mechanism works, not that a platform wallet would do the same. And this is the app-to-app surface on Android, which currently completes consent and then fails on the response leg; the browser path is where the full round trip is expected to go green.

The iPhone equivalent now runs end to end on a device — the system picker offers the licence, the consent sheet appears, the presentation verifies. That sheet leads with the requester's origin, which is the Connector's, and shows nothing about the relying party, because the iPhone protocol has no slot for a signed request. The frame is being captured and will sit beside these two as the other half of the argument: on one platform the shop can be named, on the other it cannot.

Recording pending. This clip is published as soon as the flow it shows is working end to end.

The clip above is the full journey carried through this consent screen and back to the shop, on video; it is waiting on the iPhone capture and the emulator's browser update.

#2. What the relying party had to change

This one is better shown in code than on video, and it needs stating precisely because it is the strongest argument for the pattern and it is easy to overclaim.

The shop's entire integration is a link, plus a handler for what comes back:

<a id="verify" href="https://[connector]/choose.html?return=https%3A%2F%2F[shop]%2F">
  Verify with ConnectID
</a>

The user leaves, the exchange does its work, and they return with a session reference the shop exchanges for the claims it was entitled to receive. There is no wallet code in the shop, no credential format, no cryptography, no awareness that a licence was involved at all.

The precise claim, which is narrower than "nothing changes". The demo's shop is new, so it had to integrate once — that is ordinary onboarding and would be true of any provider. The connector-specific claim is this: for a relying party already integrated with ConnectID, adding wallet-based credentials requires no change at all. A new provider is registered, a tile appears in the chooser, and it is live everywhere at once.

That property is real, it survived contact with implementation, and it is the reason the pattern is worth the trouble described on Limitations.

#3. Selective disclosure: proving age and nothing else

The same infrastructure asked for a single derived fact instead of a full identity. The wallet shows the user that only one thing is being requested, and only one thing comes back.

Recording pending. This clip is published as soon as the flow it shows is working end to end.

Watch for: the consent screen lists one item. No date of birth is disclosed: the boolean itself is signed by the issuing authority. Set it beside the licence consent frame in section 1, which lists three fields because a licence check needs them. Same protocol, same wallet: one line against three, and that difference is the whole argument for the technology.

Two honest notes. The demo requests only the boolean on purpose — a verifier could ask for the boolean and a name together and re-identify the holder while looking like an age check, which is why the request shape is a decision. And the demo's proof-of-age credential is in the format iPhone wallets cannot present, so this clip is Android until a licence-format variant exists — see on iPhone, only one credential format works.

#4. When it does not work

The failure modes, filmed rather than described: a user with no licence, a user who declines, and a journey that started in an app's embedded browser.

Recording pending. This clip is published as soon as the flow it shows is working end to end.

Watch for: how similar the three failures look to the site. That similarity is errors are opaque by design, and it is why the fallback path has to be designed as a first-class journey rather than an error handler.

#5. The desktop path

The same flow started on a laptop, where there is no wallet and a second device has to be brought in.

Recording pending. This clip is published as soon as the flow it shows is working end to end.

Watch for: whether it completes at all. We expect this path to fail in our environment, and the clip will show the attempt rather than a tidied-up version of it. A filmed failure is better evidence than a written assertion. See desktop needs a second device. This is the clip that sets expectations about where the flow should be offered at all.

#6. The same flow on iPhone and on Android

The identical journey run on both platforms, cut side by side, with the protocol each one negotiated shown on screen.

Recording pending. This clip is published as soon as the flow it shows is working end to end.

Watch for: the two protocol names. They are different, and they are not variations on a theme: the cryptography underneath is incompatible. This is "the DC API" is not one API, and it is the clip to show anyone who assumes this is a single integration.

#How these are made

The clips are produced from a scripted browser session rather than captured by hand, so that they can be re-recorded without drift whenever the demo changes. The phone and wallet portions are necessarily captured from a real device, because the wallet consent screen is exactly the thing that cannot be simulated, and it is the thing worth seeing.

Recording scripts live alongside the site source in recording/. Re-running them regenerates every automated clip.