@auth - JWT in JWE format - can dgraph handle it?

So I am exploring the so called “poor man’s auth” options with JWTs, and I realized that JWTs (in the JWS format) are decodable without any secret.

So my question is:
If I want to encrypt the “claims” of my auth tokens, can Dgraph handle that?

If not, can we refine this issue into a feature request?

If so, how?

  • How does one setup the keys?
    • which keys need to be used for encrypting/decrypting signing/verifying ?

@pawan any ideas? Specifically on encrypting claims

@gotjoshua if you want, I suspect Sam Julien will have something on that in his talk for the GraphQL in Space conference tomorrow. Check it out: https://www.graphqlcon.space/

I always look at JWT as being an identity token that can only be used if it is verified. I don’t keep any kind of password or even email address in the any client side JWT just only as much as I need to link to which identity has been authenticated so I can use it to authorize the correct information. So what if someone gets a JWT and decodes it, they can not modify it and send it back because then it will not be verified. The secret is the private key. Keep that more secure than Ft. Knox

Hey @amaster507, well… yeah, i’d say should only be used if its verified, but unfortunately it can be decoded and used without being altered by pretty much any code that gets its paws on it.

As I understand there is no way to really tie a User session to an IP address and have a JWT that is only verified for that user from that IP for the duration of that session.

Maybe I am over thinking this… (or being a bit over-cautious)
… but as I understand it:
If my server (or auth0 as Dgraph uses in the examples) sends a JWT to the client, and then the client uses that JWT to gain access to Dgraph, any other client from any other IP would be able to use that same JWT to access everything that the original client has access to.
Is that true?

The JWT is still signed by the same private key, and still “valid” no matter where it is reused from.
Therefore we are depending only on https security to guard the JWT in transit and depending on browser javascript security as long as the JWT is in memory.

@pawan and @chewxy … looking forward to your replies

I signed up for the conf and i see the talk that you refer to… hopefully I’ll have time to join.

After more thinking, I am considering a strategy like this:

My backed component:

  1. gets a valid Oauth token for a user
  2. creates a JWE that includes claims:
ip: x.x.x.x,
userID: ###,
sessionID: ###
}  // this payload would be signed and encrypted with a key 
// that only dgraph and the backend know
  1. the backend needs to update the user->sessionID edge with a facet for the (ip=x.x.x.x)

  2. this JWE can be stored by the client and used to authenticate queries and mutations
    via dgraph-js-http and the @auth rules need to do the sessionID and ip matching

In order for all this to work, Dgraph @auth would need to be able to handle decrypting the JWE payload

Things to consider…

  • Users behind load balancers that switch IPs between requests.
  • Mobile users as they travel and use different WANs and networks.
  • A user being signed in from multiple devices.
1 Like

ooo, good call. maybe IP isn’t a good idea at all.

Perhaps a session array would be better:

userUID <Sessions> _:session1UID  
_:session1UID <SessionSecret>  string
_:session1UID <Expires>  date

userUID <Sessions> _:session2UID
_:session2UID <SessionSecret> ...

Definitely adding support for JWE will be beneficial as we won’t be able to decrypt the payload without the key. Using JWT variables and @auth rules you will be able to achieve some form of authorization based on IP/Session ID.
I explored our current code and it seems that the library we use for JWT doesn’t support JWE.

But there is another library that supports JWE. Probably we can explore it and use the same. Accepting this issue and we will update you once we start working on it.

1 Like

Hi @gotjoshua, One of the best practices for using the JWT token is to have a very short expiration time for the JWT.
Currently, JWE’s are not very widely used in authentication and are not provided by any major authentication providers.
One possible solution is similar to what you mentioned that getting a JWT token from the authentication provider and then encrypting in the backend taken care of by you. GraphQL server decrypts the JWE and extract the decrypted JWT token from it and use it in authentication.
Since this is not a heavily requested feature so we are not planning to add support for it soon.
Apart from this, can you elaborate more about your use case so that we can understand your situation better?

First of all, thanks for the reply! And for the amazing product!

Well I must say that I don’t need to have any data in the jwt that is mega sensitive… But I like to learn about the options in enough depth to be able to “do right things, right”

So in my investigation I came across jwe,
And thought that an additional layer of security could be obtained using a jwe with more specific info that could be validated on the server side

I find it rather disconcerting that any bloke who gets their paws on my jwt can drop it in jwt.io
And read the contents…

But I get it, jwe’s are overkill… And if the Auth server says the user is who they say they are and the jwt signature is kosher, then it doesn’t matter who can read it as long as they can’t spoof it , alter it, or use it to impersonate someone

That said I still think it’s a cool thought experiment to imagine the most secure Auth and data flow scenario possible with dgraph, and maybe jwe could play a role in that…

Let’s say the white House wanted to use d graph for a top-security app that their employees needed to use in the wild… Other than short term
Jwt expiration, what strategies could work for user session authentication that was solid against all realistic data breaches?

You are welcome! Keep the suggestions for improvements coming in. :slight_smile:

As you pointed out JWE would be an option. We are not planning to add it right now because most users would consume the GraphQL API directly from a browser rather a backend server. Its not common for users to use encryption in the browser to encrypt their JWT’s. So we’ll keep a lookout on this and if more users want this, then we can consider building this.

In the meantime, short TTLs for the access tokens and the ability to revoke them in the case of a breach are the ways to protect against stolen tokens.

1 Like