'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 1:[1]

You could try allowing the following branches:

export const permissions = shield({
    Query: {
        _service: allow,
    },
    _Service: {
        sdl: allow
    }
},{
    fallbackRule: deny,
    allowExternalErrors: true,
    ...
});

When Apollo performs the introspection, it uses these two branches initially. Also note the "allowExternalErrors" flag. When encountering an error, graphql-shield absorbs them, which can hide issues which you are trying to debug. This might also be a problem, although your code seems fine otherwise.

Apollo also uses "Query._entities", "Query._service", "_Entity.*", "_Service.*", "_Any.*" but I haven't found this to be used by the initial introspection.

You mentioned that you can't generate a token for your build process but it is probably a good idea to protect these endpoints rather than use allow.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Namyts