Skip to content

fix(verifier): harden trust validation and presentation handling - #136

Merged
Mortega5 merged 11 commits into
mainfrom
fix/gaiax-chain-trust-bypass
Oct 27, 2026
Merged

Mortega5 merged 11 commits into
mainfrom
fix/gaiax-chain-trust-bypass

Conversation

@Mortega5

Copy link
Copy Markdown
Collaborator

Summary

  • Enforce the configured Gaia-X trust checks when validating credentials.
  • Use the configured default scope in same-device flows when no scope is supplied.
  • Associate returned credentials with configured DCQL queries or Presentation Exchange descriptors, rejecting unknown associations and ignoring credential types not configured for inclusion.
  • Decode Base64URL-encoded presentation_submission values and validate the definition ID and supported descriptor paths.
  • Support recursively nested path_nested entries, including credential-relative selectors.

Validation

  • go test ./common ./openapi ./verifier
  • go test ./openapi

Notes

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.

@Mortega5 Mortega5 added the minor Should be applied for new functionality or bigger updates. label Oct 27, 2026
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.
@Mortega5
Mortega5 force-pushed the fix/gaiax-chain-trust-bypass branch from c70868d to ca44a7f Compare October 27, 2026 12:01

@vramperez vramperez left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Comment thread verifier/verifier.go Resolved
Comment thread verifier/verifier.go Resolved
Comment thread verifier/verifier.go
**/
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 {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

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.

Comment thread verifier/verifier.go Resolved
Comment thread openapi/api_api.go Resolved
Comment thread openapi/api_api.go Resolved
@Mortega5
Mortega5 requested a review from vramperez October 27, 2026 13:04
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.
@Mortega5
Mortega5 merged commit c5a8ba7 into main Oct 27, 2026
16 of 17 checks passed
@Mortega5
Mortega5 deleted the fix/gaiax-chain-trust-bypass branch October 27, 2026 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

minor Should be applied for new functionality or bigger updates.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants