FAPI checklist

This checklist extends the minimal deployment checklist with the required configurations for setting up the Connect2id server for the FAPI Security Profile 1.0 - Part 2: Advanced, version 2021-03-12.

1. TLS terminator / HTTPS reverse proxy

  1. Make sure TLS 1.2 or later is used, and disable all weak ciphers.

    For OpenSSL (e.g. with Apache httpd):

    SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
    SSLProtocol -all +TLSv1.2
    
  2. Configure your TLS terminator / HTTPS reverse proxy to support client X.509 certificates. If a client certificate is found, it must be passed to the Connect2id server in a special HTTP header. Check the TLS guide for instructions.

2. Connect2id server configuration

Required Connect2id server configuration settings for conformance with FAPI Security Profile 1.0 - Part 2: Advanced. Assumes Connect2id server 11.6.

  1. Require registered redirection URIs to use the https scheme:

    op.reg.rejectNonTLSRedirectionURIs=true
    
  2. Make sure only PS256 or ES256 signed ID tokens can get issued:

    op.idToken.jwsAlgs=PS256,ES256
    
  3. Include a state hash in the issued ID tokens:

    op.idToken.includeStateHash=true
    
  4. Support and advertise one or more ACRs at LoA 2 or higher. Example configuration for some ACR:

    op.authz.advertisedACRs=urn:mace:incommon:iap:silver
    
  5. Allow only the code and code id_token response types:

    op.authz.responseTypes=code,code id_token
    
  6. Always require the redirect_uri parameter in authorisation requests, not only for OpenID authentication requests where the parameter is mandatory:

    op.authz.alwaysRequireRedirectURI=true
    
  7. Make sure only PS256 or ES256 signed request JWTs get accepted:

    op.authz.requestJWSAlgs=PS256,ES256
    
  8. Always require clients to submit a signed request JWT, either via the request or request_uri parameter:

    op.authz.alwaysRequireSignedRequestJWT=true
    
  9. Require an exp (expiration) claim in the request JWTs:

    op.authz.requireRequestJWTExpiration=true
    
  10. Require an nbf (not before) claim in the request JWTs:

    op.authz.requireRequestJWTNotBefore=true
    
  11. Set the maximum request JWT lifetime to 60 minutes, relative to the nbf claim:

    op.authz.maxLifetimeRequestJWTExpiration=3600
    op.authz.maxAgeRequestJWTNotBefore=3600
    
  12. Require all authorisation request parameters to be present in the request JWT:

    op.authz.requireAllParamsInRequestJWT=true
    
  13. All authorisation responses must be signed, either by means of JARM requested with response_mode=jwt or by means of a ID token in the front channel requested with response_type=code id_token:

    op.authz.alwaysRequireSignedResponse=true
    
  14. Prohibit clients to switch between the query and fragment response modes by setting the response_mode authorisation request parameter:

    op.authz.prohibitSwitchBetweenBasicResponseModes=true
    
  15. Allow only mTLS and private key JWT client authentication at the token endpoint. Note, mTLS authentication can be either configured in its PKI variant (tls_client_auth) or self-signed client X.509 certificate variant (self_signed_tls_client_auth), but not both.

    To allow private key JWT and self-signed certificate mTLS authentication:

    op.token.authMethods=private_key_jwt,self_signed_tls_client_auth
    

    To allow private key JWT and PKI mTLS authentication:

    op.token.authMethods=private_key_jwt,tls_client_auth
    
  16. Require clients to present an X.509 client certificate at the token endpoint to ensure the issued access tokens are certificate bound:

    op.token.requireClientX509Cert=true
    

The above configuration properties in one place for easy copying into a configuration file:

op.reg.rejectNonTLSRedirectionURIs=true
op.idToken.jwsAlgs=PS256,ES256
op.idToken.includeStateHash=true
# Set real ACR value(s):
op.authz.advertisedACRs=urn:mace:incommon:iap:silver
op.authz.responseTypes=code,code id_token
op.authz.alwaysRequireRedirectURI=true
op.authz.requestJWSAlgs=PS256,ES256
op.authz.alwaysRequireSignedRequestJWT=true
op.authz.requireRequestJWTExpiration=true
op.authz.requireRequestJWTNotBefore=true
op.authz.maxLifetimeRequestJWTExpiration=3600
op.authz.maxAgeRequestJWTNotBefore=3600
op.authz.requireAllParamsInRequestJWT=true
op.authz.alwaysRequireSignedResponse=true
op.authz.prohibitSwitchBetweenBasicResponseModes=true
op.token.authMethods=private_key_jwt,self_signed_tls_client_auth
# Alternative config to allow private key JWT and PKI mTLS authentication:
# op.token.authMethods=private_key_jwt,tls_client_auth
op.token.requireClientX509Cert=true

3. Authorisation

When authorising requests:

  • Make sure the end-user is authenticated at the configured LoA 2 or higher level and the acr parameter for the user session is set to it. This will also set the acr claim in the issued ID token.

  • Always require explicit consent by the end-user to authorise the requested scope if not previously authorised (the consent was persisted).

  • When submitting the consent make sure the access token type is set to identifier-based (access_token -> encoding).

4. FAPI certification test suite

We recommend running the FAPI certification tests before deploying into production a Connect2id server that needs to conform to the profile.

Note: As of May 2021, the certification suite has not been updated to the latest (final) FAPI version from 2021-03-12, which introduced additional checks and constraints. If you need to pass the current FAPI test suite with Connect2id server 11.6+ make sure the nbf claim is not required in request objects:

op.authz.requireRequestJWTNotBefore=false

To set up the certification tests two OAuth 2.0 clients need to be registered with the Connect2id server and their client_id's, redirection URIs and keys saved in the certification panel.

4.1 For client authentication type: private_key_jwt

Client 1

Sample client metadata to register the first client with the Connect2id server.

Note: The c2id in the redirection URI must be replaced with the test alias from certification panel.

{
   "preferred_client_id"             : "fapi_client_1",
   "grant_types"                     : [ "authorization_code", "refresh_token" ],
   "response_types"                  : [ "code", "code id_token" ],
   "redirect_uris"                   : [ "https://www.certification.openid.net/test/a/c2id/callback" ],
   "request_object_signing_alg"      : "PS256",
   "id_token_signed_response_alg"    : "PS256",
   "token_endpoint_auth_method"      : "private_key_jwt",
   "token_endpoint_auth_signing_alg" : "PS256",
   "jwks" : {
      "keys" : [ {
         "kty" : "RSA",
         "alg" : "PS256",
         "use" : "sig",
         "kid" : "GkHpinbDTETemwUJdv7VZ00IyQuKHkWCzRd58SHOhKE",
         "x5c" : [ "MIICrjCCAZagAwIBAgIIOwGKxqg9fJQwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA4NTMzNFoXDTIyMDUwNTA4NTMzNFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqVM3LZ1Bo25NvL5Zal9SCudKSk5qqe4DtmlBm8VN+XFDWfxWE4eCmg67xZxSOsPA6YgSQt6pOLW2TizM1LfjJCyjDjBYD0rJbzT5iR4a31OIf6qd4XohD6kLjVnrYhHWyDSTIqaStdeJnZTyNsVmFqvPvN438T9pTBm2F6wpWj5XGG4TCR0Uv666iT48oJVWeyvHczdTw8cPSQELHmBAKKzMWvxLOuJPBI2EAlVym4NUWqvrnOxlVxp00j2508YAjRTPQUnjAgUkFweIwWPWadjli5O3CSYbZ0HEMHIwTIFVSBdoYRnCfNPqP\/rbDGMAeE5ONto+DYtxOot870XoOQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCQiuvuFiiJeOy62E8\/3+0S7MWy1NyTeNzS6FO4OpKrjjDdTD3l9kR+rbbUAlh2wL2ZinRkCE\/hMAHtYMgC+gQOVYiKZr\/h1xqJ\/fSmtjSa12SEEojCR3gVSLbPTu3VBwAtoaJoh8v\/ATN8qWaez4oFpuIzTW88ATa16gGRtNmWbO7S5fO89QaAXot2QTYbfjXzLMuVfzGCwqRKtsbh5Vc2beUwXROj01hW7CNSIi8i8l\/dY4j1xtc2kIAG7IQsagyWxGHJn\/meRzX5H2bhsZCNfsB62jO3SUakhccjW\/DZdAqLkGcPvJlCkk5Ya+F2KHqmMK01OENqnxYgTWfPHz+t" ],
         "n"   : "qVM3LZ1Bo25NvL5Zal9SCudKSk5qqe4DtmlBm8VN-XFDWfxWE4eCmg67xZxSOsPA6YgSQt6pOLW2TizM1LfjJCyjDjBYD0rJbzT5iR4a31OIf6qd4XohD6kLjVnrYhHWyDSTIqaStdeJnZTyNsVmFqvPvN438T9pTBm2F6wpWj5XGG4TCR0Uv666iT48oJVWeyvHczdTw8cPSQELHmBAKKzMWvxLOuJPBI2EAlVym4NUWqvrnOxlVxp00j2508YAjRTPQUnjAgUkFweIwWPWadjli5O3CSYbZ0HEMHIwTIFVSBdoYRnCfNPqP_rbDGMAeE5ONto-DYtxOot870XoOQ",
         "e"   : "AQAB"
      } ]
   }
}

The private client JWK set:

{"keys":[{"d":"F5S-P30CEiefbeS4gSbrPxd88iI_mpDKNZItD-uHc3DBp3uL5UZe-uOIZPnjPcnbSOqpWGS3_mzYCcUVdZ5yZKxOvQAgk2if6vvesKjfpzBz9wuk1yzyA8NQF4xpSowfdFxWDWJTVj3BLY_7t4MAN7IPyUbNVay2FmISSPOyAp4n1w7FYPELFPcwB8rppT_3RTGu69ND0wQ9e_2hniSe2Z33LDHdi6e2kshgaa6U_ctLH1U7pU5DgBL50Ac65Ra-cCUJv8_0IyNAO6L_JonMiMtrNHBfQqSMqGIoYzEbIuApOr1_dBpXt33bNnAjwaWfbFT_d6FLC2kWBNsxUYaCMQ","e":"AQAB","use":"sig","kid":"GkHpinbDTETemwUJdv7VZ00IyQuKHkWCzRd58SHOhKE","x5c":["MIICrjCCAZagAwIBAgIIOwGKxqg9fJQwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA4NTMzNFoXDTIyMDUwNTA4NTMzNFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqVM3LZ1Bo25NvL5Zal9SCudKSk5qqe4DtmlBm8VN+XFDWfxWE4eCmg67xZxSOsPA6YgSQt6pOLW2TizM1LfjJCyjDjBYD0rJbzT5iR4a31OIf6qd4XohD6kLjVnrYhHWyDSTIqaStdeJnZTyNsVmFqvPvN438T9pTBm2F6wpWj5XGG4TCR0Uv666iT48oJVWeyvHczdTw8cPSQELHmBAKKzMWvxLOuJPBI2EAlVym4NUWqvrnOxlVxp00j2508YAjRTPQUnjAgUkFweIwWPWadjli5O3CSYbZ0HEMHIwTIFVSBdoYRnCfNPqP\/rbDGMAeE5ONto+DYtxOot870XoOQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCQiuvuFiiJeOy62E8\/3+0S7MWy1NyTeNzS6FO4OpKrjjDdTD3l9kR+rbbUAlh2wL2ZinRkCE\/hMAHtYMgC+gQOVYiKZr\/h1xqJ\/fSmtjSa12SEEojCR3gVSLbPTu3VBwAtoaJoh8v\/ATN8qWaez4oFpuIzTW88ATa16gGRtNmWbO7S5fO89QaAXot2QTYbfjXzLMuVfzGCwqRKtsbh5Vc2beUwXROj01hW7CNSIi8i8l\/dY4j1xtc2kIAG7IQsagyWxGHJn\/meRzX5H2bhsZCNfsB62jO3SUakhccjW\/DZdAqLkGcPvJlCkk5Ya+F2KHqmMK01OENqnxYgTWfPHz+t"],"dp":"ARzxFNlVnzztn6DbqFzV38jp-nKdFwxSVyWVWDv2059uzfELI5Sib1F5JxdzytdKMnG0AmzMMryRLnCJ0sqzg591zoQHVS_Moz_fl-PuPN-Sls85YbO2Qmf2voXKGRDkPX0JvXXwhNWxg1bQs5ueYR0S-yTO6NDvSL6sVBo21WE","dq":"Ltyh5WkbxDsq21LRsKpDy-sOxe6EkmD2yhqp90jdTlf9HCMzI2N0xzFVYS1wjdtyblYfecXr6JcWDGp_Mu7hOtjVtKMDRwtrjtJZu4GqKB9coOl8zhCAb172XqK4WoU3tms3E7lNTXleo3Zi2Zzi-Px1Y3NtRmks6hOkOkfqam0","n":"qVM3LZ1Bo25NvL5Zal9SCudKSk5qqe4DtmlBm8VN-XFDWfxWE4eCmg67xZxSOsPA6YgSQt6pOLW2TizM1LfjJCyjDjBYD0rJbzT5iR4a31OIf6qd4XohD6kLjVnrYhHWyDSTIqaStdeJnZTyNsVmFqvPvN438T9pTBm2F6wpWj5XGG4TCR0Uv666iT48oJVWeyvHczdTw8cPSQELHmBAKKzMWvxLOuJPBI2EAlVym4NUWqvrnOxlVxp00j2508YAjRTPQUnjAgUkFweIwWPWadjli5O3CSYbZ0HEMHIwTIFVSBdoYRnCfNPqP_rbDGMAeE5ONto-DYtxOot870XoOQ","p":"3mWdfsN9UylB_tCdDN9ngi0VWv-jo3F5V1rrkKGbxnJI4KltwWJaf-2iyEbvDuS2bTC-if7s558nz2QbkyQkJ8jrsEMA8tW3c-k-QTB9gWm6Decsbh8we33Gn6LTZjxWJnYIMbN_CxevopkB5CcDsYZRV0AKojhF_mfcs--PSs0","kty":"RSA","q":"wujDYlNMyaMmuVZu07HDXr-oaeKBC9YaNQU_s-GYfs-G7mjo4_OXFsvGqEO-nJYPRLdsN8gS0nGsMPGuLA_9THEmvWqPn0c4Iu3UMkpGT_281yQtSeUrIg9Eidrok3sjTFvJMt_t6epUI6EoFKldmG8Z8dBHYrTQud8vv3hiKx0","qi":"YBQ8whVPnhI7IWayhctFwfi7HkrIyTPTYWQfg4dndfNTA6HZ_87KUSF_vjZAG2n-8ifhczSMoxLqNNr3MhFRcAjUiSJxul_1d62jg4xRBCcSv2UN6Lzg-thKDoXXNtfO9aAqdi91NTuobQYfg1m2UlJ21mSKDWAZreyterxEyxs","alg":"PS256"}]}

