Skip to content

OpenID4VCI: add authorization_request_params to requestCredential for issuer-specific authorization parameters #4328

@reinkrul

Description

@reinkrul

Context

Follow-up to the OpenID4VCI client work (#4316). While integrating a Nuts node with the AET ZORG-ID issuer, we found that AET's authorization server (OpenIddict) needs an extra query parameter on the authorization request to start smartcard login. From AET's docs:

In order to use the ZORG-ID smartcard an extra redirect parameter needs to be added to the redirect in the authorize call: auth_method=SmartCard.

The Nuts requestCredential API could not add this parameter, so the redirect to AET never carried auth_method=SmartCard and the smartcard app (zorgid://) was never launched.

Problem

The requestOpenid4VCICredentialIssuance request body has one field for passing extra parameters, credential_request_params, but it only affects the Credential Request (the call to the credential endpoint, auth/openid4vci/client.go -> RequestCredential). It does not affect the authorization request.

The authorization request query is a fixed list, built in RequestOpenid4VCICredentialIssuance (auth/api/iam/openid4vci.go:131): response_type, state, client_id, client_id_scheme, authorization_details, redirect_uri, code_challenge, code_challenge_method. There is no way for the caller to add anything to it.

Field Affects which request Can add to the authorize redirect?
credential_request_params Credential Request (POST to credential endpoint) No
(nothing today) Authorization request --

So any issuer that needs an extra authorization parameter (AET's auth_method, and probably others) cannot be used through Nuts.

The ideal way to pass such information is the standard authorization_details (RFC 9396), which Nuts already sends. AET does not accept the smartcard selection there; it requires a separate top-level auth_method query parameter. This field is the workaround for issuers that, like AET, do not support the standard mechanism.

Proposed change

Add a new optional field authorization_request_params to the requestCredential body. The node adds these key/value pairs to the authorization request, the same way credential_request_params works for the credential request. They are applied after the node's own parameters, so if the caller passes a key the node also sets, the caller's value is used. The caller is responsible for the result.

OpenAPI (docs/_static/auth/v2.yaml, requestOpenid4VCICredentialIssuance body):

authorization_request_params:
  type: object
  additionalProperties:
    type: string
  description: |
    Optional key/value pairs added to the OpenID4VCI authorization request (the redirect to the
    Authorization Server's authorization_endpoint). If a key is also set by the node, the value given here is used.
    Prefer authorization_details (RFC 9396) where the issuer supports it; use this only for issuers that require
    non-standard authorization parameters.
  example: |
    { "auth_method": "SmartCard" }

Handler (auth/api/iam/openid4vci.go, just before the redirect URL is built):

// Optional caller-supplied authorization request parameters, for issuers that need extras
// (e.g. auth_method=SmartCard). Applied after the node's own parameters, so caller values win.
if request.Body.AuthorizationRequestParams != nil {
    for key, value := range *request.Body.AuthorizationRequestParams {
        authzParams[key] = value
    }
}

Request example:

{
  "issuer": "https://issuer.example.com/oauth",
  "wallet_did": "did:web:example.com",
  "authorization_details": [ { "type": "openid_credential", "credential_configuration_id": "HealthcareProfessionalDelegationCredential" } ],
  "redirect_uri": "https://example.com/oauth2/org1/callback",
  "authorization_request_params": { "auth_method": "SmartCard" }
}

Resulting redirect: .../oauth/connect/authorize?...&auth_method=SmartCard.

Scope

  • docs/_static/auth/v2.yaml -- new request-body field; run make gen-api (regenerates auth/api/iam/generated.go, e2e-tests/browser/client/iam/generated.go).
  • auth/api/iam/openid4vci.go -- add the parameters in RequestOpenid4VCICredentialIssuance.
  • Tests (auth/api/iam/openid4vci_test.go): check the parameter ends up in the redirect query.

Considerations

  • Naming follows credential_request_params. The first implementation on project-gf-pilot used the shorter authorization_params; rename it to authorization_request_params before it reaches master.
  • Because caller values are applied last, a caller could overwrite parameters the node sets (client_id, redirect_uri, etc.). This matches how credential_request_params already works. If we want to prevent this, we can deny a small set of keys (for example code_challenge).
  • Values are strings (map[string]string), since these are URL query parameters.
  • Separate from credential_request_params; the two apply to different requests and do not overlap.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions