Skip to content

[WAL-995] feat(mobile): add mobile OpenID4VCI authorization-code issuance#1935

Open
szijpeter wants to merge 14 commits into
fix/wal-1158-openid4vci-nonce-endpointfrom
feature/wal-995-openid4vci-auth-code
Open

[WAL-995] feat(mobile): add mobile OpenID4VCI authorization-code issuance#1935
szijpeter wants to merge 14 commits into
fix/wal-1158-openid4vci-nonce-endpointfrom
feature/wal-995-openid4vci-auth-code

Conversation

@szijpeter

@szijpeter szijpeter commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds production OpenID4VCI 1.0 authorization-code credential issuance to the Android and iOS mobile wallet SDK for WAL-995. A durable KMP issuance-session API now serves authorization-code and existing pre-authorized flows, so applications can resolve an offer, present a typed preview, hand authorization to the browser, safely continue from the callback, and consume typed issuance outcomes without parsing protocol JSON.

This PR is stacked on #1937, which independently owns the WAL-1158 OpenID4VCI 1.0 strict nonce_endpoint correction.

What Changed

Shared issuance and protocol handling

  • Adds typed offer, issuer, credential, transaction-code, authorization, callback, PKCE, deferred-result, and error models.
  • Introduces one session service for authorization-code and pre-authorized grants with single-use callback/session binding and replay protection.
  • Validates issuer, authorization-server selection, HTTPS endpoints, redirect URI, callback parameters, state, and optional authorization-response iss before continuing.
  • Uses issuer metadata to select PAR and DPoP behavior; DPoP is applied only when metadata supports the selected grant, with nonce challenges, ath, fresh proof identifiers, and exact target binding.
  • Requests a credential-proof nonce only when current issuer metadata advertises nonce_endpoint; proofs otherwise omit the JWT nonce claim and never use token-response c_nonce or the access token as a fallback.
  • Binds credential proofs and DPoP to the selected holder key; a DID kid is used only when its stored public JWK matches that key, otherwise proof binding falls back to JWK.
  • Follows token endpoint redirects only for same-origin 307/308 responses, preventing grant material from being re-posted after 303 or across origins.
  • Handles immediate, deferred, cancelled, and failed outcomes for SD-JWT VC, mdoc, and W3C JWT credentials.

Mobile SDKs

  • Exposes the typed session lifecycle through the public mobile KMP API and generated ABI surface.
  • Persists active authorization continuations and deferred handles in the encrypted mobile wallet database so sessions survive service and process recreation.
  • Adds equivalent Swift value types and async facade methods through the KMP bridge.
  • Preserves the existing resolveOffer and receive APIs for pre-authorized integrations while routing them through the shared engine.

Reference applications and security

  • Wires typed browser authorization, callback continuation, deferred resume, and lifecycle cancellation into the Compose and native iOS reference wallets.
  • Registers the mobile callback scheme on Android and iOS.
  • Enforces HTTPS for issuer protocol endpoints, including nonce_endpoint, without a loopback exception.
  • Keeps the PKCE verifier inside encrypted continuation state; public KMP and Swift models expose only the challenge and method.
  • Removes credential, proof, nonce, token, and callback material from issuance logging and disables HTTP header logging for these flows.
  • Keeps deferred handles opaque so access tokens and credential material do not cross the public API boundary.

Architecture Notes

  • Protocol state, callback validation, token exchange, nonce acquisition, proof construction, credential parsing, and storage remain in the shared wallet layer. Reference applications only drive typed session transitions.
  • Session and deferred state transitions are mutex-protected, persisted atomically, and terminal transitions are single-use.
  • The selected holder key is carried through token-bound DPoP and credential proof construction instead of being reselected by platform code.
  • Nonce acquisition reuses the typed, metadata-driven client introduced by [WAL-1158] fix(openid4vci): align wallet nonce handling with 1.0 #1937; this PR does not duplicate WAL-1158 behavior.

Caveats and Follow-Ups

Breaking Changes

None relative to the WAL-1158 prerequisite. Existing pre-authorized issuance entry points remain available.

@linear-code

linear-code Bot commented Jul 20, 2026

Copy link
Copy Markdown

WAL-995

@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b1c556f7-6e41-4a5d-bbb3-999f0ecd1938

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@szijpeter szijpeter changed the title feat(WAL-995): add mobile OpenID4VCI authorization-code issuance [WAL-995] feat(mobile): add mobile OpenID4VCI authorization-code issuance Jul 20, 2026
@szijpeter szijpeter self-assigned this Jul 20, 2026
@szijpeter szijpeter added the ci:mobile Run mobile related CI workflows for this PR label Jul 20, 2026
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 140ba61 to 5314c1f Compare July 20, 2026 23:01
@szijpeter
szijpeter changed the base branch from main to fix/wal-1158-openid4vci-nonce-endpoint July 20, 2026 23:02
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 2033d2d to 402f41f Compare July 20, 2026 23:08
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 5314c1f to 5b7595f Compare July 20, 2026 23:09
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 402f41f to 60f585d Compare July 20, 2026 23:15
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 5b7595f to 7882bcf Compare July 20, 2026 23:15
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 60f585d to 65485fe Compare July 20, 2026 23:19
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 7882bcf to 050cd9a Compare July 20, 2026 23:21
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 65485fe to 4a8da94 Compare July 20, 2026 23:39
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 050cd9a to db65cda Compare July 20, 2026 23:51
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 4a8da94 to e083669 Compare July 21, 2026 00:15
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from db65cda to 1b4522b Compare July 21, 2026 00:15
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from e083669 to 231ac13 Compare July 21, 2026 00:19
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 1b4522b to 7f67d48 Compare July 21, 2026 00:19
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 231ac13 to fe7126e Compare July 21, 2026 00:56
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch 2 times, most recently from aa02610 to d4e7296 Compare July 21, 2026 01:21
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from fe7126e to 1ad6dad Compare July 21, 2026 01:31
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch 2 times, most recently from 05198db to 941db22 Compare July 21, 2026 10:02
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from c2772ec to 0345cb7 Compare July 21, 2026 10:13
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 941db22 to fd5ac9c Compare July 21, 2026 10:13
@szijpeter
szijpeter marked this pull request as ready for review July 21, 2026 15:11
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 0345cb7 to 1b0a1d3 Compare July 21, 2026 15:38
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from b55b18b to 4bdaea9 Compare July 21, 2026 15:50
@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch from 1b0a1d3 to 05abf2b Compare July 22, 2026 12:02
@szijpeter
szijpeter force-pushed the feature/wal-995-openid4vci-auth-code branch from 2f63261 to a27d72e Compare July 22, 2026 12:13
@sonarqubecloud

Copy link
Copy Markdown

@szijpeter
szijpeter force-pushed the fix/wal-1158-openid4vci-nonce-endpoint branch 3 times, most recently from bff82e2 to 693fe56 Compare July 22, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci:mobile Run mobile related CI workflows for this PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant