# @Auth for multiple layers in a query

**URL:** <https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071>\
**Category:** Dgraph Cloud\
**Created:** [December 24, 2020, 6:12pm UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071 "2020-12-24T18:12:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![haPartnerships](https://avatars.discourse-cdn.com/v4/letter/h/dec6dc/32.png) [@haPartnerships](https://discuss.dgraph.io/u/haPartnerships)\
**Post date:** [December 24, 2020, 6:12pm UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071/1 "2020-12-24T18:12:13Z")

</div>

Hi

I have a simple schema describing the relationships from a consultancy to a project for a solution I am developing. Effectively a Consultancy has many Engagements which have many Programmes which have many Projects.

Schema as follows:

```auto
type Person {
	userName: String! @id 
  	firstName: String! 
	lastName: String! 
}

type Consultancy{
	id: ID! 
	name: String! 
	engagements: [Engagement] @hasInverse(field:consultancy) 
	users: [Person!] 
}

type Engagement {
	id: ID! 
	name: String! 
	consultancy: Consultancy! 
	programmes: [Programme] @hasInverse(field:engagement)
  	users: [Person!] 
}

type Programme {
	id: ID! 
	name: String! 
	engagement: Engagement! 
	projects: [Project] @hasInverse(field:programme)
  	users: [Person!] 
}

type Project {
	id: ID! 
	name: String! 
	programme: Programme! 
  	users: [Person!] 
}

```

What I am trying to get my head around is how to restrict access using @Auth (I will have a JWT token with a key ‘email’ which contains… well the email of the ‘Person’ that has been authenticated).

I cannot work out two things from the documentation:

1. how can I use a filter to filter for items (Consultancy, Engagement, Programme, Project) where their ‘users’ collection includes a Person with the userName that is equal to the JWT email key value.

2. my queryConsultancy query, by virtue of having a collection of Engagements, allows access to any Engagements that are related to the Consultancy and therefore I need to be able to also restrict access through the queryConsultancy query to those engagements based on the same principle as for the Consultancies. In turn that cascades into the programmes and projects too with the same restrictions being required.

In pseudo code what I need is:

```auto
query MyQuery {
  queryConsultancy (where a user has the JWT email value) {
    id
    name
    engagements (where a user has the JWT email value) {
      id
      name
      programmes (where a user has the JWT email value) {
        id
        name
        projects (where a user has the JWT email value) {
          id
          name
        }
      }
    }
  }
}

```

I am sure this cannot be a novel use case but I am struggling with the docs and my emerging understanding of GraphQL.

Thanks in advance

---

<div class="post-metadata">

**Author:** ![haPartnerships](https://avatars.discourse-cdn.com/v4/letter/h/dec6dc/32.png) [@haPartnerships](https://discuss.dgraph.io/u/haPartnerships)\
**Post date:** [December 24, 2020, 6:57pm UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071/2 "2020-12-24T18:57:43Z")

</div>

Just a slight addition to the post - If I am approaching this with a bad design principle to start with please do feel free to point that out with helpful advice on a better approach - that would be appreciated too!

---

<div class="post-metadata">

**Author:** ![haPartnerships](https://avatars.discourse-cdn.com/v4/letter/h/dec6dc/32.png) [@haPartnerships](https://discuss.dgraph.io/u/haPartnerships)\
**Post date:** [December 27, 2020, 11:53am UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071/3 "2020-12-27T11:53:15Z")

</div>

Have I been really dim?..

My head was in a ‘secure an API end-point’ frame of mind i.e. the query needs @auth rules applied but it just clicked that in /Graph @auth rules are applied at the type level not the query level and therefore will inherently be applied to nested arrays of types within a query.

Is that right or have i still missed the @auth model in /graph?

Thanks in advance

---

<div class="post-metadata">

**Author:** ![rajas](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rajas/32/4393_2.png) [@rajas](https://discuss.dgraph.io/u/rajas)\
**Post date:** [December 28, 2020, 6:47am UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071/4 "2020-12-28T06:47:54Z")

</div>

> [@haPartnerships](#):
>
> /Graph @auth rules are applied at the type level

Yes, auth rules are applied at type level. You may add different auth rules for adding, deleting, updating and querying a data type.

> [@haPartnerships](#):
>
> therefore will inherently be applied to nested arrays of types within a query.

This is not completely true.  
Example:  
`Consultancy` has a `query` auth rule defined and `Engagement` does not have any auth rule.  
This will only put all objects of type `Consultancy` behind auth rules. Objects of type `Engagement`, even if part of some consultancy won’t be behind any auth rules.  
This means that querying `queryConsultancy` with unsatisfied auth rule, no data will be returned. But as Engagement does not have any auth rules, data will be returned while querying `queryEngagement`.

---

<div class="post-metadata">

**Author:** ![rajas](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/rajas/32/4393_2.png) [@rajas](https://discuss.dgraph.io/u/rajas)\
**Post date:** [December 28, 2020, 7:10am UTC](https://discuss.dgraph.io/t/auth-for-multiple-layers-in-a-query/12071/5 "2020-12-28T07:10:50Z")

</div>

> [@haPartnerships](#):
>
> how can I use a filter to filter for items (Consultancy, Engagement, Programme, Project) where their ‘users’ collection includes a Person with the userName that is equal to the JWT email key value.

You may use the auth query rule on type Consultancy as follows:

```auto
type Consultancy @auth(
    query: { rule: """
       query($email: String!){
          queryConsultancy{
             users(filter:{userName:{eq:$email}}){
                userName
             }
          }
       }   
       """
    }
){
	id: ID! 
	name: String! 
	engagements: [Engagement] @hasInverse(field:consultancy) 
	users: [Person!] 
}

```

The `email` provided using the JWT token will be used as $email variable in the auth query.  
What this auth query does is that, it will filter out only the `consultancies` for which the `users` contains provided `email` as `userName`.

> [@haPartnerships](#):
>
> my queryConsultancy query, by virtue of having a collection of Engagements, allows access to any Engagements that are related to the Consultancy and therefore I need to be able to also restrict access through the queryConsultancy query to those engagements based on the same principle as for the Consultancies. In turn that cascades into the programmes and projects too with the same restrictions being required

Can an `Engagement`, `Project`, `Programme` be part of multiple `Consultancies` with different `Users`. In that case, you may have to add similar auth query rule to `Engagement` and other types as well.

If an `Engagement` is going to be part of a single `Consultancy` and `Engagement` is not going to be queried separately with `queryEngagement`, it will make more sense to not have auth rules for `Engagement` and use [generate directive](https://dgraph.io/docs/graphql/schema/generate) to explicitly disable `queryEngagement` query.

In case you are looking for more examples of using `@auth`, there is [Todo App Tutorial repo](https://github.com/dgraph-io/tudo-tutorial/tree/master/deploy/SlashGraphQL) containing schema and auth examples of a Todo Auth app.

Thanks for your feedback about @auth directive documentation. We will also be looking at improving it. Do let us know if you have any other questions.
