Configuring OAuth 2.0 Rich Authorization Requests (RAR) and OpenID for Verifiable Credential Issuance
OAuth 2.0 Rich Authorization Requests
OAuth 2.0 Rich Authorization Requests RAR is an extension of the OAuth 2.0 framework. It enables clients to request additional information or attributes about a user or resource during authorization. This additional information allows the authorization server to make more informed decisions, enabling fine-grained access control.
In the OAuth 2.0 framework, a client typically requests permission to access a user’s resources on their behalf. With RAR, the client can also request additional details about the user or resource, such as location, device type, or group membership. The authorization server can then use this information to make more informed authorization decisions.
RAR is a prerequisite for Verifiable Credential Issuance, which is discussed in the following section.
Configuring provider.yml
- The definition configuration defines new set of configuration parameters called
authorization_details_types_supported
,authorization_details_types_schema
,ignore_unknown_authorization_details_type
. - authorization_details_types_supported indicates the supported types of authorization details. This parameter also defines the strategy for computing the identifier for each incoming authorization_details.
default - A hash of specific fields in the JSON payload.
sha512 - A SHA 512 hash of the entire payload.
custom - Requires an inline JavaScript function that is provided in the script field. - authorization_details_types_schema is an array of authorization_details_types. This parameter references a JSON schema file which is used to validate incoming authorization_details.
# Copyright contributors to the IBM Verify Identity Access OIDC Provider Resources project
version24.12
logging
level debug
definition
id1
name OIDC Definition
grant_types
authorization_code
password
client_credentials
implicit
refresh_token
urn:ietf:params:oauth:grant-type:token-exchange
authorization_details_types_supported
type payment_initiation
strategy default
type account_information
strategy sha512
type openid_credential
strategy custom
script
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils);
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils);
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.SignHelper);
var ads = stsuu.getContextAttributes().getAttributeValueByName("authorization_details");
StringSigningHelper.calculateHash("testuser123","SHA512")
ignore_unknown_authorization_details_typefalse
authorization_details_types_schema
type payment_initiation
content'@schema/payment_initiation.json'
type account_information
content'@schema/account_information.json'
type openid_credential
content'@schema/openid_credential.json'
pre_mappingrule_id isvaop_pretoken # Pre-Token mapping rule ID.
post_mappingrule_id isvaop_posttoken
base_url https //isvaop.ibm.com 445/isvaop
token_settings# Token Settings
issuer https //isvaop.ibm.com # OP's issuer URI.
signing_alg PS256 # Signing algorithm for ID token generated.
signing_keystore isvaop_signing # Signing keystore name.
signing_keylabel jwtsigning # Signing key label.
attribute_map# Attribute mapping to resolve claims. also refer to attributesources.yml
surname surname
server
ssl
key ks isvaop_keys/httpserverkey
certificate ks isvaop_keys/httpservercert
jwks
signing_keystore isvaop_signing
secrets
obf_key"ENC:iUt+3MzCntxSL2FPTUuJqER79UaiRSApMz3cbgJm4yzuiv6H7KN8ADsamX6+Qre1oTsATjnb1bJ0Lmi7WWfxWeGT477yqqvgVayFlCDIFzZeNkdINjASfTE3B+/3Sm9YjIYuWtZdySiXeydhJXSiOGU9osdA9g2BZXR4eMrXNutCuaSvFH6MY+TyOH5q15vy6vEWOebJQHrnug0A8rN6NF8G8XaxCe/+yqH57jJpdhm0N7iUydIYOBOQ1wDgCc8nRMWkQqlkcRhDZvLLAIlhoshYvo06ubyryt8/vv/0AvTLq9AIiQoL8CtYLr+SNZlzWe4CnHYZdO9S+AIrUOVORw=="
enc_key"@keys/private.pem"
Configuring the static client
authorization_details_types
indicates the list of supported types specific to a client.
# Copyright contributors to the IBM Verify Identity Access OIDC Provider Resources project
clients
client_id clientRAR
client_secret"OBF:U2FsdGVkX19iBhlwc53QkybjO6RjFHhSbz4VRudYHA=" # Client secret that is used for client authentication and/or JWT signing/encryption. `OBF:` indicates obfuscated string.
client_name clientRAR # Name of the client.
client_id_issued_at 1642399207 # Timestamp (in seconds) from when the client is created.
enabled true # Set to `true` to enable this client
grant_types# Grant type that the client is allowed to use at the token endpoint.
authorization_code
password
client_credentials
implicit
refresh_token
urn:openid:params:grant-type:ciba
urn:ietf:params:oauth:grant-type:token-exchange
response_types# Response type that the client is allowed to use at the authorization endpoint.
code id_token
code
code token
none
code token id_token
redirect_uris# Redirection URI strings for use in redirect-based flows such as the authorization code and implicit flows.
https://www.rp.com/redirect
request_uris# Request URIs that are pre-registered by the Relying Party for use at the OIDC Provider.
https://www.rp.com/request/test.jwt
scopes# A list of scope values that the client can use when requesting access tokens.
cdr:registration
openid
profile
jwks_uri https //www.rp.com/oidc/endpoint/default/jwks
id_token_signed_response_alg PS512
token_endpoint_auth_method client_secret_post
token_exchange_settings
client_groups
benefits
insurance
supported_subject_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
supported_actor_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
supported_requested_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
authorization_details_types
payment_initiation
account_information
openid_credential
Dynamic client request
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/register' \
--header 'Content-Type: application/json' \
--data '{
"redirect_uris": [
"https://www.google.com"
],
"grant_types": [
"authorization_code",
"client_credentials"
],
"response_types": [
"code"
],
"authorization_details_types":["account_information","openid_credential"],
"token_endpoint_auth_method": "client_secret_post"
}'
Authorization code request with RAR
curl --location ' https://isvaop.ibm.com:445/isvaop/oauth2/authorize' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=clientRAR' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'scope=test' \
--data-urlencode 'redirect_uri=https://www.google.com' \
--data-urlencode 'response_type=code' \
--data-urlencode 'authorization_details=[{
"actions": null,
"type": "account_information",
"locations": [
"https://example.com/payments"
],
"identifier": "",
"privileges": null,
"instructedAmount": {
"currency": "EUR",
"amount": "723.50"
},
"creditorName": "Merchant A",
"creditorAccount": {
"bic":"ABCIDEFFXXX",
"iban": "DE02100100109307118603"
},
"datatypes": null,
"remittanceInformationUnstructured": "Ref Number Merchant"
}]'
Token request with RAR
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=clientRAR' \
--data-urlencode 'client_secret=asfasdfawqdewq' \
--data-urlencode 'grant_type=authorization_code' \
--data-urlencode 'code=9CowFNlxxbTcTtiMFWuMlVmLKJBa6zR_fkrQ2w7xWzk.DKAX-67L3PqrBaeVmLGhkjbFI5DkOPn4dYqJdq8_6maAUXRZG4ajyIUH4VouwcLYsbUAXlMpIxhESAXJbHvzAQ' \
--data-urlencode 'redirect_uri=https://www.google.com'
OpenID for Verifiable Credential Issuance
- OpenID for Verifiable Credential Issuance is an extension of the OpenID standard. It enables users to log in to websites and applications by using their digital credentials, such as Verifiable Credentials. This allows users to access services and information that are secured by their digital credentials, without having to remember multiple usernames and passwords.

