I'm working with a client that, in order to use their OAuth 2.0 web API, requires me to provide them with a JSON Web Key (JWK) that contains an embedded X.509 certificate. Then, when I'm requesting information from the API, they say I need to pass a "signed (with private keys) JWT Bearer token" on each request.

I've never worked with JWK's before so I was looking over the official JWK documentation, but it's very dense and doesn't really talk about how these are used in real life applications.

I found this site / command line tool that can generate JWK's in different formats, and it generates the JWK with an X.509 certificate that is self-signed. I'm wondering, in this case, is it okay to use a self-signed cert to talk to this API? I understand that with web browsers, you absolutely need a cert that is from a trusted CA because the client and web server are essentially strangers, but this cert isn't being used publicly for a website; it's just being used between my application and this OAuth API, and both parties already trust each other.

So really my question is, would generating a JWK with a self-signed X.509 certificate be sufficient, and then use the private key of the certificate to sign JWT Bearer tokens when actually using the API?

3 Answers 3


The possible use of a self-signed certificate should be part of your customer's security policy and/or security guidelines. I would strongly advise against the use of self-signed certificates in any type of production network for any purpose as it provides less security than a certificate signed by a trusted CA.

To answer your question, the certificate will provide the needed functionality, but I doubt it is your decision to make if it can be used. You should consult that with your customer.


It sounds like they use OAuth mTLS. There are two different things you can archive with OAuth mTLS:

  • Client Authentication
  • Client Certificate-Bound Access Tokens

Both goals can be archieved with self-signed certificates, c.f. Section 2.2. of the OAuth mTLS RFC.


Distilling out the use-case you are describing:

  • You need to pass a "signed (with private keys) JWT Bearer token" on each request.
  • The (I assume) RSA public key that signs that JWT needs to be in an X.509 certificate. So your datastructure is something like:
JWK{ X.509Cert{ RSAPubKey } }  --signs--> JWT

Obviously the server does not want to accept JWTs signed by anybody's key, so it needs some way to establish trust in the RSAPubKey.

There are two fundamental approaches:

  1. PKI: the X.509Cert is issued by a CA that the server trusts.
  2. Self-signed and registered: Here there will be some sort of explicit registration step where the client says "Here's the RSA key that I will use to sign my future requests", and the server maintains a list of such client keys.

Either approach is fine. In the PKI case the CA does all the heavy lifting of ensuring that the name information in the cert matches the user's account info. In the self-signed case the user gets to choose the cert metadata themselves, so your server needs to do more vetting during the registration process, and needs to be careful about mapping certs / pub keys to accounts, but there's nothing fundamentally wrong with the approach.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .