Repository navigation
fix(verifier): harden trust validation and presentation handling - #136
Conversation
Reject same-device sessions for unknown clients, enforce configured credential types, and always run trust validators instead of the Gaia-X chain bypass. Add regression tests for unknown clients and untrusted Gaia-X credentials
Resolve the client's configured default scope when /samedevice omits scope. Reject explicitly empty scopes and return a client error when no default is available.
Associate returned credentials with configured DCQL query or Presentation Exchange descriptor IDs. Reject unknown or missing request associations and ignore credentials whose types are not configured for token inclusion.
Decode Base64URL Presentation Exchange submissions, validate definition IDs and credential paths, and keep DCQL and descriptor associations distinct.
Allow recursive Presentation Exchange path_nested chains while retaining strict path validation, with regression tests.
c70868d to
ca44a7f
Compare
vramperez
left a comment
There was a problem hiding this comment.
Thanks for hardening this! The Gaia-X chain bypass removal looks right; a few comments below, mainly a regression in the cross-device v1 flow.
| **/ | ||
| func (v *CredentialVerifier) StartSameDeviceFlow(host string, protocol string, state string, redirectPath string, clientId string, nonce string, requestMode string, scope string, requestProtocol string) (authenticationRequest string, err error) { | ||
| logging.Log().Debugf("Initiate samedevice flow for %s - %s.", host, clientId) | ||
| if _, err = v.credentialsConfig.RequiredCredentialTypes(clientId, scope); err != nil { |
There was a problem hiding this comment.
An unknown client/scope is a client error, but this error propagates to StartSIOPSameDevice, which answers 500 and echoes err.Error() (e.g. "no service X configured"). Return a typed error and map it to 400 with a generic message.
There was a problem hiding this comment.
Fixed in e2f4ea4. Unknown clients and scopes now return a typed error, which the same-device endpoint maps to HTTP 400 with a generic message rather than exposing configuration details.
There was a problem hiding this comment.
Thanks — the DB-backed config is covered, but cacheBasedCredentialsConfig.RequiredCredentialTypes (used with static config / credentials-config-service) still returns "no service %s configured" and the raw ErrorNoSuchScope, so that backend still yields a 500 with the internal message. Please wrap both with ErrorUnknownClientOrScope there too.
There was a problem hiding this comment.
Good catch. Confirmed that the cache-backed implementation could return an untyped error for an unknown service and the raw missing-scope error. Both cases now wrap ErrorUnknownClientOrScope, so the existing handler returns HTTP 400 with a generic client-facing message. I added regression tests for both cases and the tracked Go package suite passes. The fix is in my local worktree and has not been committed or pushed yet.
Fix DCQL type_values validation for JWT-VC credentials and update integration fixtures to use type_values instead of SD-JWT vct_values. Add query validation and numeric precision regression tests.
Summary
presentation_submissionvalues and validate the definition ID and supported descriptor paths.path_nestedentries, including credential-relative selectors.Validation
go test ./common ./openapi ./verifiergo test ./openapiNotes
Descriptor paths are validated against the supported path forms. This change does not evaluate arbitrary JSONPath expressions or verify that credential-relative paths resolve to an existing claim.