Kong / kong

🦍 The Cloud-Native API Gateway and AI Gateway.
https://konghq.com/install/#kong-community
Apache License 2.0
38.78k stars 4.77k forks source link

API tokens using JWT #1772

Closed endeepak closed 3 years ago

endeepak commented 7 years ago

Context: We are planning to expose our APIs to our application users similar to Github api keys. We need rate limiting etc which are implemented beautifully in kong. Our use case can be achieved easily with key auth plugin, but couple of concerns there

The JWT spec seems to solve both of these problems (assuming secret used for signing token is safe)

Problem: The current JWT plugin seems to generate new pair of issuer field (iss / called as key there) and secret per consumer for signing. These values are stored in DB

Question: What is the recommended way achieve use case like Github api keys with JWT in kong?

saamalik commented 7 years ago

+1

thibaultcha commented 7 years ago

Authentication of proxied APIs need to talk to DB to get secret and iss

What other solutions are you envisioning that would allow Kong nodes to be aware of your consumer's credentials (signing the tokens) all the while not storing them in the database at the same time?

Tokens are stored as free text

We would welcome contributions for this, but at the same time, such a contribution would need to find an elegant way of dealing with this issue across the entire code base, providing a proper DB encryption for all secrets stored in both Cassandra and Postgres. This is on our TODO list.

The JWT token generation logic has to be implemented outside kong

That is correct. Contributions welcomed :)

thibaultcha commented 7 years ago

PS: at the same time, you can use RS256 to sign your tokens, for which Kong will only require you to store the public key in the DB.

endeepak commented 7 years ago

Authentication of proxied APIs need to talk to DB to get secret and iss

What other solutions are you envisioning that would allow Kong nodes to be aware of your consumer's credentials (signing the tokens) all the while not storing them in the database at the same time?

Avoiding DB access for fetching secret : I was hoping it would be more like nginx plus jwt token support. In this case, a single secret is needed on server side as configuration. The configuration is loaded on server startup and no db access for fetching secret. The jwt plugin for caddy also has similar implementation where secret is configured using a environment variable JWT_SECRET

Avoiding DB access for fetching consumer details : The sub field in jwt claim can have consumer id and other public claim fields can be used for consumer username and customid (explained below). An example for this can be found in auth0 jwt docs

To draw parallels in kong, the flow in kong could be as follows

Security aspect

None of the consumer tokens are stored in DB, hence no need for encryption / hashing. This assumes the secret for creating token is safe guarded on server side, which would be a minimum requirement even when encryption / hashing mechanism is used for storing sensitive data in DB.

So no DB access at all?

Yes*, only If blacklisting tokens is not needed. No*, If blacklisting is needed. You'll have to store the black listed tokens in DB as explained here. Even with this, it would be just one DB call vs 2 DB calls needed now (1 for retrieving secret + 1 for retrieving consumer details)

@thibaultcha Thanks for suggesting RS256

ksachdev1 commented 7 years ago

Reading this post, should I assume that there is no blacklisting of JWT supported by Kong?

gottfrois commented 7 years ago

@endeepak exposing consumer metadata as http headers (one http header for one consumer attribute) might be problematic if you start having a big enough claim payload. Would be nice if kong expose the base64 encoded string that we just need to decode and deal with it.

What do you think?

mvanholsteijn commented 5 years ago

@endeepak, I would suggest using RS256 encryption, requiring you only to store only the public key of your users for validation. Very safe, as you do not have knowledge of the private key of your caller and you do not have to communicate any secrets to the users.

bungle commented 3 years ago

I am closing this as using an asymmetric signature algorithm should be the preferred way to go.