node.jsgraphqlgraphql-federationgraphql-shield

Apollo Server Federation with graphql-shield


I'm using graphql-shield to protect a subgraph.

const isAuthenticated = rule({ cache: 'contextual' })(async (parent, args, ctx, info) => {
  return ctx.isAuthenticated
})

const permissions = shield({
  Query: {
    '*': and(isAuthenticated)
  },
  Mutation: {
    '*': and(isAuthenticated)
  }
})

const server = new ApolloServer({
    schema: applyMiddleware(buildSubgraphSchema([{ typeDefs, resolvers }]), permissions),
    introspection: global.configuration.ENVIRONMENT === 'development'
})

And in my build process, I'm using rover CLI to update thesupergraph schema in Apollo Studio:

rover subgraph introspect http://localhost/graphql | rover subgraph publish super-graph@development --routing-url http://localhost/graphql --schema - --name persons

The rover update fails because the permission shield throws a Not Authorised! error.

How do I protect the subgraph with graphql-shield and also permit SubgraphIntrospectQuery operation?

I understand it is possible to add a bearer token to the rover introspect command:

rover subgraph introspect http://localhost/graphql --header "Authorization: Bearer token"

However, there is no way for me to generate an access token during the build process.


Solution

  • I was able to resolve this issue by changing the scope of my authentication.

    Instead of authenticating all "*"

    const permissions = shield({
      Query: {
        '*': and(isAuthenticated)
      },
      Mutation: {
        '*': and(isAuthenticated)
      }
    })
    

    I change to authenticating individual operations:

    const permissions = shield({
      Query: {
        'user': and(isAuthenticated),
        'users': and(isAuthenticated)
        ....
      },
      Mutation: {
        'createUser': and(isAuthenticated),
        'updateUser': and(isAuthenticated)
        ....
      }
    })