PingOne Platform APIs

Create a private_key_jwt JWKS string

In the PingOne application configuration, when the tokenEndpointAuthMethod property is set to PRIVATE_KEY_JWT, the configuration requires either the jwks property (specifying a JWKS string) or the jwksUrlproperty (specifying the location on a web server that hosts the JWKS string).

When using the jwksUrl property, the application configuration JSON looks like this. Note that the jwksUrl must be https://:

{
  ...
  "tokenEndpointAuthMethod": "PRIVATE_KEY_JWT",
  "jwksUrl": "https://{{pathToJwksString}}",
  ...
}

The application configuration JSON for the JWKS string in the jwks property must be formatted as one line with double quotes escaped:

{
  ...
  "tokenEndpointAuthMethod": "PRIVATE_KEY_JWT",
  "jwks": "{ \"keys\": [ { \"kty\": \"RSA\", \"e\": \"AQAB\", \"use\": \"sig\", \"kid\": \"q3sWApYjHZQLmWMUdAIqZiVWSshDdau5eI4K_Bm65Us\", \"alg\": \"RS256\", \"n\": \"jWA_vDxg41NrYJdIiv3BcljMy7V15bMyOyK5aJov6FgUTE2Xm_B9SqJu55qmS3CxVhvYWSpRIZvhrgap19CE_VnrAc5pzwj2oSEmDRXXFSGmMjHAmfTXU66nDZVmhbtDIBkPU-h55RDZf6zIn3SPOrmWJYj0G5X2fMJfbUOpuROjH1aMqqGOxcT-dX-LA0dd94LrH4J-g1HFeGZqw-uyQO8l1g6fbQYVaNvnHtw9V7U7I684Ks-3sZcU-YhexNhiN53izIglhdVva9pjSTUk4BnmYtSlfyF6HzUYkvg3H1S0Y6LqzW8lOIw8SF-L6jQqkT2DPDwDbxzNoaNx8lIE0Q\" } ]}",
  ...
}

The following information describes the steps for generating the JWKS for use with "tokenEndpointAuthMethod": "PRIVATE_KEY_JWT".

Create the JWKS string

You will use the generated keys you created for your private key JWT (refer to Create a private key JWT) to generate a JWKS string object that can be used as the value in your PingOne application’s jwks property.

  1. Copy the Public Key and wrap it like this:

    {
    "keys": [
      <Your public key>
     ]
    }

    Which looks like this:

    {
    "keys": [
       {
         "kty": "RSA",
         "e": "AQAB",
         "use": "sig",
         "kid": "q3sWApYjHZQLmWMUdAIqZiVWSshDdau5eI4K_Bm65Us",
         "alg": "RS256",
         "n": "jWA_vDxg41NrYJdIiv3BcljMy7V15bMyOyK5aJov6FgUTE2Xm_B9SqJu55qmS3CxVhvYWSpRIZvhrgap19CE_VnrAc5pzwj2oSEmDRXXFSGmMjHAmfTXU66nDZVmhbtDIBkPU-h55RDZf6zIn3SPOrmWJYj0G5X2fMJfbUOpuROjH1aMqqGOxcT-dX-LA0dd94LrH4J-g1HFeGZqw-uyQO8l1g6fbQYVaNvnHtw9V7U7I684Ks-3sZcU-YhexNhiN53izIglhdVva9pjSTUk4BnmYtSlfyF6HzUYkvg3H1S0Y6LqzW8lOIw8SF-L6jQqkT2DPDwDbxzNoaNx8lIE0Q"
       }
     ]
    }
  2. The string needs to be reduced to one line and the double quotes escaped.

    The JSON for the PingOne application POST (or PUT) to create the application looks like:

    {
      ...
      "tokenEndpointAuthMethod": "PRIVATE_KEY_JWT",
      "jwks": "{\r\n  \"keys\": [\r\n    {\r\n        \"kty\": \"RSA\",\r\n        \"e\": \"AQAB\",\r\n        \"use\": \"sig\",\r\n        \"kid\": \"q3sWApYjHZQLmWMUdAIqZiVWSshDdau5eI4K_Bm65Us\",\r\n        \"alg\": \"RS256\",\r\n        \"n\": \"jWA_vDxg41NrYJdIiv3BcljMy7V15bMyOyK5aJov6FgUTE2Xm_B9SqJu55qmS3CxVhvYWSpRIZvhrgap19CE_VnrAc5pzwj2oSEmDRXXFSGmMjHAmfTXU66nDZVmhbtDIBkPU-h55RDZf6zIn3SPOrmWJYj0G5X2fMJfbUOpuROjH1aMqqGOxcT-dX-LA0dd94LrH4J-g1HFeGZqw-uyQO8l1g6fbQYVaNvnHtw9V7U7I684Ks-3sZcU-YhexNhiN53izIglhdVva9pjSTUk4BnmYtSlfyF6HzUYkvg3H1S0Y6LqzW8lOIw8SF-L6jQqkT2DPDwDbxzNoaNx8lIE0Q\"\r\n    }\r\n  ]\r\n}",
      ...
    }

