User authentication

Hello good day,

I am exploring dgraph, but after browsing the docs, I cant find how to manage users for the database.

I tried to install it, and I can access the database without a user/password.

I felt dumb, I want to ask, where I can find the docs about managing users for the database?

Thanks.

1 Like

There’s currently no mechanism for user/password based authentication. You could set up TLS for now (which doesn’t totally give you what you want). We do have plans to add TLS support this year.

You mean user/password based authentication?

Right. Sorry for the typo. We have plans to add user/pwd based auth.

3 Likes

Hi, can ask you some questions?

Do you intend to use this feature to manage user control of the database or your client (application/auth) users?

For the second option generally we create an isolated API. So inside that I API you will construct your model of users/auth logic. So in that case only that API can access Dgraph.

The first one I don’t see hurry to implement. But as most of all database has it. It’s good to has too.

Cheers.

Hi,
I 'm also interested in the access control feature.
Just like other databases, you can create user, grant or revoke user privileges for resource access.
I want a feature of query control.
if I grant an access privileges to user bob for some URI like
“bob:/function/has”, ## this means bob can use has function in query
“bob:/hasUser/user/createdTime”,
then bob can write query like this:

{
 q(func: has(hasUser)){
          user{
                  createdTime
          }
  }
}

However, if bob write a query like this,

{
 q(func: has(hasUser)){
          user{
                  name
          }
  }
}

an access deny response should be given.
for he didn’t have access privilages for “bob:/hasUser/user/name”

