Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async / custom signers and verifiers #103

Open
dhensby opened this issue Oct 24, 2022 · 0 comments
Open

Async / custom signers and verifiers #103

dhensby opened this issue Oct 24, 2022 · 0 comments

Comments

@dhensby
Copy link

dhensby commented Oct 24, 2022

Custom (asynchronous) signer/verifier support

When using an external secret store / key management service such as AWS KMS or Azure Key Vault, it is not always possible to have the private key or secret in application memory. Instead, the KMS is used to perform the signing and responds with the signature. As this is an external service it happens asynchronously.

Currently, it is not possible to use these types of asynchronous signing services with the JWS library (at least, not without some circumvention).

Describe the ideal solution

I would like to be able to provide a custom algorithm resolver and to support an asynchronous signer.

The jwsSign opts could take an option that replaces the jwa library for returning a signer/verifier pair. The signer/verifier could then return a Promise that resolves with the signature.

Alternatives and current workarounds

At the moment, the best workaround I can find is to effectively sign the token twice. Once with a random private key that is available in memory and then again using the KMS. The signature from the KMS is then used in place of the one generated in memory.

const { generateKeyPairSync } = require('crypto');
const jws = require('jws');
const keyPair = generateKeyPairSync('rsa', { ... });

async function sign(alg, payload) {
  const signature = jws.sign({
    header: { alg },
    payload,
    secret: keyPair.privateKey,
  });
  const jwsWithoutSig = signature.split('.', 2).join('.');
  const sig = await someAsyncSigner(alg, jwsWithoutSig);
  return `${jwsWithoutSig}.${sig}`;
}

Additional context

There have been other requests around this type of feature and I think the above proposal is the most generic way to achieve the ability to support async signing.

This should address these related issues: #34, #93

I am happy to work on this solution, but it will involve breaking changes as the sign/verify functions will become async instead of sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant