What is the endpoint of a namespace on a dedicated server?

I have set up 2 Namespaces in my dedicated cluster. What is the GraphQL endpoint of those?

It is the same. You just need to login(ACL) into the right user of that namespace.

@MichelDiz thanks for the answer! :raised_hands:

I’ve tried all day to get this working today.

I have now found a way to run the login(userId: "", password: "", namespace: 1) query from the Tenant-0 because this is the only namespace I have access to from outside the Cloud interface. I do this because I don’t want to expose the Admin Key in my application! It’s weird but at least this seemed to work and I could query the other namespace from my app.

The next problem I ran into was that my custom lambda stopped working with the error message that no access JWT has been submitted! So it seems that the X-Dgraph-AccessToken header is not getting forwarded to the internal dql.mutate and dql.query functions! How would I do this? The actual error message I get is:

"rpc error: code = Unauthenticated desc = no accessJwt available"

I have further noticed that if I run queries (in my namespace) from the GraphQL tab, including my custom Auth header, it result in a “Network Error”. Investigation of the network tab in the browser shows that it’s because of a CORS error! What is going on here?

I think there is a long discussion about this here in discuss. @amaster507 do you know how?

Maybe you could use the next thing I mention about NGINX bellow.

You can hide any key behind via NGINX header passthrough proxy_set_header X-Dgraph-AccessToken your-key-here. But never do this with admin keys. Cuz with admin you can edit/see /admin configs.

With this you can create a proxy between your API or something - between lambda and the API. With proxy_set_header the key will be passed.

Not sure, there is a new guideline from Google that prohibits browsers and engines from communicating with non-HTTPS applications whether it comes from a protected site or not. Only HTTP to HTTP or HTTPS to HTTPS.

Thanks for the quick reply!

Well, I would still need to bundle the admin key with my app, right? I have to use the admin key because the login mutation only exists on the /admin endpoint. That’s what confused me so much. How is this supposed to work and why is the Tenant-0 always exposed to public?

Here’s what I did to get the accessJWT when I query against the graphql endpoint:

type Tokens {
  accessJWT: String
  refreshJWT: String
}

type LoginPayload {
  response: Tokens
}

type Mutation {
		getTokenForNamespace(userId: String, password: String, namespace: Int, refreshToken: String): LoginPayload @custom(http: {
			url: "https://<endpoint>/admin",
			method: POST,
			secretHeaders: [
        "DG-Auth:AdminKeyTesting"
      ],
    	introspectionHeaders:["DG-Auth:AdminKeyTesting"]
      graphql: "mutation($userId: String, $password: String, $namespace: Int, $refreshToken: String) { login(userId: $userId, password: $password, namespace: $namespace, refreshToken: $refreshToken) }"
		})
}



# Dgraph.Secret AdminKeyTesting "YOUR-ADMIN-KEY-HERE"

Why does it work on the Shared Cluster then?

Nope. if you pass via NGINX, you don’t need. But the Key will will expire in some moment.

We have the Slash API Key. I don’t know how this works in a dedicated server. Can you help @rarvikar ?

If you are using ACL you can expose it. What you can’t is left the login key available to anyone.

I have no idea, What I told you is a fact. Now how much it affects Cloud I don’t know.

I think I have this as well. Found it when I have opened Ratel and then under the Extra Settings tab. What would I use this API Key for? For sure not in a Webapp, right?

Yes I do but I can’t see how I would expose it and how I would be able to differentiate between my namespaces then - I only have one endpoint.

Not saying that this is the case but I’m not sure if this is the problem. The referer is https so I guess this should work. It also works if I don’t submit a custom header! I was assuming that a Shared Cluster is somehow similar to a dedicated instance, I just have access to one namespace. Furthermore, it would really surprise me if the built in GraphQL tab of the Cloud admin interface does not work as soon as a custom header is submitted. I’m guessing that it is not only me running a dedicated server.

If you open Ratel from the Cloud Panel. It will create an API Key and inject on the fly.

If you wanna use Ratel from your end. You have to go in the panel and create an Admin or User Key.

BTW, Have you tried X-Dgraph-AuthToken?

Cuz you have a login. The namespaces are ACL Login bound. Once you log in with the user of that namespace, you will be redirected to the GraphQL of that namespace.

I’m not sure. Dedicated servers tend to have a different logic than shared servers. I never used a dedicated one.

No, I have not tried the X-Dgraph-Auth Token but like I’ve said. I have used the X-Dgraph-AccessToken which gets generated when logging in via the /admin endpoint of the Dedicated Cluster.

As I’ve said, I was able to query data from my application using this token but unfortunately my lambda is not woking since it seems that only my Custom Header (eg. X-Auth-Token) gets forwarded to the lambda resolver. Which I could confirm by login the authHeader parameter in the resolver.

However, since the lambda is stored in that specific namespace I thought that it automatically attaches the appropriate header for the lambda. This is a serious problem since I can basically not use dql or graphql inside the lambda.

Update

I have the feeling that the header forwarding is an issue. It seems that the X-Dgraph-AccessToken never gets forwarded (and somehow also not added, even when accessing lambda resolvers on the very same namespace). If this is the case then Dgraph Cloud with multi tennency is simply not working! Correct me, but I have no clue how we would have @auth rules in combination with the X-Dgrap-AccessToken at the same time.

If I remember right Dgraph Lambda ist hosted on Cloud. Then this could be an issue here

async function dqlMutate(mutate: string | Object): Promise<GraphQLResponse> {
  const response = await fetch(`${process.env.DGRAPH_URL}/mutate?commitNow=true`, {
    method: "POST",
    headers: {
      "Content-Type": typeof mutate === 'string' ? "application/rdf" : "application/json",
      "X-Auth-Token": process.env.DGRAPH_TOKEN || ""
    },
    body: typeof mutate === 'string' ? mutate : JSON.stringify(mutate)
  })
  if (response.status !== 200) {
    throw new Error("Failed to execute DQL Mutate")
  }
  return response.json();
}

since no X-Dgraph-AccessToken is getting submitted! I have also tried to manually do a fetch request inside a lambda resolver, where I have included a valid access token.

const response = await fetch(`https://MY_BACKEND/mutate?commitNow=true`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Dgraph-AccessToken": "MY_TOKEN",
          
      },
      body: JSON.stringify({
        query: `{ q(func: uid(${input.id})) { uid } }`,
        mutations: [{}],
      }),
    });

   
    const test = await response.json();

Doing this results in an access denied error

{\"data\":null,\"errors\":[{\"message\":\"Access Denied\"}]}