Skip to content

fix: make VPResponse.VPToken spec-compliant (map[string][]string)#366

Closed
leifj wants to merge 1 commit into
SUNET:mainfrom
sirosfoundation:fix/vptoken-spec-compliance
Closed

fix: make VPResponse.VPToken spec-compliant (map[string][]string)#366
leifj wants to merge 1 commit into
SUNET:mainfrom
sirosfoundation:fix/vptoken-spec-compliance

Conversation

@leifj

@leifj leifj commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

VPResponse.VPToken was typed as map[string]string, but the OID4VP 1.0 spec (§8.1) requires each vp_token value to be an array of presentations.

When a spec-compliant wallet sends {"vp_token": {"pid_1_5": ["eyJ..."]}}, json.Unmarshal silently drops the entry because it cannot coerce []string into string, leaving the map empty and causing downstream "VP Token not found" errors.

Changes

  1. response_parameters.go — Changed VPToken from map[string]string to map[string][]string
  2. handlers_verifier.go — Updated map lookup to unwrap vpTokens[0] after length check
  3. handlers_verification.go — Same unwrap logic for the verifier handler
  4. response_parameters_additional_test.go — Updated test to use new array type

Fixes #365

OID4VP 1.0 §8.1 requires vp_token values to be arrays of presentations.
The previous map[string]string type caused json.Unmarshal to silently
drop array values from spec-compliant wallets, resulting in 'VP Token
not found' errors.

- Change VPToken from map[string]string to map[string][]string
- Update API gateway handler to unwrap first token from array
- Update verifier handler with same unwrap logic
- Update tests to use new type

Fixes SUNET#365
@sonarqubecloud

Copy link
Copy Markdown

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the OpenID4VP direct_post (JWE) response handling to align with OID4VP 1.0 §8.1 by modeling vp_token values as arrays, preventing silent JSON unmarshal drops from spec-compliant wallets.

Changes:

  • Change VPResponse.VPToken from map[string]string to map[string][]string to match the spec’s array-of-presentations requirement.
  • Update verifier/APIGW handlers to unwrap a token from the array after checking it’s non-empty.
  • Adjust the VPResponse marshal/unmarshal test to use the new array type.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
pkg/openid4vp/response_parameters.go Updates VPResponse vp_token type to map values as []string for spec compliance.
internal/apigw/apiv1/handlers_verifier.go Unwraps vp_token array entry when extracting the token for the credential query ID.
internal/verifier/apiv1/handlers_verification.go Unwraps vp_token array entry when extracting the token per scope.
pkg/openid4vp/response_parameters_additional_test.go Updates VPResponse test data to use map[string][]string and validates round-trip.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if !ok {
vpTokens, ok := vpResponse.VPToken[credQueryID]
if !ok || len(vpTokens) == 0 {
c.log.Error(nil, "VP Token not found for credential query", "query_id", credQueryID, "available_keys", vpResponse.VPToken)
if !ok || len(vpTokens) == 0 {
c.log.Error(nil, "VP Token not found for credential query", "query_id", credQueryID, "available_keys", vpResponse.VPToken)
return nil, fmt.Errorf("VP Token not found for credential query: %s", credQueryID)
}
if !ok || len(vpTokens) == 0 {
c.log.Error(nil, "VP token not found for scope", "scope", scope)
return nil, fmt.Errorf("VP token not found for scope: %s", scope)
}
@leifj

leifj commented May 8, 2026

Copy link
Copy Markdown
Contributor Author

Superceeded by #386

@leifj leifj closed this May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Make VPResponse.VPToken spec compliant.

2 participants