You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GraphQL as a spec supports custom directives. This is how Apollo is able to add things like @key and @external.
We can leverage our own custom directive(s) to better support authorization (for example). The linked docs have an example section on authorization, but we can do something even better since we have our authorization already abstracted into its own service.
Inside our schemas we can annotate types, queries, and mutations with things like their resource path, which would let us implement gateway-level authorization.
These are pseudo-examples from pricing. These are simplified and not the exact types or names used in pricing, but I wanted to use something more grounded in reality than metasyntactic variables.
The directive we really care about here is what I called ref.
Name not set in stone. @kieckhafer and I brainstormed a few more:
@affects
@concerns
@hook
@involves
@policy
@ref
@reference
@uses
@bind
@connect
@entity isn't really well thought-out or an official idea, I was just spitballing some other things we could annotate.
@key is a directive added and used by Apollo Federation itself.
The first query is an example of a query (getPricebook) that works with one resource. This will be our most common case.
The second query (getPricebookEntry) is an example that works with two resources, as clients are able to request fields on pricebooks as well.
This plan does not support referencing conditional or optional resources. For example, if getPricebookEntry only enforced rules on pricebook-entries unless clients request fields within pricebooks, with this plan I suppose the workflow would be to only annotate with the former, and optionally enforce the latter in the pricing service itself.
How
The work required for this issue:
vet custom directives for our use, figure out how to make them an how best to fit them into our ecosystem
figure out how to cleanly add them to all services
I noticed that when you startup with a custom directive buildFederatedSchemas complains that you are using an unregistered directive. We still want individual services to be able to run independently of the federation, so we need to either figure out why, or perhaps define the directives in each service's schema.
implement @ref (in concept---can be called anything that makes sense)
Why
This lets us do some really cool things. It will let us go from have 0% of our authorization checks at the gateway level and 100% at the app level to having most of them (by far) at the gateway level. This means we will be able to determine whether users are authorized to perform certain actions before we even call out to the app in question.
The text was updated successfully, but these errors were encountered:
Do we want to define some default mapping or a directive that maps queries and mutations to actions? Like do we want by default to map the name of the query/mutation to the action name directly? For example: graphql query primaryShopId maps to authz action 'primaryShopId`.
Nevermind I see there's an explicit `action:' annotation parameter
@ticean and I discussed directives like this early on (I wrote a couple that did all the ID encode/decode automatically) but we opted not to use them because we weren't sure how/if they would work across microservices (which at the time meant schema stitching but now means federation support). Assuming you've tested and verified that this all works transparently with federation, then yipee! Specifically, my concern would be whether both the service and the gateway would need to install the directives, and potential mismatches with that.
We may want to prefix the directives to avoid clashes, unless this will be a generic solution that isn't tied to Reaction.
Do we need a way to support either AND or OR when they specify multiple checks?
Have you considered moving all non-mutation checks to decorate the types rather than the queries? I don't know if it's feasible, but I can think of at least three clear benefits:
Guarantee that the visibility of a type is the same everywhere, without the same check in multiple places.
We could omit/error a type at any level if there are children of children of children, etc. requested
Query rules would be applied automatically to the responses of mutations as well, ensuring that you can't see something simply because you can mutate it (up for debate whether this is good or bad).
What about some of the special cases like owner access?
aldeed
added
the
enhancement
For issues that describe a feature that needs to be added, changed, or removed, but is not a bug
label
May 5, 2020
What
GraphQL as a spec supports custom directives. This is how Apollo is able to add things like
@key
and@external
.We can leverage our own custom directive(s) to better support authorization (for example). The linked docs have an example section on authorization, but we can do something even better since we have our authorization already abstracted into its own service.
Inside our schemas we can annotate types, queries, and mutations with things like their resource path, which would let us implement gateway-level authorization.
For example:
Some notes on the above:
ref
.@affects
@concerns
@hook
@involves
@policy
@ref
@reference
@uses
@bind
@connect
@entity
isn't really well thought-out or an official idea, I was just spitballing some other things we could annotate.@key
is a directive added and used by Apollo Federation itself.getPricebook
) that works with one resource. This will be our most common case.getPricebookEntry
) is an example that works with two resources, as clients are able to request fields on pricebooks as well.getPricebookEntry
only enforced rules on pricebook-entries unless clients request fields within pricebooks, with this plan I suppose the workflow would be to only annotate with the former, and optionally enforce the latter in the pricing service itself.How
The work required for this issue:
buildFederatedSchemas
complains that you are using an unregistered directive. We still want individual services to be able to run independently of the federation, so we need to either figure out why, or perhaps define the directives in each service's schema.@ref
(in concept---can be called anything that makes sense)Why
This lets us do some really cool things. It will let us go from have 0% of our authorization checks at the gateway level and 100% at the app level to having most of them (by far) at the gateway level. This means we will be able to determine whether users are authorized to perform certain actions before we even call out to the app in question.
The text was updated successfully, but these errors were encountered: