#Securing a GraphQL API for public access

1 messages · Page 1 of 1 (latest)

worn latch
#

When your GraphQL API serves both internal admin functions and user data, how do you safely expose it to the public internet? I'm facing this challenge as we prepare to launch our mobile app, and I'd love to hear this community's thoughts on the best approach.

The current web app is server-side rendered, this gives me a huge benefit that the App Backend to API Server can be done purely in the private network in our cluster. Some dynamic pages still do JSON calls to the legacy backend and then the backend does the GraphQL query to the user.

Authentication in our GraphQL API is done via JWT tokens, if a user has a valid session, we pass that session context to our API via this token. Authentication is handled through this token. This same API also provides queries and mutations for administrative things, these are already handled via RBAC.

And there are highly-sensitive internal APIs that only server-controlled code can only call. For this, we have special app-scoped JWT tokens. And these are guarded in the resolvers as well.

My main concern is going to be around deployment strategies and and protecting sensitive queries and mutations. These are already protected via authentication guards, but nothing keeps people from trying to discover their existence by analyzing the error responses.

I can think of 3 options so far and I would love this communities feedback and ideas!

  • Just expose the API, rely on schema introspection being off. Mutations and queries are checked at runtime for authorization.
  • Use a @public directive and then have a separate API Gateway deployment reverse proxy the API and uses this directive to filter out anything that is not tagged public
  • Deploy the core API in 2 modes, internal & public. With the public mode doing schema validation-level rejections (kinda what the API gateway would do)

Has anyone implemented the @public directive approach? How did you handle schema synchronization? Are there other approaches I haven't considered?

surreal cargo
#

Disabling introspection is one thing, don't forget the other stuff like error masking, query nesting depth and rate limiting

#

I think you can funnel the traffic from the internet through an api gateway that does the authentication and authorization that should give you full control over what goes where, and yes, some things like login are most likely to be public. It gets more difficult if you want to introduce a public directive on field level. but if it stays on resolver level a guard should be ok

worn latch
#

I ended up migrating from Apollo to Yoga as the graphql-server. I really like how it defaults to a well handled error masking behavior.