When you set PRIVATE_KEY_JWT as your application’s tokenEndpointAuthMethod, the following endpoints support the client_assertion and client_assertion_type properties.

  • {{authPath}}/{{envID}}/as/token

  • {{authPath}}/{{envID}}/as/introspect

  • {{authPath}}/{{envID}}/as/par

  • /as/revoke

  • /as/device_authorization

For more information about using the client_assertion and client_assertion_type properties with the token request, refer to Token (authorization_code) (PRIVATE_KEY_JWT).

Configure the JWKS URL

To use the jwksUrl property in the PingOne application’s configuration, the JWKS string must be hosted on a web server, accessible to the internet (using https://). For testing purposes, the following code sample shows a simple node server file (running on a local web server) that hosts the JWKS string.

const https = require("https");
const host = 'localhost';
const port = 3000;

const requestListener = function (req, res) {
    res.setHeader("Content-Type", "application/json");
    res.writeHead(200);

    const jwksString = "{\r\n  \"keys\": [\r\n    {\r\n        \"kty\": \"RSA\",\r\n        \"e\": \"AQAB\",\r\n        \"use\": \"sig\",\r\n        \"kid\": \"q3sWApYjHZQLmWMUdAIqZiVWSshDdau5eI4K_Bm65Us\",\r\n        \"alg\": \"RS256\",\r\n        \"n\": \"jWA_vDxg41NrYJdIiv3BcljMy7V15bMyOyK5aJov6FgUTE2Xm_B9SqJu55qmS3CxVhvYWSpRIZvhrgap19CE_VnrAc5pzwj2oSEmDRXXFSGmMjHAmfTXU66nDZVmhbtDIBkPU-h55RDZf6zIn3SPOrmWJYj0G5X2fMJfbUOpuROjH1aMqqGOxcT-dX-LA0dd94LrH4J-g1HFeGZqw-uyQO8l1g6fbQYVaNvnHtw9V7U7I684Ks-3sZcU-YhexNhiN53izIglhdVva9pjSTUk4BnmYtSlfyF6HzUYkvg3H1S0Y6LqzW8lOIw8SF-L6jQqkT2DPDwDbxzNoaNx8lIE0Q\"\r\n    }\r\n  ]\r\n}";

    res.end(jwksString);
};

const server = https.createServer(requestListener);
server.listen(port, host, () => {
    console.log(`Server is running on https://${host}:${port}`);
});

With the JWKS string in a known location, the application configuration JSON looks like this:

{
  ...
  "tokenEndpointAuthMethod": "PRIVATE_KEY_JWT",
  "jwksUrl": "jwksUrl": "{{pathToJwksString}}",
  ...
}