The PEM-encoded client certificate:

-----BEGIN CERTIFICATE-----
MIICrjCCAZagAwIBAgIIEqd/vpy8MEkwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA4NTExMFoXDTIyMDUwNTA4NTExMFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnU8f74vvF5qkP3cmcNmMQo2DJj00eZWJ28QQJNNpL83o0SNN2q/neCdBPhFqldHhTpu5p2Nyedvn1lCZqkNNPX7pKinOBFMhBw68x/NLE+vXYMQBGr6x7dt2MtnHhrvJSEYIHQMaRY5ip6CiRF/ebrUv3j30jPQNQEwfdVzbTxWP24LksKkUj9y8e9XJlulqnMyYHWFOD++Q3atYAb5MqMHAe1UwQGQUTcPcx0b7jhlCq3wJYsCB1Mr+Es8FgD5tKKQVMapk9smrL2Guq+syk3kXyoA6AKjNxJwWIy/6kc9/UdD7BHHGAM4UVki/ZwyIYfw3djm/RwiVYkHRGRrAuQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBJ9955biRVt1Lo89Xg543np/RMJRCZ1kmqzuCqlJtsuI+8eYSWr0ilcjFRVZEXfGTU9ePyCTcCraXDv8MkSjFrf5a6Wf5/8iLiBmd2Cr6uyTcJ8it5Bqcrjk7YU7RCXXzJSk6/GETfvF7RCRTZccCV3UjV8Os5WbHPnp5fbfjqNGBxsmvEYEqKQLg4sLyXejwXYUfum+v+weF8W4EfaiPPFxGmcRtF/dYL3hxa5XG4RLfF7I1ODZ+x/MdXZcvGrEoxgpc8MoJKc6oRPtwSutPn0r/+Siw14kIXCE/jckm+HQ01Ts0AatTAI7/OiPepjlkgM8SZZGfFeIrjkkC/VnN/
-----END CERTIFICATE-----

The PEM-encoded private key:

-----BEGIN PRIVATE KEY-----
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCdTx/vi+8XmqQ/dyZw2YxCjYMmPTR5lYnbxBAk02kvzejRI03ar+d4J0E+EWqV0eFOm7mnY3J52+fWUJmqQ009fukqKc4EUyEHDrzH80sT69dgxAEavrHt23Yy2ceGu8lIRggdAxpFjmKnoKJEX95utS/ePfSM9A1ATB91XNtPFY/bguSwqRSP3Lx71cmW6WqczJgdYU4P75Ddq1gBvkyowcB7VTBAZBRNw9zHRvuOGUKrfAliwIHUyv4SzwWAPm0opBUxqmT2yasvYa6r6zKTeRfKgDoAqM3EnBYjL/qRz39R0PsEccYAzhRWSL9nDIhh/Dd2Ob9HCJViQdEZGsC5AgMBAAECggEAWm8egOwFa6BvRD0PUFkAlVIdT2JoRG1/b2PrlAAlvGG3smOFYm81tpF6pGAG0lJyIGrN9DjrmrqdMUvsy0EdqnjHOoIF+d6AYjpKtPhc9PrkOrDzoZh3WbKM5PbmCcLzGCWKjIM4Gzyb4poqLvyeNy7acf1UFaRH6erZOvNC8NchdL1I3SzovL7B/X3GlJBw2WUJ84CedLye82HHGi05duEODQcJPAzRaE3SMfGGA5xICRg/jKEVySSXYJiUwHDlCZoFoh/hvfpluYkhmECI6ISabglkCivNmIR8pYbWaQFt66NJNZLoC79Han2V6/iQX+Yo4qU74fPcyFXnjYlXMQKBgQDS1MvqNU3bEohKsoHrGAEKDr1EZRyUd31t+45AEsTnoKNumXKws26STzWB/IRu0+Vg7+C8vzqMSfAQYd2jBYLHBBvhE8zs4XQqafluhq9oTJEtIzrH/YQZbVAa2diEI92+/L/0rD6uipZzxuHcpjd2NbSxzzFLlgwF3knIgR8vKwKBgQC/At0neUdX+SlK6yrNDtrcC1e8krd2PIhKE1R+q7saQuPFDaK/dHTp3YLzGveocT0EL8SpXi9glfSOCjMKTa+gM2DThWg/GnFWIKe/MsgNunYSC5A6aCRaS2DR7vKMCbV5r8FGiSX69cX/PXouHD71XCbY83I+NVm9OrrolJs9qwKBgE54x+FHr8/PiQ0MfhDL4W8l50pyu/2CsBvkmqC8m69++fWrhaXBU3F/q/HS1FQP6Ht5LVPzdU5MIt9mHcGUxoVewSW4Yfj1PXCf+ygpV1Zh0VNUnodbk/SG3F7yIIWmd92jY6slBTuf97nmF6Ex+Mi12qin7rgshBMXFq1bagj7AoGAISZwF1+3AA+gGP6DaR9A4JufWHzmFkEfLiv4qBtJ157wRMy/CBdACy6EgYiWnsc4Xbekm/hapJqh3NzsSsd8yYLhNRScKQd/0ADO3CIGEkvgHfWfzGMym/ElFoov0hoFQt873fADhXCOMmQLBmGkk5SwsUpe82jy8CJ3OdJAtw0CgYB4nB44T9Sm7XE6TR1nmHhRlPnvKokZ8X7aYBTKvwTjvkFH5edzRP7O7oTyXtZWejLe3aoOn4OZb8vP5s8VLmbo8SPi3GrHXV21Jz46WrUe/5bbGNkcVY6mf1PZJ12Jsxtr7RkgjEryBKcgsiiqBt2USW4rtvMfTqG2Uf00NCD/4A==
-----END PRIVATE KEY-----

The client scope for the issued tokens can be set to:

openid offline_access

The resource URL can be set to the UserInfo endpoint of the Connect2id server, for example:

https://fapi.c2id.com/c2id/userinfo

Client 2

Sample client metadata to register the second client with the Connect2id server.

Note: The c2id in the redirection URI must be replaced with the test alias from certification panel.

{
   "preferred_client_id"             : "fapi_client_2",
   "grant_types"                     : [ "authorization_code", "refresh_token" ],
   "response_types"                  : [ "code", "code id_token" ],
   "redirect_uris"                   : [ "https://www.certification.openid.net/test/a/c2id/callback?dummy1=lorem&dummy2=ipsum" ],
   "request_object_signing_alg"      : "PS256",
   "id_token_signed_response_alg"    : "PS256",
   "token_endpoint_auth_method"      : "private_key_jwt",
   "token_endpoint_auth_signing_alg" : "PS256",
   "jwks" : {
      "keys" : [ {
         "kty" : "RSA",
         "alg" : "PS256",
         "use" : "sig",
         "kid" : "fapi-c43faf75-0fd9-470f-ab68-32d9e0d86b70",
         "x5c" : [ "MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8\/IUmWdtMzo3fAZTMYGbzaq\/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P\/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get\/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR\/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB" ],
         "n"   : "oRsAhgNZErbwhbPhJ6VzTGWqEH-qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN-c82Kwxtcqxok9nXhWKoJ-SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8_IUmWdtMzo3fAZTMYGbzaq_SiPV-C1j5ONOZid2sG-EAZvMOq1RFXr5UAt6b--QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv-o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P_4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQ",
         "e"   : "AQAB"
      } ]
   }
}