by the way, “bob:/" means bob can access any resources.
"bob:/
/name/*” means bob can access all “name” predicates

PS. Or maybe I’m just confusing everything. Zer09 said “managing users for the database”. For me he is talking about DB access and not application level.

Well, for end users I do not see much relation to this authentication control feature (But Dgraph is working on it) with the Dgraph instance access control. I think this could be something like “security” matters and not user management.

@BlankRain Today you can do what you wanna do, just mount your bussines logic facing this. You can use specific kinds for group of Nodes (this is fully free, up to you). You can create something like “has (protected)”, “has (top.secret)”, “has (pin.to.access)” and several possibilities to add to your nodes. Hence you will determine in your API how to handle it. Your API will determine who has access or not.

Taking GraphQL as an example, it does not have this feature by default. The GraphQL team neither gives a specific recommendation, leaving it totally free for developers to choose the best approach. In Dgraph you already have something plausible as I exemplify above.

And I don’t know if there is some DB with user management alredy ready to go. It does exist?

your idea is great. thank you very much :grinning::grinning::grinning:

1 Like

@mrjn @MichelDiz Hi. Is this in the works or is it already available? Had a look at the docs but that says that I have to add my own layer on top. Would prefer some kind of basic security mechanism to be provided by the DB layer itself since if I put one more layer on top, it will add more complexity/scaling problems - Dgraph can scale and I have to make the top layer scale with Dgraph.

If I am to add a layer above Dgraph, what would you recommend? I saw the Nginx conf which Ratel uses here: ratel/play-dgraph-io.nginx.conf at master · dgraph-io/ratel · GitHub - would it be something like that? Wanted to confirm before using it.

I am not interested in authorization at the moment in Dgraph cause I am handling that with Apollo. Using Dgraph as backend, Apollo as Frontend in Node.js

(PS: I am using GraphQL - So, I hope it will be some kind of header or basic auth which I can pass into the http call)

Thanks.

Humm, that topic has more than 2 years. I’m confused a bit about the context.

Well, if this topic was about User Auth to access the DB itself (not an application). This is handled today by ACL. Access Control Lists - Enterprise features

If this is about auth in the level application. It is https://dgraph.io/docs/graphql/authorization/directive/ - This Auth just works with GraphQL. DQL endpoints should be isolated.

Not sure what you see there. There’s nothing there. All the security on the Playground is handled by Dgraph itself. Which uses a flag to restrict mutations. But you still can query.

What kind of layer are you talking about? security layer? GraphQL is a layer for example.

Well, the Auth directive does exactly this If I’m not mistaking.

Cheers.

Hi @MichelDiz , Thanks for the quick reply. I was talking about the DB Level authentication and not application level authorization (I am handling that with apollo). I was looking for a simple way like what Postgres, MySQL, Mongo or any DB provides to authenticate (say basic auth or anything else) so that I can secure queries to my DB.

So, I guess in this case the @auth directive isn’t relevant. The layer I was talking about was the authentication layer for the DB as @mrjn mentioned in HTTP Authentication

I was using the Nginx Ratel example was to see how Ratel authenticates requests to Dgraph - For instance you ask for the userid and password for publicly exosed db and then let the users in. So, was looking at how you handle the auth in that case.

Hope this clarifies.

Hum, there are plans to add TLS everywhere and also add Poor Man’s ACL/Auth on the exposed endpoints. Like /mutate, /query, /commit, /graphql and so on.

e.g

@MichelDiz Great! I was looking for something similar to this link you shared: https://github.com/dgraph-io/dgraph/pull/5162 but for GraphQL endpoints. Looks like that is for /admin currently.

The PR you point has 3 kinds of checks in it:

  1. Guardian only access: Although it is an enterprise feature, ACL works at /graphql. Using ACL, you can set which users have what permissions on which predicates. Then you will need to log in the ACL user to get his JWT and supply the JWT at /graphql using the X-Dgraph-AccessToken header. That is one way to have DB level auth.

  2. Poor man’s auth: There is nothing concrete on Poor man’s auth for /graphql yet. If you would like to have Poor man’s auth on /graphql then please upvote the RFC for that.

  1. IP whitelisting: We haven’t yet felt a need to have IP whitelisting at /graphql, because this endpoint is supposed to be publicly exposed. If you think it would make sense to have IP whitelisting too at /graphql then please let us know your use case.
2 Likes

@abhimanyusinghgaur Sure. Have already upvoted for it. Just a poor man’s auth would be good enough.

Hey, sorry it takes me to long to chime in.

BTW my question is about the “managing users for the database itself” and not for the application lavel auth. But I think this issue is already solved in https://dgraph.io/docs/enterprise-features/access-control-lists/

Thanks

1 Like

Hi @tvvignesh,

We were discussing this, and we came across a way through which you can achieve this. We have an upcoming feature to disable queries by default if the @auth JWT is not supplied in the header.

So, if someone has configured @auth for their GraphQL schema, and they have turned on that feature to disable queries if no @auth JWT was supplied; then if someone sends a request, the GraphQL layer will first check if the JWT is there and is valid. Only when these conditions meet (acts like authentication), it will proceed to find query results according to the authorization (if any, specified in the JWT and on the query).

So, if you didn’t apply any @auth rules on any of your types, but still configured Dgraph.Authorization in your schema, then the @auth JWT just acts like authentication.

Does that sound useful to you in comparison to Poorman’s auth?

Sure. JWT will make a lot of sense more than poor man’s auth if you have the bandwidth.

Few thing to be taken care of / answered:

  1. Who is issuing the JWT? The App or the DB? Who will sign it?
  2. What will be the revoking mechanism if JWT is compromised before expiry?
  3. Will it be a perpetual token or will there be a refresh mechanism?
  4. Are you aiming for stateless auth with Dgraph or will the token be persisted in the DB (since the DB has state anyways)?
  5. How will nodes in a Dgraph Setup multiple alphas, zeros and ratel authenticate within themselves? Will they use JWT too?

JWT is a great way to go forward. Since Dgraph stores user data, security must be the top priority more than anything else and would definitely be everyone’s concern, so taking all the precautions is good.

JWTs are not issued by the DB. You would need to issue your own JWTs. The same private key is used by the issuer to sign and by the DB to verify.

Right now, the configuration allows to revoke all tokens by changing the private key.

This is all up to your implementation of issuing the JWTs. You could make short lived tokens that require the end users/app to make refresh requests. Or you could make a JWT that expires in 70 years.

The token must be sent with every request in a header. The tokens are not persisted to the database unless you persist it through a mutation, but this would just store it and not make it reusable unless it is attached to the header of the request.

The Dgraph.Authorization deals specifically with the /graphql endpoint and does not deal with inter cluster ccommunication. If ratel is communicating with the /graphql endpoint (which I don’t think it does at this time) then it would work with the JWT in the same manner.

1 Like

Thanks for the answers @amaster507 - Read this :https://dgraph.io/docs/graphql/authorization/authorization-overview/ after reading your answer and have now understood how Dgraph is authorizing with JWT.

One last question I have is, is it possible to have multiple private keys? If I have multiple microservices connecting to Dgraph and if private key on one service is compromised, with single private key I would end up revoking jwts of all services just because I changed private key of one service. And I have to go and update every service with the new private key.