Configuring provider.yml
- The definition configuration defines a new grant_type
urn:ietf:params:oauth:grant-type:token-exchange
.
# Copyright contributors to the IBM Verify Identity Access OIDC Provider Resources project
version24.12
logging
level debug
definition
id1
name OIDC Definition
grant_types
authorization_code
password
client_credentials
implicit
refresh_token
urn:ietf:params:oauth:grant-type:token-exchange
urn:ietf:params:oauth:grant-type:pre-authorized_code
pre_mappingrule_id isvaop_pretoken # Pre-Token mapping rule ID.
post_mappingrule_id isvaop_posttoken
base_url https //isvaop.ibm.com 445/isvaop
token_settings# Token Settings
issuer https //isvaop.ibm.com # OP's issuer URI.
signing_alg PS256 # Signing algorithm for ID token generated.
signing_keystore isvaop_signing # Signing keystore name.
signing_keylabel jwtsigning # Signing key label.
attribute_map# Attribute mapping to resolve claims. also refer to attributesources.yml
surname surname
pre_auth_settings
pre_authorized_code_lifetime_in_secs1800
require_transaction_codetrue
transaction_code_charset123456789
transaction_code_length4
credential_issuer_jwks_uri_map
https://www.ibm.com https //test.com/jwks
https://test.com https //test.com/default/jwks
server
ssl
key ks isvaop_keys/httpserverkey
certificate ks isvaop_keys/httpservercert
jwks
signing_keystore isvaop_signing
secrets
obf_key"ENC:iUt+3MzCntxSL2FPTUuJqER79UaiRSApMz3cbgJm4yzuiv6H7KN8ADsamX6+Qre1oTsATjnb1bJ0Lmi7WWfxWeGT477yqqvgVayFlCDIFzZeNkdINjASfTE3B+/3Sm9YjIYuWtZdySiXeydhJXSiOGU9osdA9g2BZXR4eMrXNutCuaSvFH6MY+TyOH5q15vy6vEWOebJQHrnug0A8rN6NF8G8XaxCe/+yqH57jJpdhm0N7iUydIYOBOQ1wDgCc8nRMWkQqlkcRhDZvLLAIlhoshYvo06ubyryt8/vv/0AvTLq9AIiQoL8CtYLr+SNZlzWe4CnHYZdO9S+AIrUOVORw=="
enc_key"@keys/private.pem"
Configuring the static client
- A new property
act_as_credential_issuer
to indicates if the client act as credential issuer client
# Copyright contributors to the IBM Verify Identity Access OIDC Provider Resources project
clients
client_id clientVerifiableCredential
client_secret"OBF:U2FsdGVkX19iBhlwc53QkybjO6RjFHhSbz4VRudYHA=" # Client secret that is used for client authentication and/or JWT signing/encryption. `OBF:` indicates obfuscated string.
client_name clientVerifiableCredential # Name of the client.
client_id_issued_at 1642399207 # Timestamp (in seconds) from when the client is created.
enabled true # Set to `true` to enable this client
grant_types# Grant type that the client is allowed to use at the token endpoint.
authorization_code
password
client_credentials
implicit
refresh_token
urn:openid:params:grant-type:ciba
urn:ietf:params:oauth:grant-type:token-exchange
urn:ietf:params:oauth:grant-type:pre-authorized_code
response_types# Response type that the client is allowed to use at the authorization endpoint.
code id_token
code
code token
none
code token id_token
redirect_uris# Redirection URI strings for use in redirect-based flows such as the authorization code and implicit flows.
https://www.rp.com/redirect
act_as_credential_issuer true
authorization_details_types# Supported authorization details type
openid_credential
request_uris# Request URIs that are pre-registered by the Relying Party for use at the OIDC Provider.
https://www.rp.com/request/test.jwt
scopes# A list of scope values that the client can use when requesting access tokens.
cdr:registration
openid
profile
jwks_uri https //www.rp.com/oidc/endpoint/default/jwks
id_token_signed_response_alg PS512
token_endpoint_auth_method client_secret_post
token_exchange_settings
client_groups
benefits
insurance
supported_subject_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
supported_actor_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
urn:x-oath:params:oauth:token-type:device-secret
supported_requested_token_types
urn:ietf:params:oauth:token-type:access_token
urn:ietf:params:oauth:token-type:refresh_token
urn:ietf:params:oauth:token-type:id_token
Dynamic client request
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/register' \
--header 'Content-Type: application/json' \
--data '{
"redirect_uris": [
"https://www.google.com"
],
"grant_types": [
"authorization_code",
"client_credentials"
],
"response_types": [
"code"
],
"authorization_details_types":["account_information","openid_credential"],
"act_as_credential_issuer":true,
"token_endpoint_auth_method": "client_secret_post"
}'
Pre-Authorized code Flow
- In the context of verifiable credential issuance, a pre-authorized code is used to authorize the client application to issue verifiable credentials on behalf of the user. This allows the user to grant the application permission to access their personal data and issue verifiable credentials without sharing their credentials with the issuer. The pre-authorized code is an important component of the pre-authorized code flow in OAuth 2.0, and it enables secure and seamless access to personal data and verifiable credentials.
- Before initiating the flow with the Wallet, the Credential Issuer must perform preparatory steps, such as, end-user authentication and authorization. Consequently, the Credential Issuer sends the Pre-Authorized Code to the Wallet. This flow does not use the Authorization Endpoint. Instead, the Wallet exchanges the Pre-Authorized Code for the Access Token directly at the Token Endpoint. The Access Token is subsequently used to request Credential issuance at the Credential Endpoint.