The private client JWK set:

{"keys":[{"d":"Wf5cZ3_9RM_-QaG-10e7xWRRAJBgE8ZcuyT405_op9nAWLUSb1mv4EMzl_rpXi9a4ec6SEF41YZttuvqZQaDINqLtVjHSkIAm8gicYG_y5W23Xn6bd-DhQS0CIyp0ficdNiT2gp3mrAn2W1-lSw7iZOL6hBA0KErcNB5jaxrDai0oxzHrdQpIPiLmwSpksimKMm8HNoIV5qIv6F1iIAexuyPrLZOfWWTGZsMVmTeaIWt-FXVf5I8D8pKDhX688H9BHSqbdhmx-JI2sfoM47VT2Na-d1y4WwmM2RhfcrSJqeqIb0K2cvBB_5gPlZowHKYazZWJwXg1kDsbWbwKx0UQQ","e":"AQAB","use":"sig","kid":"fapi-c43faf75-0fd9-470f-ab68-32d9e0d86b70","x5c":["MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8\/IUmWdtMzo3fAZTMYGbzaq\/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P\/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get\/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR\/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB"],"dp":"XVAz7y7ytSymr0G7XMuqW-BUS6zbw0Ej7MhgDSDHoqK-0KFt4B3MGTVshM1SUZlcOunW8Z-pnNREnt90r85jyuAXjYYTNBbV7gzoPB1UqDtdDRrHsx40ag_MgRNmpKkyDN0AVhfjpIncHY2nmhuU1XBb8x81KAsTIArXNSUHiJE","dq":"qwE_xNtjE9iBG1YGrA9qhC_4ARc8r1WBjWMZeaN230N5rXTNvn2f-leKmSVZ3sHp1pDsb5pkwcYtTaZzClp4TPAb1bwGUrTPy27Aia0fnsDdRJA3O2LACVavofhKZ8MSXbJKngorNJH4qRTUz9cvHFETIeUrK-Pc3h23KAWAabE","n":"oRsAhgNZErbwhbPhJ6VzTGWqEH-qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN-c82Kwxtcqxok9nXhWKoJ-SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8_IUmWdtMzo3fAZTMYGbzaq_SiPV-C1j5ONOZid2sG-EAZvMOq1RFXr5UAt6b--QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv-o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P_4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQ","p":"zyDu4zZoPT5iRaDw0oOhRze-sWS9MaE5GGkPeQXk2xwdMn26dSwBWBA2MX2RpfqWiqk_zWu-Pw08OjKmYfzA8xakh8LlUmog520R9zi4oNuEOOmX6sGTf4m4Z9an804IdolV7Titc2SX8FbAOb0-kT5CJv4-BepVZd7se3i-hlE","kty":"RSA","q":"xx4ovqUyOobDYPLtlFve1N_oWnRRm_t992XAMu1_5OcGUT66NOv_mX71SYT9WCDJjJfkfnBrQEpxghT_lc_Mp8gmTjsu_Oc2tXRwHCcfLtmvSDwXjwcXwtPr9CyFZQRI_t__yH7QYcuNy6C6wkBdF_YsS944OPo8cpgVtnJnAfU","qi":"TbrshlUSrRSCqafR3sLHXxBIZxsD8k8o9j_9Km-1Hysr1S9E63W1WNf5tW2K4qirDvuAFfRo4hA5EeJ-_g4t8cAkQtD9WKiDFZ2lZPRJUdx3TIzsGEcaYAL8k3mCfqPmuIBxvZNF5NymGZS9CD6P6wZWoMDarUU6fbRXmJXEjJ8","alg":"PS256"}]}

The PEM-encoded client certificate:

-----BEGIN CERTIFICATE-----
MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8/IUmWdtMzo3fAZTMYGbzaq/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB
-----END CERTIFICATE-----

The PEM-encoded private key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChGwCGA1kStvCFs+EnpXNMZaoQf6pTN7OJf2bjtIkV4iRdqF+/o5PZSAScCo35zzYrDG1yrGiT2deFYqgn5LN8tu+ddeyfh3bB6n3eQQc/NGLmlkZjfk6Wx9kZyZIMpWISCOLA3TVQdvOZTIW/z8hSZZ20zOjd8BlMxgZvNqr9KI9X4LWPk405mJ3awb4QBm8w6rVEVevlQC3pv75B9mCcDZF+MQnPMeddcB8gotgFEaKHzYV0pw7QdDuCgdC8PtfivbWngAZJaa/6jgFbbkgnVB8cBjvaxgoB6hHq8TTWGoAnvk//hZKWNBI4miGG73ZA+Y8vQc45u8lHXLFpc9yFAgMBAAECggEAWf5cZ3/9RM/+QaG+10e7xWRRAJBgE8ZcuyT405/op9nAWLUSb1mv4EMzl/rpXi9a4ec6SEF41YZttuvqZQaDINqLtVjHSkIAm8gicYG/y5W23Xn6bd+DhQS0CIyp0ficdNiT2gp3mrAn2W1+lSw7iZOL6hBA0KErcNB5jaxrDai0oxzHrdQpIPiLmwSpksimKMm8HNoIV5qIv6F1iIAexuyPrLZOfWWTGZsMVmTeaIWt+FXVf5I8D8pKDhX688H9BHSqbdhmx+JI2sfoM47VT2Na+d1y4WwmM2RhfcrSJqeqIb0K2cvBB/5gPlZowHKYazZWJwXg1kDsbWbwKx0UQQKBgQDPIO7jNmg9PmJFoPDSg6FHN76xZL0xoTkYaQ95BeTbHB0yfbp1LAFYEDYxfZGl+paKqT/Na74/DTw6MqZh/MDzFqSHwuVSaiDnbRH3OLig24Q46ZfqwZN/ibhn1qfzTgh2iVXtOK1zZJfwVsA5vT6RPkIm/j4F6lVl3ux7eL6GUQKBgQDHHii+pTI6hsNg8u2UW97U3+hadFGb+333ZcAy7X/k5wZRPro06/+ZfvVJhP1YIMmMl+R+cGtASnGCFP+Vz8ynyCZOOy785za1dHAcJx8u2a9IPBePBxfC0+v0LIVlBEj+3//IftBhy43LoLrCQF0X9ixL3jg4+jxymBW2cmcB9QKBgF1QM+8u8rUspq9Bu1zLqlvgVEus28NBI+zIYA0gx6KivtChbeAdzBk1bITNUlGZXDrp1vGfqZzURJ7fdK/OY8rgF42GEzQW1e4M6DwdVKg7XQ0ax7MeNGoPzIETZqSpMgzdAFYX46SJ3B2Np5oblNVwW/MfNSgLEyAK1zUlB4iRAoGBAKsBP8TbYxPYgRtWBqwPaoQv+AEXPK9VgY1jGXmjdt9Dea10zb59n/pXipklWd7B6daQ7G+aZMHGLU2mcwpaeEzwG9W8BlK0z8tuwImtH57A3USQNztiwAlWr6H4SmfDEl2ySp4KKzSR+KkU1M/XLxxREyHlKyvj3N4dtygFgGmxAoGATbrshlUSrRSCqafR3sLHXxBIZxsD8k8o9j/9Km+1Hysr1S9E63W1WNf5tW2K4qirDvuAFfRo4hA5EeJ+/g4t8cAkQtD9WKiDFZ2lZPRJUdx3TIzsGEcaYAL8k3mCfqPmuIBxvZNF5NymGZS9CD6P6wZWoMDarUU6fbRXmJXEjJ8=
-----END PRIVATE KEY-----

