Adding a Auth Directive that only allows public access to some fields

Is there any way to just allow public access to some fields from a type? So in the example type below only allow other users to access id and name without giving access to the email?

type User {
  id: ID!
  name: String
  email: String
}

That’s not possible as far as I know.

It is not currently possible.

You basically have two work arounds:

  1. Create two User types, one with public, one with private info
  2. Lock the whole type from view, and create a custom dql query to query only what you want to be visible

J

Thanks for your response. With the two type option could the public node just reference the private one. Or would we have to duplicate the node?

The private could reference the public but not the other way around. The information would be different, as there would be no need to duplicate data.

J

Another idea in theory is to use an interface where the interface is the public and the implementing is the private. This would mean that the data was on a singular node still. There might be some other gotchas when using this model but in theory it should work.

1 Like

@amaster507 this will not work as expected. If I understood right, then you suggest something like this:

interface Public {
  id: ID!
  name: String
}

type User implements Public 
  @auth(
    # query rules - eg. users can only see their own email
  ){
  id: ID!
  name: String

  email: String
}

In such a scenario you would not be able to run a single user query for type User since @auth rules for the implementation of interfaces are connected with AND. Thus, querying (and applying the assumption that @auth is set so that a user can only query himself)

query User {
  queryUser {
    id
    name
    email
  }
}

# Result
{
  data: {
    queryUser: [
      {
        id: "0x1"
        name: "My User"
        email: "[email protected]"
      }
    ]
  }
}

would only give one result - that of the querying user. Running the query via the interface would result in the expected results for all users

query Public {
  queryPublic {
    id
    name
  }
}

# Result
{
  data: {
    queryPublic: [
      {
        id: "0x1"
        name: "My User"
      },
      {
        id: "0x2"
        name: "User 2"
      },
      {
        id: "0x3"
        name: "User 3"
      }
    ]
  }
}

So, at least in my understanding, the only way of having a single user query with the expected field protection is either via a @custom DQL query if you only care about query protection, or, if you need a more sophisticated approach (eg. including mutations), via custom lambda resolvers.

1 Like