hasura / graphql-engine

Blazing fast, instant realtime GraphQL APIs on your DB with fine grained access control, also trigger webhooks on database events.
https://hasura.io
Apache License 2.0
31.08k stars 2.76k forks source link

Decouple authorization headers (and/or URL) while fetching remote schema introspection from authorization headers (and/or URL) for running GraphQL queries against the remote schema #4890

Open tirumaraiselvan opened 4 years ago

tirumaraiselvan commented 4 years ago

Suppose you have an external graphql service which has authentication. Most likely it has a bearer token based authentication which is given in the Authorization header.

If we want to add this service as a remote schema, we need to configure a Authorization header. But this means that the client when making queries will not be able to use their own Authorization header as it will be over-ridden during runtime.

To solve this, you may add the remote schema with a special admin-access-key header but the problem now is that for every call to the remote schema, the admin-access-key is unnecessarily sent. You need to be especially careful that your remote schema uses the Authorization header to resolve the access controls and NOT the admin-access-key. PS: In case of another Hasura remote schema, this problem is averted because we can use x-hasura-admin-secret to add the remote schema and the session variables are added automatically during runtime.

A quick solution to this is to have special auth headers that are used only for adding/modifying remote schema and not used during runtime.

coco98 commented 4 years ago

My feeling is that providing the graphql introspection result of the graphql server as an optional parameter while adding a remote schema. My fear is that this would make the headers and authz system more complicated to reason about.

JasCodes commented 3 years ago

@coco98 Let's take example of Github. It's not possible to get Root access of their Graphql API. So I need to pass user Autherization header. And based on the token certain graphql API will be exposed. And there lies the tricky part. You can't see remote api if token is not provided, or atleast sample token to do initial introspection.

convcha commented 3 years ago

I agree with @tirumaraiselvan. I think it would remove unnecessary complexity if we could add a header that is only used when adding/updating remote schemas. I've given up and am trying to add my own header from the Hasura console, but I'm a little afraid it will also be given to requests from clients.

abjrcode commented 3 years ago

I totally second this proposal as well: Remote schema introspection requests should not conflate with normal requests It's not even clear that this is the case in the UI. It doesn't show you that headers configured on the remote schemas will be passed on during normal end user GraphQL requests.

IMHO Normal GraphQL requests shouldn't be mixed with Introspection requests.

Bessonov commented 2 years ago

Ran in the same issue. Because I control every aspect, I disable security if a special header is present (= check if the request comes from hasura) and if x-hasura-role isn't set (=check if the request was initiated from add schema and not through hasura's endpoint). Any thoughts on that? Is there any security issue?

Remote schema introspection requests should not conflate with normal requests

Agree. And additionally it should supports an authentication as an OAuth2 confidential client through resource owner password grant.

AndresPrez commented 2 years ago

Helloo @coco98 ! is there any progress on this one?

ryanto commented 2 years ago

I'd love if we could add a header that only gets included when adding or updating a remote schema.

The reason I need this is I don't want to expose introspection on my GraphQL server, but need to somehow allow introspection when Hasura is trying to add/update.

PS: I'm loving Hasura's remote schemas + stitching 😄

abooij commented 2 years ago

As a long-term path forwards on issues like these, we're currently exploring the idea of storing the remote schema introspection. If this stored introspection could be provided explicitly to Hasura, then you could request it with any HTTP headers you want.

However:

  1. I can't promise that we'll do this, it's merely being explored as an option right now.
  2. Because it's just in an exploratory phase, we don't have any details on how this would work yet.
  3. It would take quite some time to implement this.
  4. I don't know anything about how this feature would be made available.
dorianiq commented 1 year ago

I agree introspection and run-time requests should have separate header management. It's also quite a hassle to deal with when rotating admin secrets between remote services.

djnym commented 1 year ago

We have this exact issue right now so and are looking to implement a workaround with an extra header that would allow introspection only. One thought did occur to me that if you allowed uploading of a schema as a file that might also provide a way to work around this. Has that been considered for remote schemas?

maxcan commented 1 year ago

My feeling is that providing the graphql introspection result of the graphql server as an optional parameter while adding a remote schema. My fear is that this would make the headers and authz system more complicated to reason about.

This would be super beneficial for me. My basic set up is this:

graph TD;
    hasura(hasura on aws fargate)<-->postgres(postgres on aws rds);
    lambda(lambda remote schema)<-->hasura;
    apigw(aws api gateway)-->hasura
    inet(((the internet)))<--> apigw

For the lambda graphql server, it interacts with the database completely via hasura. However, the schema is statically generated in development so lambda doesn't need hasura running at launch. It would alleviate some issues if we could also statically pass in the expected lambda graphql schema.

yorgyetson commented 1 year ago

I am also running into this issue now. I have a remote schema that manages it's own roles/permissions and can be configured with the same JWT secret as Hasura. But I don't have a way for the users to pass their own Authorization header since it is overridden by the config.