The client scope for the issued tokens can be set to:

openid offline_access

The resource URL can be set to the UserInfo endpoint of the Connect2id server, for example:

https://fapi.c2id.com/c2id/userinfo

4.2 For client authentication type: mtls

Client 1

Sample client metadata to register the first client with the Connect2id server.

Note: The c2id in the redirection URI must be replaced with the test alias from certification panel.

{
   "preferred_client_id"             : "fapi_client_1",
   "grant_types"                     : [ "authorization_code", "refresh_token" ],
   "response_types"                  : [ "code", "code id_token" ],
   "redirect_uris"                   : [ "https://www.certification.openid.net/test/a/c2id/callback" ],
   "request_object_signing_alg"      : "PS256",
   "id_token_signed_response_alg"    : "PS256",
   "token_endpoint_auth_method"      : "self_signed_tls_client_auth",
   "jwks" : {
      "keys" : [ {
         "kty" : "RSA",
         "alg" : "PS256",
         "use" : "sig",
         "kid" : "fapi-4e47bfca-69bc-4010-8726-1a10c199d82b",
         "x5c" : [ "MIICrjCCAZagAwIBAgIIZ2K9yYwq94AwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA5NTM0OFoXDTIyMDUwNTA5NTM0OFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkPWD86AC6tWCgn\/gDcyu6D8V1+0zWt8rHXuCZtr5\/RYywQQBr3WuVG3pUhwEhGZIuoxItcgjnFhg1gdy2z3L5diqsqoE3VDBXvFT145TJpFwGNbjFdvYR0QxOWL1z6l7UtmjA1\/dYO06ZSPC347mVptll\/LV7olOutTBu1JbktadIWk2EMgPvhfenyXKDPi3zRz8OTptBubW4kBQkoV2DHyiKNTZv82\/9cuhoGzpv7uDkGsa75eivvWTV8tMP4G7WLa0\/T5AdxutBgkoqpeyN5hebVnCZFdeak+5i11cbtlyTw39rniRtXzu\/uF8QMBqpawUmxoiE4eCQ1FfiKXGTQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAoTG1xGaqMivCWmO9cG7MJXhCWiQ0YPj2HQ3oCh0IX2xKJ8eL5KH\/S9Ja0ZOYTFs1Sq7NIHRRUzQFK47aLKFMfztUxmWDX6eBXjQ994IbzeAKbNcXOb01XkYfR3atiLSuWRSZ91bNMDHay5zaIL88Yq+Lr\/PirKbSWudMp01fg4s1wU9NFTZugCFGagioiwMlyNUrDiHNSiQAyjyqmYGdy8Tb0JuZ1tvspnNijKAeOg4MnOhZmPp2n9ewSDSYWn6OaF0sIE7Ju74g\/aW0ZMtU5AN6jT9AwBske1LNZtos1fKAyE5RA9AxTuN3GGBXZ9gZD0XGWsFJQM8C+s\/CXH2bm" ],
         "n"   : "kPWD86AC6tWCgn_gDcyu6D8V1-0zWt8rHXuCZtr5_RYywQQBr3WuVG3pUhwEhGZIuoxItcgjnFhg1gdy2z3L5diqsqoE3VDBXvFT145TJpFwGNbjFdvYR0QxOWL1z6l7UtmjA1_dYO06ZSPC347mVptll_LV7olOutTBu1JbktadIWk2EMgPvhfenyXKDPi3zRz8OTptBubW4kBQkoV2DHyiKNTZv82_9cuhoGzpv7uDkGsa75eivvWTV8tMP4G7WLa0_T5AdxutBgkoqpeyN5hebVnCZFdeak-5i11cbtlyTw39rniRtXzu_uF8QMBqpawUmxoiE4eCQ1FfiKXGTQ",
         "e"   : "AQAB"
      } ]
   }
}

The private client JWK set:

