title: Is it possible to create a JSON Web Token using Azure Key Vault's Keys API?
body: <p>I am currently using the <code>jsonwebtokens</code> package for generating signed JWTs with a RSA signing key. I was experimenting to see how I can move to <strong>Azure Key Vault</strong>. One way I can do is to store the private and public keys as Vault Secrets. But I noticed that there's also a Vault Keys API which generates a key in Vault and signs data which I provide it.</p>
  <p>I've been trying with the <a href="https://www.npmjs.com/package/@azure/keyvault-keys" rel="nofollow noreferrer"><code>@azure/keyvault-keys</code></a> package and this is where I've got:</p>
  <pre class="lang-js prettyprint-override"><code>async signJsonWebToken(data: object, expiry: string): Promise&lt;string&gt; {
    const headerB64 = this.base64url(JSON.stringify(this.keyHeader), 'binary');
    const payloadB64 = this.base64url(this.getTokenData(data, expiry), 'utf8');
    const payload = `${headerB64}.${payloadB64}`;
  
    const key = await this.keyClient.getKey(this.KEY_NAME);
    const cryptClient = new CryptographyClient(key, new DefaultAzureCredential());
  
    const hash = crypto.createHash('sha256');
    const digest = hash.update(payload).digest();
  
    const signResult = await cryptClient.sign('RS256', digest);
    const signResultB64 = this.base64url(signResult.result.toString(), 'utf8');
    const result = `${payload}.${signResultB64}`;
    this.logger.log('Key: ' + key.key);
    this.logger.log('Sign result: ' + result);
    return result;
  }
  
  private base64url(data: string, encoding: string) {
    return SBuffer
      .from(data, encoding)
      .toString('base64')
      .replace(/=/g, '')
      .replace(/\+/g, '-')
      .replace(/\//g, '_');
  }
  
  private getTokenData(data: object, expiry: string): string {
    const now = Date.now();
    const expiresIn = new Date();
    if (expiry.endsWith('d')) {
      expiresIn.setDate(expiresIn.getDate() + parseInt(expiry));
    } else if (expiry.endsWith('h')) {
      expiresIn.setHours(expiresIn.getHours() + parseInt(expiry));
    } else if (expiry.endsWith('m')) {
      expiresIn.setMinutes(expiresIn.getMinutes() + parseInt(expiry));
    }
    const tokenData = Object.assign({
      iat: now,
      exp: expiresIn.getTime()
    }, data);
    return JSON.stringify(tokenData);
  }
  </code></pre>
  <p>The generated signed signature do not look anywhere close to what I'd usually be getting with the <code>jsonwebtoken</code> package. My intention is that I'd like to sign my tokens with Vault but would like to verify with <code>jsonwebtoken.verify()</code>. Is this even possible? What am I doing wrong in my code?</p>