Skip to content

Feat/handle deny consent 2 - #33

Open
grahamallen-1 wants to merge 2 commits into
stateofca:mainfrom
spruceid:feat/handle-deny-consent-2
Open

grahamallen-1 wants to merge 2 commits into
stateofca:mainfrom
spruceid:feat/handle-deny-consent-2

Conversation

@grahamallen-1

Copy link
Copy Markdown
Contributor

Handle deny-consent (access_denied) on the OID4VP response endpoint

Summary

When a user declines to share their credentials, the wallet returns an OAuth access_denied error to the verifier instead of a vp_token. Today OpenCred does not recognize that response: it falls through to vp_token extraction and the exchange is left hanging until it times out or the user intervenes. This teaches the standard OID4VP response handler to treat a returned error as a completed-but-failed presentation, so the verifier can surface an error and clean up its state immediately.

What changes

In handleAuthorizationResponse (lib/workflows/profiles/native-oid4vp-standard.js), before extracting the vp_token: if the response body carries a string error, validate that the returned state matches the authorization request, then mark the exchange invalid and record the error under the current step's results (bumping the sequence). A mismatched state throws, as elsewhere in this handler. This runs after the dc_api.jwt decrypt step, so it applies to both encrypted and plain responses.

The exchange moving to invalid with the error recorded is what lets the frontend show the user a clear "you declined / cancelled" message instead of spinning until the exchange TTL expires.

Paired wallet change

This is the verifier half of a wallet-side change. The wallet (sprucekit-mobile 0.21.1) exposes a denyPermission API that POSTs to the response endpoint with error=access_denied and state={state}, informing the verifier that the user cancelled. Wallet PR summary:

A user can decide to deny consent while presenting their credentials. The verifier app needs to be made aware of this choice so it can clean up local state and display an error message. Without responding to the denial, the verifier app is left on its own and requires a timeout or user intervention. The access_denied error code specifies that "The End-User did not give consent to share the requested Credentials with the Verifier." Consume sprucekit-mobile/0.21.1, which exposes the denyPermission API that will POST /response with error=access_denied and state={state}.

Tests

Adds test/unit/workflows/61-oid4vp-standard-deny-consent.test.js:

  • a returned error marks the exchange invalid, records the error, and bumps the sequence
  • the error is recorded under the current step
  • a mismatched state throws

Verified: lint clean; unit suite green; the new tests fail against the pre-change handler.

References

OAuth 2.0 (RFC 6749) — the access_denied error code ("The resource owner or authorization server denied the request"): §4.1.2.1 and §5.2
https://www.rfc-editor.org/rfc/rfc6749#section-4.1.2.1

OpenID Connect Core 1.0 — access_denied in the authentication error response ("The End-User ... did not consent"): §3.1.2.6
https://openid.net/specs/openid-connect-core-1_0.html#AuthError

OpenID for Verifiable Presentations 1.0 — the authorization error response returned to the verifier (error + state), including delivery over direct_post:
https://openid.net/specs/openid-4-verifiable-presentations-1_0.html

Wallet change: sprucekit-mobile 0.21.1 denyPermission (POSTs error=access_denied + state to the response endpoint).

This branch has not been deployed

No deployments
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.

1 participant