{"keys":[{"d":"DkXucS2fO-o8CId400MFMd8MUo-Lj_YLc8K2i1Qia1YlNzYiyFkJCk0sPSZ_F15O6PdpLWUAhKN7HXfsSkQicIZOAHuXMQeDksqmW8Iq09BcPkXiZEOaXyIKysDAvWrNttGxKGLnFGUna9ACnyqd6YcxkK2bfPpOIz1RuhUY6TNMnt2p5JYuFL0OzRWNY0DAkLPzg97PVAyA0QaG4zY0A70UItq5DW35WSIlz4l_w2SCYaQCqlX89QYDL5JCYtWv1HUHdKGgnuzDD-HbVRaNXW0Is0hmJqru8ugjm_70SBRkS_p9G5jvk1HknMfN4MOnXCokF0l4RGkaqhDgbUQ1AQ","e":"AQAB","use":"sig","kid":"fapi-4e47bfca-69bc-4010-8726-1a10c199d82b","x5c":["MIICrjCCAZagAwIBAgIIZ2K9yYwq94AwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA5NTM0OFoXDTIyMDUwNTA5NTM0OFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkPWD86AC6tWCgn\/gDcyu6D8V1+0zWt8rHXuCZtr5\/RYywQQBr3WuVG3pUhwEhGZIuoxItcgjnFhg1gdy2z3L5diqsqoE3VDBXvFT145TJpFwGNbjFdvYR0QxOWL1z6l7UtmjA1\/dYO06ZSPC347mVptll\/LV7olOutTBu1JbktadIWk2EMgPvhfenyXKDPi3zRz8OTptBubW4kBQkoV2DHyiKNTZv82\/9cuhoGzpv7uDkGsa75eivvWTV8tMP4G7WLa0\/T5AdxutBgkoqpeyN5hebVnCZFdeak+5i11cbtlyTw39rniRtXzu\/uF8QMBqpawUmxoiE4eCQ1FfiKXGTQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAoTG1xGaqMivCWmO9cG7MJXhCWiQ0YPj2HQ3oCh0IX2xKJ8eL5KH\/S9Ja0ZOYTFs1Sq7NIHRRUzQFK47aLKFMfztUxmWDX6eBXjQ994IbzeAKbNcXOb01XkYfR3atiLSuWRSZ91bNMDHay5zaIL88Yq+Lr\/PirKbSWudMp01fg4s1wU9NFTZugCFGagioiwMlyNUrDiHNSiQAyjyqmYGdy8Tb0JuZ1tvspnNijKAeOg4MnOhZmPp2n9ewSDSYWn6OaF0sIE7Ju74g\/aW0ZMtU5AN6jT9AwBske1LNZtos1fKAyE5RA9AxTuN3GGBXZ9gZD0XGWsFJQM8C+s\/CXH2bm"],"dp":"b2ev664eVOzcNefzU4FqEfUQ94Jw29e_CqW-ELZYaV2lcYFL6CxJARKiGtd4z1s4JyCUvN9HRbHND5xgeXQnN_9WI1681TMxInVn149oYtcVC0Ie_2D4OV20xhC72o8fyROgdVaIW7igbhb81mAHwnDAlT2_b2f_ybixtkZUN8k","dq":"grim8b9qsrnT5Jno2eaonOtWH-1Ig1Qup87MeV1JumBXZJDP4dvbpKyhfRR7JrsDTRAcVZBsywKKqW8izsrpz1oC8x6Hfc9fYdtjYqVs89mjd-CZXu-eshuo4Kbx087qYN4ogrAMcw0pXKTLgtZkehKE_DYIyM89N5-eib6rekE","n":"kPWD86AC6tWCgn_gDcyu6D8V1-0zWt8rHXuCZtr5_RYywQQBr3WuVG3pUhwEhGZIuoxItcgjnFhg1gdy2z3L5diqsqoE3VDBXvFT145TJpFwGNbjFdvYR0QxOWL1z6l7UtmjA1_dYO06ZSPC347mVptll_LV7olOutTBu1JbktadIWk2EMgPvhfenyXKDPi3zRz8OTptBubW4kBQkoV2DHyiKNTZv82_9cuhoGzpv7uDkGsa75eivvWTV8tMP4G7WLa0_T5AdxutBgkoqpeyN5hebVnCZFdeak-5i11cbtlyTw39rniRtXzu_uF8QMBqpawUmxoiE4eCQ1FfiKXGTQ","p":"xuMjfbhMOn0dJ6cjKC_Zh4S6QRnnBcrTXzHdtQXhLL4s0frEBgbJWb9V074jnORImOv0_ewHV84IWamOXxFz3CxzVXz7WuvyQnZCkANY0TQepO7nDxrDBn-3DgcDzXntrMJg0-8UeeetXjyifmxM8yFeZPAXTL9LJTNOwJxIAo0","kty":"RSA","q":"upXvXWigitVYW49h8bDDebJT4ppBOdECagVjNMVeTAGBDOtsWlJs-2myL7ntm4exDRJBp8-HRpOpBZGeARdb9WIaWzC3eymYLfUt5G2RYK1fYLJVmpvvIIBumQZUtR6Mn-L4aptoQGraAHJpGLRgGi1S336tAH8Q9cBUFiFhwsE","qi":"Q2ng2_AmVOrrHscH-Y5TXuFezL488ZJNk1GJZsJ0kUpDaLSP1sWGlUOt8v5BeyG2_wdrjKqbEROG2_O2vGESsJ4ZLlSFtexNcT7IZmv7X1-Co_TQYlCj9P2qh9X1dRrpzJ4wN5bFbjIPis5StDXRmfmtNcfyMm5aNoWyVXlWn38","alg":"PS256"}]}

The PEM-encoded client certificate:

-----BEGIN CERTIFICATE-----
MIICrjCCAZagAwIBAgIIZ2K9yYwq94AwDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTA5NTM0OFoXDTIyMDUwNTA5NTM0OFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkPWD86AC6tWCgn/gDcyu6D8V1+0zWt8rHXuCZtr5/RYywQQBr3WuVG3pUhwEhGZIuoxItcgjnFhg1gdy2z3L5diqsqoE3VDBXvFT145TJpFwGNbjFdvYR0QxOWL1z6l7UtmjA1/dYO06ZSPC347mVptll/LV7olOutTBu1JbktadIWk2EMgPvhfenyXKDPi3zRz8OTptBubW4kBQkoV2DHyiKNTZv82/9cuhoGzpv7uDkGsa75eivvWTV8tMP4G7WLa0/T5AdxutBgkoqpeyN5hebVnCZFdeak+5i11cbtlyTw39rniRtXzu/uF8QMBqpawUmxoiE4eCQ1FfiKXGTQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAoTG1xGaqMivCWmO9cG7MJXhCWiQ0YPj2HQ3oCh0IX2xKJ8eL5KH/S9Ja0ZOYTFs1Sq7NIHRRUzQFK47aLKFMfztUxmWDX6eBXjQ994IbzeAKbNcXOb01XkYfR3atiLSuWRSZ91bNMDHay5zaIL88Yq+Lr/PirKbSWudMp01fg4s1wU9NFTZugCFGagioiwMlyNUrDiHNSiQAyjyqmYGdy8Tb0JuZ1tvspnNijKAeOg4MnOhZmPp2n9ewSDSYWn6OaF0sIE7Ju74g/aW0ZMtU5AN6jT9AwBske1LNZtos1fKAyE5RA9AxTuN3GGBXZ9gZD0XGWsFJQM8C+s/CXH2bm
-----END CERTIFICATE-----

The PEM-encoded private key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCQ9YPzoALq1YKCf+ANzK7oPxXX7TNa3ysde4Jm2vn9FjLBBAGvda5UbelSHASEZki6jEi1yCOcWGDWB3LbPcvl2KqyqgTdUMFe8VPXjlMmkXAY1uMV29hHRDE5YvXPqXtS2aMDX91g7TplI8LfjuZWm2WX8tXuiU661MG7UluS1p0haTYQyA++F96fJcoM+LfNHPw5Om0G5tbiQFCShXYMfKIo1Nm/zb/1y6GgbOm/u4OQaxrvl6K+9ZNXy0w/gbtYtrT9PkB3G60GCSiql7I3mF5tWcJkV15qT7mLXVxu2XJPDf2ueJG1fO7+4XxAwGqlrBSbGiITh4JDUV+IpcZNAgMBAAECggEADkXucS2fO+o8CId400MFMd8MUo+Lj/YLc8K2i1Qia1YlNzYiyFkJCk0sPSZ/F15O6PdpLWUAhKN7HXfsSkQicIZOAHuXMQeDksqmW8Iq09BcPkXiZEOaXyIKysDAvWrNttGxKGLnFGUna9ACnyqd6YcxkK2bfPpOIz1RuhUY6TNMnt2p5JYuFL0OzRWNY0DAkLPzg97PVAyA0QaG4zY0A70UItq5DW35WSIlz4l/w2SCYaQCqlX89QYDL5JCYtWv1HUHdKGgnuzDD+HbVRaNXW0Is0hmJqru8ugjm/70SBRkS/p9G5jvk1HknMfN4MOnXCokF0l4RGkaqhDgbUQ1AQKBgQDG4yN9uEw6fR0npyMoL9mHhLpBGecFytNfMd21BeEsvizR+sQGBslZv1XTviOc5EiY6/T97AdXzghZqY5fEXPcLHNVfPta6/JCdkKQA1jRNB6k7ucPGsMGf7cOBwPNee2swmDT7xR5561ePKJ+bEzzIV5k8BdMv0slM07AnEgCjQKBgQC6le9daKCK1Vhbj2HxsMN5slPimkE50QJqBWM0xV5MAYEM62xaUmz7abIvue2bh7ENEkGnz4dGk6kFkZ4BF1v1YhpbMLd7KZgt9S3kbZFgrV9gslWam+8ggG6ZBlS1Hoyf4vhqm2hAatoAcmkYtGAaLVLffq0AfxD1wFQWIWHCwQKBgG9nr+uuHlTs3DXn81OBahH1EPeCcNvXvwqlvhC2WGldpXGBS+gsSQESohrXeM9bOCcglLzfR0WxzQ+cYHl0Jzf/ViNevNUzMSJ1Z9ePaGLXFQtCHv9g+DldtMYQu9qPH8kToHVWiFu4oG4W/NZgB8JwwJU9v29n/8m4sbZGVDfJAoGBAIK4pvG/arK50+SZ6NnmqJzrVh/tSINULqfOzHldSbpgV2SQz+Hb26SsoX0Ueya7A00QHFWQbMsCiqlvIs7K6c9aAvMeh33PX2HbY2KlbPPZo3fgmV7vnrIbqOCm8dPO6mDeKIKwDHMNKVyky4LWZHoShPw2CMjPPTefnom+q3pBAoGAQ2ng2/AmVOrrHscH+Y5TXuFezL488ZJNk1GJZsJ0kUpDaLSP1sWGlUOt8v5BeyG2/wdrjKqbEROG2/O2vGESsJ4ZLlSFtexNcT7IZmv7X1+Co/TQYlCj9P2qh9X1dRrpzJ4wN5bFbjIPis5StDXRmfmtNcfyMm5aNoWyVXlWn38=
-----END PRIVATE KEY-----

The client scope for the issued tokens can be set to:

openid offline_access

The resource URL can be set to the UserInfo endpoint of the Connect2id server, for example:

https://fapi.c2id.com/c2id/userinfo

Client 2

Sample client metadata to register the second client with the Connect2id server.

Note: The c2id in the redirection URI must be replaced with the test alias from certification panel.

{
   "preferred_client_id"             : "fapi_client_2",
   "grant_types"                     : [ "authorization_code", "refresh_token" ],
   "response_types"                  : [ "code", "code id_token" ],
   "redirect_uris"                   : [ "https://www.certification.openid.net/test/a/c2id/callback?dummy1=lorem&dummy2=ipsum" ],
   "request_object_signing_alg"      : "PS256",
   "id_token_signed_response_alg"    : "PS256",
   "token_endpoint_auth_method"      : "self_signed_tls_client_auth",
   "jwks" : {
      "keys" : [ {
         "kty" : "RSA",
         "alg" : "PS256",
         "use" : "sig",
         "kid" : "fapi-c43faf75-0fd9-470f-ab68-32d9e0d86b70",
         "x5c" : [ "MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8\/IUmWdtMzo3fAZTMYGbzaq\/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P\/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get\/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR\/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB" ],
         "n"   : "oRsAhgNZErbwhbPhJ6VzTGWqEH-qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN-c82Kwxtcqxok9nXhWKoJ-SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8_IUmWdtMzo3fAZTMYGbzaq_SiPV-C1j5ONOZid2sG-EAZvMOq1RFXr5UAt6b--QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv-o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P_4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQ",
         "e"   : "AQAB"
      } ]
   }
}

The private client JWK set:

{"keys":[{"d":"Wf5cZ3_9RM_-QaG-10e7xWRRAJBgE8ZcuyT405_op9nAWLUSb1mv4EMzl_rpXi9a4ec6SEF41YZttuvqZQaDINqLtVjHSkIAm8gicYG_y5W23Xn6bd-DhQS0CIyp0ficdNiT2gp3mrAn2W1-lSw7iZOL6hBA0KErcNB5jaxrDai0oxzHrdQpIPiLmwSpksimKMm8HNoIV5qIv6F1iIAexuyPrLZOfWWTGZsMVmTeaIWt-FXVf5I8D8pKDhX688H9BHSqbdhmx-JI2sfoM47VT2Na-d1y4WwmM2RhfcrSJqeqIb0K2cvBB_5gPlZowHKYazZWJwXg1kDsbWbwKx0UQQ","e":"AQAB","use":"sig","kid":"fapi-c43faf75-0fd9-470f-ab68-32d9e0d86b70","x5c":["MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8\/IUmWdtMzo3fAZTMYGbzaq\/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P\/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get\/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR\/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB"],"dp":"XVAz7y7ytSymr0G7XMuqW-BUS6zbw0Ej7MhgDSDHoqK-0KFt4B3MGTVshM1SUZlcOunW8Z-pnNREnt90r85jyuAXjYYTNBbV7gzoPB1UqDtdDRrHsx40ag_MgRNmpKkyDN0AVhfjpIncHY2nmhuU1XBb8x81KAsTIArXNSUHiJE","dq":"qwE_xNtjE9iBG1YGrA9qhC_4ARc8r1WBjWMZeaN230N5rXTNvn2f-leKmSVZ3sHp1pDsb5pkwcYtTaZzClp4TPAb1bwGUrTPy27Aia0fnsDdRJA3O2LACVavofhKZ8MSXbJKngorNJH4qRTUz9cvHFETIeUrK-Pc3h23KAWAabE","n":"oRsAhgNZErbwhbPhJ6VzTGWqEH-qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN-c82Kwxtcqxok9nXhWKoJ-SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8_IUmWdtMzo3fAZTMYGbzaq_SiPV-C1j5ONOZid2sG-EAZvMOq1RFXr5UAt6b--QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv-o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P_4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQ","p":"zyDu4zZoPT5iRaDw0oOhRze-sWS9MaE5GGkPeQXk2xwdMn26dSwBWBA2MX2RpfqWiqk_zWu-Pw08OjKmYfzA8xakh8LlUmog520R9zi4oNuEOOmX6sGTf4m4Z9an804IdolV7Titc2SX8FbAOb0-kT5CJv4-BepVZd7se3i-hlE","kty":"RSA","q":"xx4ovqUyOobDYPLtlFve1N_oWnRRm_t992XAMu1_5OcGUT66NOv_mX71SYT9WCDJjJfkfnBrQEpxghT_lc_Mp8gmTjsu_Oc2tXRwHCcfLtmvSDwXjwcXwtPr9CyFZQRI_t__yH7QYcuNy6C6wkBdF_YsS944OPo8cpgVtnJnAfU","qi":"TbrshlUSrRSCqafR3sLHXxBIZxsD8k8o9j_9Km-1Hysr1S9E63W1WNf5tW2K4qirDvuAFfRo4hA5EeJ-_g4t8cAkQtD9WKiDFZ2lZPRJUdx3TIzsGEcaYAL8k3mCfqPmuIBxvZNF5NymGZS9CD6P6wZWoMDarUU6fbRXmJXEjJ8","alg":"PS256"}]}

The PEM-encoded client certificate:

