solo-io / gloo

The Feature-rich, Kubernetes-native, Next-Generation API Gateway Built on Envoy

Home Page:https://docs.solo.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Graphql - Support for security headers from OpenAPI spec using autogeneration

nmnellis opened this issue · comments

commented

Gloo Edge Product

Enterprise

Gloo Edge Version

v1.16

Is your feature request related to a problem? Please describe.

Today we create all our graphql schemas using the autogenerated feature to convert OpenAPI spec to graphql endpoints but it does not support the authorization headers defined in the security spec of OpenAPI.

We need support for Authorization and X-App-Client-ID headers.

Here is a sample spec

{
  "openapi": "3.0.1",
  "info": {
    "title": "Entity Data Service",
    "version": "1.0.0"
  },
  "security": [
    {
      "bearer": []
    },
    {
      "clientId": []
    }
  ],
  "components": {
    "securitySchemes": {
      "clientId": {
        "type": "apiKey",
        "description": "Paste the X-App-Client-Id from your welcome mail into the box below and click 'Authorize'",
        "name": "X-App-Client-Id",
        "in": "header"
      },
      "bearer": {
        "type": "http",
        "description": "Retrieve bearer token by clicking on the 'Get Token' tab in the main page. Enter your username and password as supplied in your welcome mail. Copy the returned token and paste it into the box below and click 'Authorize' to use the 'Try it out' capability.",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      }
    }
  }
}

Describe the solution you'd like

No response

Describe alternatives you've considered

I can manually edit the schema after the fact but anytime its regenerated these headers will disappear.

Additional Context

No response

A "scripted" workaround would be to use yq against the GraphQLApi CR, like so:

#!/bin/sh

####################################################################################################
#
# Patch the GraphQLAPI CR and add standard headers to all operations.
#
####################################################################################################

INPUT_FILE=mocks-graphql-api-source.yaml

yq -i '.spec.executableSchema.executor.local.resolutions["*"].restResolver.request.headers += {"Authorization": "'{\$headers.Authorization}'","X-app-client-Id": "'{\$headers.X-app-client-Id}'"}' $INPUT_FILE

If we consider auto-generating the header passing, we should consider making that an opt-in, as it could be that the headers that the resolver should pass to the backend services should not come from the headers on the GraphQL request at all, or that headers have different names and/or formats across different services used in a larger graph. Both those use-cases would not work with auto-generated header passing ... in fact, it might actually be a security risk to automatically do that.

is the ask here to propagate the incoming headers upstream based on the OAS?
what happens if we stitch together multiple of these upstreams with different header requirements?

Would this need to be feature flag? as after the change we may send upstream headers that were not sent before.

Yes, the ask is that we, based on the headers defined in the OAS, propagate those headers from the GraphQL request to the Upstreams.

If we have multiple upstreams with different headers, I think we should simply map all of them, which would require the client to specify all the different headers on the GraphQL request. I really don't see another way around it.

And yes, I think this should be flagged as an "opt-in", because having this option as the default sounds kind of like a bad practice to me (in most use-cases).

The customer use-case here is that they have a standardized security-scheme across all their micro-services, where all of these services use the same set of security headers. When we generate the GraphQL resolvers for these services, if we don't add mappings for these headers, the resolver's requests simply won't work, as they're missing these required header. So this customer can never use the generated GraphQLApi CRs, and always has to enhance/enrich them with this header mapping logic. The thought was that, since the OAS has the information of the required security headers, we could add an "opt-in" to automatically generate these header mappings.