Skip to content

JWKS endpoint

How to expose a JWKS endpoint (JSON Web Key Set) with this library.

Note: The algorithm RS256 is used by default.

Export a JWK from a key chain

Considering you have for example on your side this key chain:

  • public key path: /home/user/.ssh/id_rsa.pub
  • private key path: /home/user/.ssh/id_rsa
  • private key passphrase: test

To extract the JWK (JSON Web Key) properties, you can use the JwkRS256Exporter as following:

<?php

use OAT\Library\Lti1p3Core\Security\Jwks\Exporter\Jwk\JwkRS256Exporter;
use OAT\Library\Lti1p3Core\Security\Key\KeyChainFactory;
use OAT\Library\Lti1p3Core\Security\Key\KeyInterface;

$keyChain = (new KeyChainFactory)->create(
    '1',
    'mySetName',
    'file://home/user/.ssh/id_rsa.pub',
    'file://home/user/.ssh/id_rsa',
    'test',
     KeyInterface::ALG_RS256
);

$jwkExport = (new JwkRS256Exporter())->export($keyChain);

Notes: - the $jwkExport variable now contain the needed JWK properties:

{
    "alg": "RS256",
    "kty": "RSA",
    "use": "sig",
    "n": "...",
    "e": "...",
    "kid": "1"
}
- If you want to support other algorithms than RS256, you can implement the JwkExporterInterface.

Export a JWKS from multiple key chains

Considering you have for example on your side those key chains:

Chain 1: - public key path: /home/user/.ssh/chain1/id_rsa.pub - private key path: /home/user/.ssh/chain1/id_rsa - private key passphrase: test1

Chain 2: - public key path: /home/user/.ssh/chain2/id_rsa.pub - private key path: /home/user/.ssh/chain2/id_rsa - private key passphrase: test2

You can then use the KeyChainRepository:

<?php

use OAT\Library\Lti1p3Core\Security\Key\KeyChainFactory;
use OAT\Library\Lti1p3Core\Security\Key\KeyChainRepository;
use OAT\Library\Lti1p3Core\Security\Key\KeyInterface;

$keyChain1 = (new KeyChainFactory)->create(
    'kid1',
    'myKeySetName',
    'file://home/user/.ssh/chain1/id_rsa.pub',
    'file://home/user/.ssh/chain1/id_rsa',
    'test1',
     KeyInterface::ALG_RS256
);

$keyChain2 = (new KeyChainFactory)->create(
    'kid2',
    'myKeySetName',
    'file://home/user/.ssh/chain2/id_rsa.pub',
    'file://home/user/.ssh/chain2/id_rsa',
    'test2',
     KeyInterface::ALG_RS256
);

$keyChainRepository = new KeyChainRepository();
$keyChainRepository
    ->addKeyChain($keyChain1)
    ->addKeyChain($keyChain2);

$keySet = $keyChainRepository->findByKeySetName('myKeySetName'); //  = [$keyChain1, $keyChain2]

Note: you can also provide your own KeyChainRepositoryInterface implementation, to store keys in database by example.

To extract the JWKS (JSON Web Key Set) properties for you key set name myKeySetName, you can use the JwksExporter as following:

<?php

use OAT\Library\Lti1p3Core\Security\Jwks\Exporter\JwksExporter;

$jwksExport = (new JwksExporter($keyChainRepository))->export('myKeySetName');

Now the $jwksExport array contains the needed JWKS properties ready to be exposed to provide a JWKS endpoint from your application:

{
    "keys": [
        {
            "alg": "RS256",
            "kty": "RSA",
            "use": "sig",
            "n": "...",
            "e": "...",
            "kid": "kid1"
        },
        {
            "alg": "RS256",
            "kty": "RSA",
            "use": "sig",
            "n": "...",
            "e": "...",
            "kid": "kid2"
        }
    ]
}

Provide a JWKS response

You can expose the JwksRequestHandler in an application controller to provide a ready to use JWKS PSR7 response for a given key set name:

<?php

use OAT\Library\Lti1p3Core\Security\Jwks\Exporter\JwksExporter;
use OAT\Library\Lti1p3Core\Security\Jwks\Server\JwksRequestHandler;

$handler = new JwksRequestHandler(new JwksExporter($keyChainRepository));

$response = $handler->handle('myKeySetName');

Note: Up to you to provide the logic to retrieve the key set name to expose.