-----BEGIN CERTIFICATE-----
MIICrjCCAZagAwIBAgIIMrt9dj7dh4owDQYJKoZIhvcNAQELBQAwFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MB4XDTIxMDUwNTEwMzgzOFoXDTIyMDUwNTEwMzgzOFowFzEVMBMGA1UEAxMMb2F1dGgtY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoRsAhgNZErbwhbPhJ6VzTGWqEH+qUzeziX9m47SJFeIkXahfv6OT2UgEnAqN+c82Kwxtcqxok9nXhWKoJ+SzfLbvnXXsn4d2wep93kEHPzRi5pZGY35OlsfZGcmSDKViEgjiwN01UHbzmUyFv8/IUmWdtMzo3fAZTMYGbzaq/SiPV+C1j5ONOZid2sG+EAZvMOq1RFXr5UAt6b++QfZgnA2RfjEJzzHnXXAfIKLYBRGih82FdKcO0HQ7goHQvD7X4r21p4AGSWmv+o4BW25IJ1QfHAY72sYKAeoR6vE01hqAJ75P/4WSljQSOJohhu92QPmPL0HOObvJR1yxaXPchQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA1SfsHAKMHPhCM4hqVLBfrfhSfxrKSreplg8KFhtxQsJAkDfbSoZ7MxdXRTWQQmtSpYwSsWSXHO8IS2AwVFarOCA53mZuyh4sAgg928WZ3nTtdUh4+KKxRXQbuoJNelQoeDMudG0OzmsPoHN7mVEyOMNAJGrZopeStanM0YiYEHVdHHSaBe7AUnrzWy2C4wpdomwyR0p5uRR0f6hP5pz81Get/sZr4E9TI2Xu0JMQ4TKoNwRGWau47dwBF6Hp4HTgq7Etl9L9xXzo+T3CzBH8UCAR/Oz8Ro+hjzYUd3EaOIHHTCJoiKPF72dMaKujjTdudRN3h2a3XAp+YCc9dOfWB
-----END CERTIFICATE-----

The PEM-encoded private key:

-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQChGwCGA1kStvCFs+EnpXNMZaoQf6pTN7OJf2bjtIkV4iRdqF+/o5PZSAScCo35zzYrDG1yrGiT2deFYqgn5LN8tu+ddeyfh3bB6n3eQQc/NGLmlkZjfk6Wx9kZyZIMpWISCOLA3TVQdvOZTIW/z8hSZZ20zOjd8BlMxgZvNqr9KI9X4LWPk405mJ3awb4QBm8w6rVEVevlQC3pv75B9mCcDZF+MQnPMeddcB8gotgFEaKHzYV0pw7QdDuCgdC8PtfivbWngAZJaa/6jgFbbkgnVB8cBjvaxgoB6hHq8TTWGoAnvk//hZKWNBI4miGG73ZA+Y8vQc45u8lHXLFpc9yFAgMBAAECggEAWf5cZ3/9RM/+QaG+10e7xWRRAJBgE8ZcuyT405/op9nAWLUSb1mv4EMzl/rpXi9a4ec6SEF41YZttuvqZQaDINqLtVjHSkIAm8gicYG/y5W23Xn6bd+DhQS0CIyp0ficdNiT2gp3mrAn2W1+lSw7iZOL6hBA0KErcNB5jaxrDai0oxzHrdQpIPiLmwSpksimKMm8HNoIV5qIv6F1iIAexuyPrLZOfWWTGZsMVmTeaIWt+FXVf5I8D8pKDhX688H9BHSqbdhmx+JI2sfoM47VT2Na+d1y4WwmM2RhfcrSJqeqIb0K2cvBB/5gPlZowHKYazZWJwXg1kDsbWbwKx0UQQKBgQDPIO7jNmg9PmJFoPDSg6FHN76xZL0xoTkYaQ95BeTbHB0yfbp1LAFYEDYxfZGl+paKqT/Na74/DTw6MqZh/MDzFqSHwuVSaiDnbRH3OLig24Q46ZfqwZN/ibhn1qfzTgh2iVXtOK1zZJfwVsA5vT6RPkIm/j4F6lVl3ux7eL6GUQKBgQDHHii+pTI6hsNg8u2UW97U3+hadFGb+333ZcAy7X/k5wZRPro06/+ZfvVJhP1YIMmMl+R+cGtASnGCFP+Vz8ynyCZOOy785za1dHAcJx8u2a9IPBePBxfC0+v0LIVlBEj+3//IftBhy43LoLrCQF0X9ixL3jg4+jxymBW2cmcB9QKBgF1QM+8u8rUspq9Bu1zLqlvgVEus28NBI+zIYA0gx6KivtChbeAdzBk1bITNUlGZXDrp1vGfqZzURJ7fdK/OY8rgF42GEzQW1e4M6DwdVKg7XQ0ax7MeNGoPzIETZqSpMgzdAFYX46SJ3B2Np5oblNVwW/MfNSgLEyAK1zUlB4iRAoGBAKsBP8TbYxPYgRtWBqwPaoQv+AEXPK9VgY1jGXmjdt9Dea10zb59n/pXipklWd7B6daQ7G+aZMHGLU2mcwpaeEzwG9W8BlK0z8tuwImtH57A3USQNztiwAlWr6H4SmfDEl2ySp4KKzSR+KkU1M/XLxxREyHlKyvj3N4dtygFgGmxAoGATbrshlUSrRSCqafR3sLHXxBIZxsD8k8o9j/9Km+1Hysr1S9E63W1WNf5tW2K4qirDvuAFfRo4hA5EeJ+/g4t8cAkQtD9WKiDFZ2lZPRJUdx3TIzsGEcaYAL8k3mCfqPmuIBxvZNF5NymGZS9CD6P6wZWoMDarUU6fbRXmJXEjJ8=
-----END PRIVATE KEY-----

The client scope for the issued tokens can be set to:

openid offline_access

The resource URL can be set to the UserInfo endpoint of the Connect2id server, for example:

https://fapi.c2id.com/c2id/userinfo

4.3 Sample JWK set code

Sample Java code to generate a FAPI client RSA JWK (alg=PS256) with a self-signed certificate. Requires a recent version of the OAuth 2.0 / OpenID Connect SDK:

import java.security.cert.X509Certificate;
import java.util.*;
import com.nimbusds.jose.*;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.jwk.gen.*;
import com.nimbusds.jose.util.*;
import com.nimbusds.jwt.util.*;
import com.nimbusds.oauth2.sdk.id.*;
import com.nimbusds.oauth2.sdk.util.*;

// Generate an RSA JWK
RSAKey rsaJWK = new RSAKeyGenerator(2048)
    .keyID("fapi-" + UUID.randomUUID())
    .keyUse(KeyUse.SIGNATURE)
    .algorithm(JWSAlgorithm.PS256)
    .generate();

// Use RSA JWK to sign self-issued client certificate
Date now = new Date();
Date nbf = now;
long oneYearInSeconds = 3600 * 24 * 365;
Date exp = DateUtils.fromSecondsSinceEpoch(DateUtils.toSecondsSinceEpoch(now) + oneYearInSeconds);

X509Certificate clientCert = X509CertificateUtils.generateSelfSigned(
    new Issuer("oauth-client"),
    nbf,
    exp,
    rsaJWK.toRSAPublicKey(),
    rsaJWK.toPrivateKey());

// Append client certificate to RSA JWK
rsaJWK = new RSAKey.Builder(rsaJWK)
    .x509CertChain(Collections.singletonList(Base64.encode(clientCert.getEncoded())))
    .build();

// Print the public JWK set, required for the client metadata
System.out.println(new JWKSet(rsaJWK.toPublicJWK()));

// Print the PEM-encoded client certificate
System.out.println(X509CertUtils.toPEMString(clientCert));

// Print the private JWK set
System.out.println(new JWKSet(rsaJWK).toString(false));

// Print the PEM-encoded private key
System.out.println(
    "-----BEGIN PRIVATE KEY-----\n" +
    Base64.encode(rsaJWK.toPrivateKey().getEncoded()) + "\n" +
    "-----END PRIVATE KEY-----\n");