JWT token security

Both the front end communication and the lifecycle events use JWT tokens for data exchange. To ensure data integrity, we sign the payload according to RFC 7519. The signature can be verified using public certificates.

JOSE compliant header

The token header contains the 'jku' claim, which holds a URL linking to the public key that should be used to verify the signature.
For front end communication the Plug-In Adapter library has a few built-in certificates for fast evaluation of the most used public keys (coyocloud and coyostaging), but can download missing public keys on demand from this URL. If a plug-in has a back end, it can use the same mechanism to download missing / unknown keys when verifying passed front end communication tokens or lifecycle events.

jku URL whitelist

To prevent malicious attacks a plug-in MUST check the public key download URL ('jku' header claim) against a whitelist of known sites:

Adding key download URLs and keys to the Plug-In Adapter library manually

The Plug-In Adapter library allows to add custom download URLs and / or public keys for signature validation.
Please note that the protocol MUST be secured by TLS using HTTPS.
You can add multiple keys for the same issuer regex, which can be useful when there is a transition to a new public key and you want to cover both.

import {JwkStore} from '@coyoapp/plugin-adapter';

const JWK_REGEX = /^https:\/\/some.site$/i; // match 'iss' issuer claim
const JWK = {
  alg: {
    name: 'RSASSA-PKCS1-v1_5',
    hash: { name: 'SHA-256' }
  },
  key: {
    kty: 'RSA',
    n:
      '6pEgjiM-gu6T7HFeI_OWxr7YftcYqFVHnpMcAsW510Nqn4citmM6XvOMlagovI5c3MoSHvfpRPuHqNpR' +
      'HX_ZpOlbn0NDCJFsOaKQPmffaQSaeRdHsVmXgFAJ3Y7cUSW4NqJAZV71GwMzOu7B7db1htF-kPvb0lN0' +
      '18EXrWBFO0nkHYGi_7vUedwbAu-hOaMh1028Yiwl2dcZW3X9htE6RhXY_B4PofiipOGtklotm424b0Gh' +
      'ccGdIz7cBapxNX1_QLc3C4QatpWt8Hs4QWH0iJMRpdFpuOxkZ8d6c6aqbUglgXLrEICT3ZWrBOFZCVom' +
      'NYyYv321BdfLfnSIT4bIQQ',
    e: 'AQAB',
    alg: 'RS256',
    use: 'sig'
  }
};

// call the next statement from within some initialisation function after you instantiated
// the PluginAdapter
const jwkStore = JwkStore.getInstance();
// add jku download URL
jwkStore.addHost('https://pubkeys.some.site');
// or add a key directly, the regex must match the issuer
jwkStore.addJwk(JWK_REGEX, JWK);
// or add multiple keys for one environment
jwkStore.addJwk(JWK_REGEX, JWK1, JWK2, JWK3);