- User information is collected, and the pre-authorized code is generated.
- This is a sequence diagram once the Pre-Authorized code is received by the Credential issuer.

Configuring mapping rule
- A new mapping rule called preauth_userauth.js is invoked to perform user authentication and authorization. It can be an LDAP lookup or HTTPCallout.
- A callbackURL is published as a part of the mapping rule invocation. After the user is authenticated, the callbackURL can be invoked with the status to indicate the status (success or failure).
- preauth_userauth.js sample
/**
* Copyright contributors to the IBM Verify Identity Access OIDC Provider Resources project
*/
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils);
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.OAuthMappingExtUtils);
importClass(Packages.com.ibm.security.access.httpclient.HttpClient);
IDMappingExtUtils.traceString("CallbackURL$$" + preauth.getCallbackURL() + '$$');
var payload = preauth.getPayload();
if(payload["type"] == "http"){
var headers = new Headers();
//Perform a HTTP Callout, if it comes back successfully, user metadata is populated.
headers.addHeader('Content-Type','application/json');
var payload = preauth.getPayload();
payload["callbackURL"] = preauth.getCallbackURL()
IDMappingExtUtils.traceString("payload: " + JSON.stringify(payload));
let resp = HttpClientV2.httpPost("https://host.docker.internal/userauth", headers, JSON.stringify(payload), null, null, null, null, null, null, null, null, true, null)
if (resp.hasError()) {//getError
IDMappingExtUtils.traceString("resp.getError(): " + resp.getError());
} else {
IDMappingExtUtils.traceString("StatusCode: " + resp.getCode());
if(resp.getCode() == 200){
IDMappingExtUtils.traceString("hERE: ");
var metadata = {};
metadata.uid = "prabbit";
metadata.given_name = "peter";
metadata.family_name = "rabbit";
metadata.preferred_username = "peter@zoo.org";
IDMappingExtUtils.traceString("approved: ");
preauth.approved(metadata);
}
}
}
//IDMappingExtUtils.traceString("preauth.isCallback(): " + preauth.isCallback());
else{
if (preauth.isCallback()) {
if (payload.status === "approved") {
var metadata = {};
metadata.uid = "prabbit";
metadata.given_name = "peter";
metadata.family_name = "rabbit";
metadata.preferred_username = "peter@zoo.org";
preauth.approved(metadata);
} else if (payload.status === "denied") {
IDMappingExtUtils.traceString("denied " );
preauth.denied();
} else {
OAuthMappingExtUtils.throwSTSCustomUserMessageException("Expecting authentication status", 400, "invalid_request");
}
} else if (preauth.isCallback() == undefined){
IDMappingExtUtils.traceString("else if " );
if (payload.status === "undefinedapproved") {
var metadata = {};
metadata.uid = "prabbit";
metadata.given_name = "peter";
metadata.family_name = "rabbit";
metadata.preferred_username = "peter@zoo.org";
preauth.approved(metadata);
} else if(payload.status === "denied"){
IDMappingExtUtils.traceString("denied " );
preauth.denied();
}
else{
//A callback url is published, once user is authenticated successfully, the callback URL can be called with the approved status to complete the flow.
IDMappingExtUtils.traceString("pending " );
IDMappingExtUtils.traceString("CallbackURL:::" + preauth.getCallbackURL() + ':::');
preauth.pending();
}
} else {
IDMappingExtUtils.traceString("else " );
IDMappingExtUtils.traceString("$$CallbackURL" + preauth.getCallbackURL() + '$$');
preauth.pending(); // for initial request, we return pending first
}
}
- preauth_notifytxcode.js sample
- This mapping rule is invoked to be able to deliver the transaction code to the user.
importClass(Packages.com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils);
importClass(Packages.com.ibm.security.access.httpclient.HttpClient);
var headers = new Headers();
headers.addHeader('Content-Type','application/json');
var payload = preauth.getTransactionCode();
payload["callbackURL"] = preauth.getCallbackURL()
IDMappingExtUtils.traceString("payload: " + JSON.stringify(payload));
let resp = HttpClientV2.httpPost("https://gateway.sms.com", headers, JSON.stringify(payload), null, null, null, null, null, null, null, null, true, null)
if (resp.hasError()) {//getError
IDMappingExtUtils.traceString("resp.getError(): " + resp.getError());
}
IDMappingExtUtils.traceString("CODE$$" + preauth.getTransactionCode()+"$");
Preauthorized request
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/preauth' \
--header 'Content-Type: application/json' \
--data-raw '{
"user.email": "john.does@gmail.com"
}'
- The mapping rule is triggered, and a callback URL is now available. After the user is authenticated, the callback URL needs to be invoked.
Callback request
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/preauth?stateId=b1444419-81df-4377-9a0d-5af4d10b64ae' \
--header 'Content-Type: application/json' \
--data '{
"status": "approved"
}'
- If the status is approved in the mapping rule, user-related data can be populated.
- The transaction code is now generated and the preauth_notifytxcode.js is invoked. The transaction code can be sent via an SMS gateway to the end-user.
Token request
curl --location 'https://isvaop.ibm.com:445/isvaop/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=clientVerifiableCredential' \
--data-urlencode 'client_secret=asfasdfawqdewq' \
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:pre-authorized_code' \
--data-urlencode 'scope=openid tpin' \
--data-urlencode 'pre-authorized_code=0QssrwwbDhAT5lfqiNupYQynknXkzWhE9B7_euPFI4Q.jJ2DPI-p7zFXudQ82LeS__cG9m8KYXnF_EPjP6Zze3zU--4P2L0jFhILqEEuQTrmOBvlnasirqWJf77nRE8e7w' \
--data-urlencode 'redirect_uri=https://www.google.com' \
--data-urlencode 'authorization_details=[{
"type": "openid_credential",
"credential_configuration_id": "ABCDEFGHIJKLMNOPQRS",
"claims": {
"org.iso.18013.5.1": {
"given_name": {},
"family_name": {},
"birth_date": {}
},
"org.iso.18013.5.1.aamva": {
"organ_donor": {}
}
}
}]' \
--data-urlencode 'tx_code=6127'
Token response
{
"access_token": "YGoE9kZdoYea0C4CQz64inGRgZa7YXYA32a4Xr5_wYo.Hl0Kba71Z5hXAfxBTMMmFBJRmGVV6TPc2gpG4pifoxuY2qRKa3LesU3DmXjTxYp0jW0GEYceYolvhBBiBZWZaQ",
"authorization_details": [
{
"actions": null,
"claims": {
"org.iso.18013.5.1": {
"birth_date": {
"date": "13th Jan 1956"
},
"family_name": {
"name": "Doe"
},
"given_name": {
"name": "John"
}
},
"org.iso.18013.5.1.aamva": {
"organ_donor": {
"name": "Jane Doe"
}
}
},
"credential_configuration_id": "ABCDEFGHIJKLMNOPQRS",
"datatypes": null,
"identifier": "",
"locations": null,
"privileges": null,
"type": "openid_credential"
}
],
"c_nonce": "WsRJdk9vGd_wJ-M344ElkerLhe0PgkgyTY3jY7EC_bI",
"c_nonce_expires_in": 3600,
"expires_in": 7200,
"refresh_token": "u6oy_uI6FRSNMMDfd9rwDnws9ddyYT8EabxB3IHrrjc.f1aXOxYhNfauCSdx50vusC__AxT_LZzSt9z-hHcjlojJBDJeQLqTnF094AKf0Kx_HZwU3JQbcpElgZPknHLt7g",
"scope": "openid",
"token_type": "bearer"
}
Note
RAR and VC require
Updated 9 days ago