-
Notifications
You must be signed in to change notification settings - Fork 268
fix(query-planning): Prevent error for satisfiable @shareable mutation fields
#3304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(query-planning): Prevent error for satisfiable @shareable mutation fields
#3304
Conversation
🦋 Changeset detectedLatest commit: c3a0bc0 The changes in this PR will be included in the next version bump. This PR includes changesets to release 7 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Docs preview has no changesThe preview was not built because there were no changes. Build ID: 29e66b239b70546e5b20804e |
|
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. |
e727633 to
5dd2b5c
Compare
@shareable mutation fields
369029b to
57c8040
Compare
duckki
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Just like the Rust QP counterpart.
…able` mutation fields (#8352) This PR fixes a bug where query planning may unexpectedly error while planning an operation with a satisfiable `@shareable` mutation field. Specifically, this PR: 1. Updates query planning on mutation fields to only consider one initial subgraph at a time for a traversal, and returns the plan with lowest cost. - Previously, this was mixing up options that started in different subgraphs in the same traversal, which would sometimes generate query planning errors if those differing options were chosen. There were a few ways to fix this, but the least invasive/simplest was just to do multiple traversals, each with a limited initial subgraph. - Non-local selection estimation was also appropriately updated to account for this (if it weren't, it would systemically overestimate the number of non-local selections). 2. Updates a particular query planning optimization to avoid discarding an option if another option with less subgraph jumps/cost is found, if that option starts in a different subgraph and the option is for a mutation operation. 3. Updates query planning to ignore `@key` edges at top-level (previously only root type resolution edges were ignored). This PR is the equivalent of [this JS repo PR](apollographql/federation#3304). Unrelatedly, this PR also fixes an error messaging issue when QP unexpectedly doesn't find a plan (this shouldn't happen, but if it did, it was previously using the wrong federation error enum and message).
duckki
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I confirmed that this PR matches the Rust update. Approved again.
…tial subgraph constraints
a436eaa to
c3a0bc0
Compare
…3305) This PR fixes a bug where composition may erroneously declare a schema with a `@shareable` mutation field satisfiable when it shouldn't be. Specifically, this PR updates composition satisfiability to ensure that all query paths under a `@shareable` mutation field can be satisfied starting at the same subgraph. (I.e., that no matter what selection set is on the `@shareable` mutation field, the query planner will not need to make multiple calls to that mutation field across subgraphs.) This is done by partitioning subgraph paths in `ValidationState` by the initial subgraph when a shared mutation field is encountered, and keeping track of separate error stacks as well. If all these partitions experience satisfiability errors, then there's no way to satisfy the selection set containing the witness operation from each partition using a single `@shareable` mutation field call, and the user is asked to fix (at least) one of the partition's satisfiability errors. This PR may cause composition errors for a previously successful composition if that composition was mistakenly satisfiable due to this bug. We've determined that this may not be a rare occurrence, and accordingly this fix will land in the next minor release (which is why this PR was split off from #3303, where it was originally filed). This PR is currently stacked on top of #3304 for tests to pass, but once that PR merges and is pulled into `next`, this PR's base will change to `next`.
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to next, this PR will be updated.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ `next` is currently in **pre mode** so this branch has prereleases rather than normal releases. If you want to exit prereleases, run `changeset pre exit` on `next`.⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ # Releases ## @apollo/composition@2.12.0-preview.4 ### Minor Changes - Fixes a bug where composition may not generate a satisfiability error for an unsatisfiable `@shareable` mutation field. ([#3305](#3305)) ([#3305](#3305)) ### Patch Changes - Fixed handling `@requires` dependency on fields returned by `@interfaceObject` ([#3318](#3318)) Depending on the merge order of the types, we could fail composition if a type that `@requires` data from an `@interfaceObject` is merged before the interface. Updated merge logic to use explicit merge order of scalars, input objects, interfaces, and finally objects. - Updated dependencies \[[`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499)]: - @apollo/federation-internals@2.12.0-preview.4 - @apollo/query-graphs@2.12.0-preview.4 ## @apollo/gateway@2.12.0-preview.4 ### Patch Changes - Updated dependencies \[[`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`bc07e979b9fd24c9b94740b170f11023fe99ba1e`](bc07e97), [`9cbdcb53f859c877a476e2725faa4cb205506f57`](9cbdcb5)]: - @apollo/federation-internals@2.12.0-preview.4 - @apollo/query-planner@2.12.0-preview.4 - @apollo/composition@2.12.0-preview.4 ## @apollo/federation-internals@2.12.0-preview.4 ### Patch Changes - Fixed demand control validations ([#3314](#3314)) Updated `@cost`/`@listSize` validations to use correct federation spec to look them up in the schema. ## @apollo/query-graphs@2.12.0-preview.4 ### Patch Changes - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4)]: - @apollo/federation-internals@2.12.0-preview.4 ## @apollo/query-planner@2.12.0-preview.4 ### Patch Changes - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499)]: - @apollo/federation-internals@2.12.0-preview.4 - @apollo/query-graphs@2.12.0-preview.4 ## @apollo/subgraph@2.12.0-preview.4 ### Patch Changes - Updated dependencies \[[`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4)]: - @apollo/federation-internals@2.12.0-preview.4 ## apollo-federation-integration-testsuite@2.12.0-preview.4 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to next, this PR will be updated. # Releases ## @apollo/composition@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) - Added isSuccess argument to @connect and @source ([#3294](#3294)) - Fixes a bug where composition may not generate a satisfiability error for an unsatisfiable `@shareable` mutation field. ([#3305](#3305)) ([#3305](#3305)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - Automatically propagate authorization requirements from implementing type to interface in the supergraph. ([#3321](#3321)) Authorization requirements now automatically propagate from implementing types to interfaces during composition. Direct auth specifications on interfaces are no longer allowed. Interface access requires satisfying ALL implementing types' requirements (`AND` rule), with these requirements included in the supergraph for backward compatibility with older routers. - Fix transitive auth requirements on `@requires` and `@fromcontext` ([#3321](#3321)) Adds new `postMergeValidation` check to ensure that all fields that depends on data from other parts of the supergraph through `@requires` and/or `@fromContext` directives explicitly specify matching `@authenticated`, `@requiresScopes` and/or `@policy` auth requirements, e.g. ```graphql type T @key(fields: "id") { id: ID! extra: String @external # we need explicit `@authenticated` as it is needed to access extra requiresExtra: String @requires(fields: "extra") @authenticated } type T @key(fields: "id") { id: ID! extra: String @authenticated } ``` - Preparing new preview release 2.12.0-preview.3 (patch). ([#3308](#3308)) - Adding new CompositionOption `maxValidationSubgraphPaths`. This value represents the maximum number of SubgraphPathInfo objects that may exist in a ValidationTraversal when checking for satisfiability. Setting this value can help composition error before running out of memory. Default is 1,000,000. ([#3275](#3275)) - Restrict usage of auth directives on interfaces ([#3321](#3321)) Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields. GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime. - Allow merging external types when using arrays as default arguments. ([#3096](#3096)) - Stricter merge rules for @requiresScopes and @Policy ([#3321](#3321)) Current merge policies for `@authenticated`, `@requiresScopes` and `@policy` were inconsistent. If a shared field uses the same authorization directives across subgraphs, composition merges them using `OR` logic. However, if a shared field uses different authorization directives across subgraphs composition merges them using `AND` logic. This simplified schema evolution, but weakened security requirements. Therefore, the behavior has been changed to always apply `AND` logic to authorization directives applied to the same field across subgraphs. Since `@policy` and `@requiresScopes` values represent boolean conditions in Disjunctive Normal Form, we can merge them conjunctively to get the final auth requirements. For example: ```graphql # subgraph A type T @authenticated { # requires scopes (A1 AND A2) OR A3 secret: String @requiresScopes(scopes: [["A1", "A2"], ["A3"]]) } # subgraph B type T { # requires scopes B1 OR B2 secret: String @requiresScopes(scopes: [["B1"], ["B2"]] } # composed supergraph type T @authenticated { secret: String @requiresScopes( scopes: [ ["A1", "A2", "B1"], ["A1", "A2", "B2"], ["A3", "B1"], ["A3", "B2"] ]) } ``` This algorithm also deduplicates redundant requirements, e.g. ```graphql # subgraph A type T { # requires A1 AND A2 scopes to access secret: String @requiresScopes(scopes: [["A1", "A2"]]) } # subgraph B type T { # requires only A1 scope to access secret: String @requiresScopes(scopes: [["A1"]]) } # composed supergraph type T { # requires only A1 scope to access as A2 is redundant secret: String @requiresScopes(scopes: [["A1"]]) } ``` - Fixed handling `@requires` dependency on fields returned by `@interfaceObject` ([#3318](#3318)) Depending on the merge order of the types, we could fail composition if a type that `@requires` data from an `@interfaceObject` is merged before the interface. Updated merge logic to use explicit merge order of scalars, input objects, interfaces, and finally objects. - Updated dependencies \[[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](3e2b0a8), [`bb4614d338ae03bac51a5fc2439590f172c4e54d`](bb4614d), [`99f2da21de88f9ad9a32ee7ed64b2d4a92887b40`](99f2da2), [`468f27842608f4e390cfc88bc7e6b4b0945f95ff`](468f278), [`3fd5157b309f1d3439b2d87c67b0601fb246d04c`](3fd5157), [`b734ea04d118db09cf6077fdd968c8f04a96327a`](b734ea0), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](e7e6757), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`faea2d1174d80593264f2227cfde9a2ba1a59b96`](faea2d1), [`97b9d2edfcfeed99124f9e115f992cbef3804682`](97b9d2e), [`f6af504f1ba8283fd00af0d6e3c9c1a665d62736`](f6af504), [`a595235d3cf8f67611efd8395332b64d067b5f1f`](a595235)]: - @apollo/query-graphs@2.12.0 - @apollo/federation-internals@2.12.0 ## @apollo/gateway@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - Updated dependencies \[[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](3e2b0a8), [`bb4614d338ae03bac51a5fc2439590f172c4e54d`](bb4614d), [`99f2da21de88f9ad9a32ee7ed64b2d4a92887b40`](99f2da2), [`468f27842608f4e390cfc88bc7e6b4b0945f95ff`](468f278), [`3fd5157b309f1d3439b2d87c67b0601fb246d04c`](3fd5157), [`b734ea04d118db09cf6077fdd968c8f04a96327a`](b734ea0), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](e7e6757), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`faea2d1174d80593264f2227cfde9a2ba1a59b96`](faea2d1), [`0dbc7cc72ffacf324231e9ccb2de4189f6bf3289`](0dbc7cc), [`97b9d2edfcfeed99124f9e115f992cbef3804682`](97b9d2e), [`f6af504f1ba8283fd00af0d6e3c9c1a665d62736`](f6af504), [`bc07e979b9fd24c9b94740b170f11023fe99ba1e`](bc07e97), [`a595235d3cf8f67611efd8395332b64d067b5f1f`](a595235), [`9cbdcb53f859c877a476e2725faa4cb205506f57`](9cbdcb5)]: - @apollo/query-planner@2.12.0 - @apollo/composition@2.12.0 - @apollo/federation-internals@2.12.0 ## @apollo/federation-internals@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) - Added isSuccess argument to @connect and @source ([#3294](#3294)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - Automatically propagate authorization requirements from implementing type to interface in the supergraph. ([#3321](#3321)) Authorization requirements now automatically propagate from implementing types to interfaces during composition. Direct auth specifications on interfaces are no longer allowed. Interface access requires satisfying ALL implementing types' requirements (`AND` rule), with these requirements included in the supergraph for backward compatibility with older routers. - Fix transitive auth requirements on `@requires` and `@fromcontext` ([#3321](#3321)) Adds new `postMergeValidation` check to ensure that all fields that depends on data from other parts of the supergraph through `@requires` and/or `@fromContext` directives explicitly specify matching `@authenticated`, `@requiresScopes` and/or `@policy` auth requirements, e.g. ```graphql type T @key(fields: "id") { id: ID! extra: String @external # we need explicit `@authenticated` as it is needed to access extra requiresExtra: String @requires(fields: "extra") @authenticated } type T @key(fields: "id") { id: ID! extra: String @authenticated } ``` - Preparing new preview release 2.12.0-preview.3 (patch). ([#3308](#3308)) - Adding new CompositionOption `maxValidationSubgraphPaths`. This value represents the maximum number of SubgraphPathInfo objects that may exist in a ValidationTraversal when checking for satisfiability. Setting this value can help composition error before running out of memory. Default is 1,000,000. ([#3275](#3275)) - Fixed demand control validations ([#3314](#3314)) Updated `@cost`/`@listSize` validations to use correct federation spec to look them up in the schema. - Restrict usage of auth directives on interfaces ([#3321](#3321)) Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields. GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime. - Stricter merge rules for @requiresScopes and @Policy ([#3321](#3321)) Current merge policies for `@authenticated`, `@requiresScopes` and `@policy` were inconsistent. If a shared field uses the same authorization directives across subgraphs, composition merges them using `OR` logic. However, if a shared field uses different authorization directives across subgraphs composition merges them using `AND` logic. This simplified schema evolution, but weakened security requirements. Therefore, the behavior has been changed to always apply `AND` logic to authorization directives applied to the same field across subgraphs. Since `@policy` and `@requiresScopes` values represent boolean conditions in Disjunctive Normal Form, we can merge them conjunctively to get the final auth requirements. For example: ```graphql # subgraph A type T @authenticated { # requires scopes (A1 AND A2) OR A3 secret: String @requiresScopes(scopes: [["A1", "A2"], ["A3"]]) } # subgraph B type T { # requires scopes B1 OR B2 secret: String @requiresScopes(scopes: [["B1"], ["B2"]] } # composed supergraph type T @authenticated { secret: String @requiresScopes( scopes: [ ["A1", "A2", "B1"], ["A1", "A2", "B2"], ["A3", "B1"], ["A3", "B2"] ]) } ``` This algorithm also deduplicates redundant requirements, e.g. ```graphql # subgraph A type T { # requires A1 AND A2 scopes to access secret: String @requiresScopes(scopes: [["A1", "A2"]]) } # subgraph B type T { # requires only A1 scope to access secret: String @requiresScopes(scopes: [["A1"]]) } # composed supergraph type T { # requires only A1 scope to access as A2 is redundant secret: String @requiresScopes(scopes: [["A1"]]) } ``` ## @apollo/query-graphs@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](3e2b0a8), [`bb4614d338ae03bac51a5fc2439590f172c4e54d`](bb4614d), [`99f2da21de88f9ad9a32ee7ed64b2d4a92887b40`](99f2da2), [`468f27842608f4e390cfc88bc7e6b4b0945f95ff`](468f278), [`3fd5157b309f1d3439b2d87c67b0601fb246d04c`](3fd5157), [`b734ea04d118db09cf6077fdd968c8f04a96327a`](b734ea0), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](e7e6757), [`faea2d1174d80593264f2227cfde9a2ba1a59b96`](faea2d1), [`97b9d2edfcfeed99124f9e115f992cbef3804682`](97b9d2e), [`f6af504f1ba8283fd00af0d6e3c9c1a665d62736`](f6af504), [`a595235d3cf8f67611efd8395332b64d067b5f1f`](a595235)]: - @apollo/federation-internals@2.12.0 ## @apollo/query-planner@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](3e2b0a8), [`bb4614d338ae03bac51a5fc2439590f172c4e54d`](bb4614d), [`99f2da21de88f9ad9a32ee7ed64b2d4a92887b40`](99f2da2), [`468f27842608f4e390cfc88bc7e6b4b0945f95ff`](468f278), [`3fd5157b309f1d3439b2d87c67b0601fb246d04c`](3fd5157), [`b734ea04d118db09cf6077fdd968c8f04a96327a`](b734ea0), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](e7e6757), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`faea2d1174d80593264f2227cfde9a2ba1a59b96`](faea2d1), [`97b9d2edfcfeed99124f9e115f992cbef3804682`](97b9d2e), [`f6af504f1ba8283fd00af0d6e3c9c1a665d62736`](f6af504), [`a595235d3cf8f67611efd8395332b64d067b5f1f`](a595235)]: - @apollo/query-graphs@2.12.0 - @apollo/federation-internals@2.12.0 ## @apollo/subgraph@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) - When a `GraphQLScalarType` resolver is provided to `buildSubgraphSchema()`, omitted configuration options in the `GraphQLScalarType` no longer cause the corresponding properties in the GraphQL document/AST to be cleared. To explicitly clear these properties, use `null` for the configuration option instead. ([#3287](#3287)) - Updated dependencies \[[`3e2b0a8569a9fe46726182887ed0b4bfc0b52468`](3e2b0a8), [`bb4614d338ae03bac51a5fc2439590f172c4e54d`](bb4614d), [`99f2da21de88f9ad9a32ee7ed64b2d4a92887b40`](99f2da2), [`468f27842608f4e390cfc88bc7e6b4b0945f95ff`](468f278), [`3fd5157b309f1d3439b2d87c67b0601fb246d04c`](3fd5157), [`b734ea04d118db09cf6077fdd968c8f04a96327a`](b734ea0), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`e7e67579908d5cd2fa6fe558228dffe4808cd98d`](e7e6757), [`faea2d1174d80593264f2227cfde9a2ba1a59b96`](faea2d1), [`97b9d2edfcfeed99124f9e115f992cbef3804682`](97b9d2e), [`f6af504f1ba8283fd00af0d6e3c9c1a665d62736`](f6af504), [`a595235d3cf8f67611efd8395332b64d067b5f1f`](a595235)]: - @apollo/federation-internals@2.12.0 ## apollo-federation-integration-testsuite@2.12.0 ### Minor Changes - Federation 2.12 and Connect 0.3 ([#3276](#3276)) - Add connect spec v0.2 ([#3228](#3228)) - Federation v2.12 release ([#3323](#3323)) ### Patch Changes - Preparing preview.2 release ([#3255](#3255)) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: dariuszkuc <9501705+dariuszkuc@users.noreply.github.com>
This PR was opened by the [Changesets release](https://github.com/changesets/action) GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to version-2.11, this PR will be updated. # Releases ## @apollo/composition@2.11.4 ### Patch Changes - Automatically propagate authorization requirements from implementing type to interface in the supergraph. ([#3325](#3325)) Authorization requirements now automatically propagate from implementing types to interfaces during composition. Direct auth specifications on interfaces are no longer allowed. Interface access requires satisfying ALL implementing types' requirements (`AND` rule), with these requirements included in the supergraph for backward compatibility with older routers. - Fix transitive auth requirements on `@requires` and `@fromcontext` ([#3325](#3325)) Adds new `postMergeValidation` check to ensure that all fields that depends on data from other parts of the supergraph through `@requires` and/or `@fromContext` directives explicitly specify matching `@authenticated`, `@requiresScopes` and/or `@policy` auth requirements, e.g. ```graphql type T @key(fields: "id") { id: ID! extra: String @external # we need explicit `@authenticated` as it is needed to access extra requiresExtra: String @requires(fields: "extra") @authenticated } type T @key(fields: "id") { id: ID! extra: String @authenticated } ``` - Restrict usage of auth directives on interfaces ([#3325](#3325)) Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields. GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime. - Stricter merge rules for @requiresScopes and @Policy ([#3325](#3325)) Current merge policies for `@authenticated`, `@requiresScopes` and `@policy` were inconsistent. If a shared field uses the same authorization directives across subgraphs, composition merges them using `OR` logic. However, if a shared field uses different authorization directives across subgraphs composition merges them using `AND` logic. This simplified schema evolution, but weakened security requirements. Therefore, the behavior has been changed to always apply `AND` logic to authorization directives applied to the same field across subgraphs. Since `@policy` and `@requiresScopes` values represent boolean conditions in Disjunctive Normal Form, we can merge them conjunctively to get the final auth requirements. For example: ```graphql # subgraph A type T @authenticated { # requires scopes (A1 AND A2) OR A3 secret: String @requiresScopes(scopes: [["A1", "A2"], ["A3"]]) } # subgraph B type T { # requires scopes B1 OR B2 secret: String @requiresScopes(scopes: [["B1"], ["B2"]] } # composed supergraph type T @authenticated { secret: String @requiresScopes( scopes: [ ["A1", "A2", "B1"], ["A1", "A2", "B2"], ["A3", "B1"], ["A3", "B2"] ]) } ``` This algorithm also deduplicates redundant requirements, e.g. ```graphql # subgraph A type T { # requires A1 AND A2 scopes to access secret: String @requiresScopes(scopes: [["A1", "A2"]]) } # subgraph B type T { # requires only A1 scope to access secret: String @requiresScopes(scopes: [["A1"]]) } # composed supergraph type T { # requires only A1 scope to access as A2 is redundant secret: String @requiresScopes(scopes: [["A1"]]) } ``` - Updated dependencies \[[`d221ac04c3ee00a3c7a671d9d56e2cfa36943b49`](d221ac0), [`7730c03e128be6754b9e40c086d5cb5c4685ac66`](7730c03), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`6adbf7e86927de969aedab665b6a3a8dbf3a6095`](6adbf7e), [`2a20dc38dfc40e0b618d5cc826f18a19ddb91aff`](2a20dc3)]: - @apollo/federation-internals@2.11.4 - @apollo/query-graphs@2.11.4 ## @apollo/gateway@2.11.4 ### Patch Changes - Updated dependencies \[[`d221ac04c3ee00a3c7a671d9d56e2cfa36943b49`](d221ac0), [`7730c03e128be6754b9e40c086d5cb5c4685ac66`](7730c03), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`6adbf7e86927de969aedab665b6a3a8dbf3a6095`](6adbf7e), [`2a20dc38dfc40e0b618d5cc826f18a19ddb91aff`](2a20dc3)]: - @apollo/composition@2.11.4 - @apollo/federation-internals@2.11.4 - @apollo/query-planner@2.11.4 ## @apollo/federation-internals@2.11.4 ### Patch Changes - Automatically propagate authorization requirements from implementing type to interface in the supergraph. ([#3325](#3325)) Authorization requirements now automatically propagate from implementing types to interfaces during composition. Direct auth specifications on interfaces are no longer allowed. Interface access requires satisfying ALL implementing types' requirements (`AND` rule), with these requirements included in the supergraph for backward compatibility with older routers. - Fix transitive auth requirements on `@requires` and `@fromcontext` ([#3325](#3325)) Adds new `postMergeValidation` check to ensure that all fields that depends on data from other parts of the supergraph through `@requires` and/or `@fromContext` directives explicitly specify matching `@authenticated`, `@requiresScopes` and/or `@policy` auth requirements, e.g. ```graphql type T @key(fields: "id") { id: ID! extra: String @external # we need explicit `@authenticated` as it is needed to access extra requiresExtra: String @requires(fields: "extra") @authenticated } type T @key(fields: "id") { id: ID! extra: String @authenticated } ``` - Fixed demand control validations ([#3314](#3314)) Updated `@cost`/`@listSize` validations to use correct federation spec to look them up in the schema. - Restrict usage of auth directives on interfaces ([#3325](#3325)) Restricts usage of `@authenticated`, `@policy` and `@requiresScopes` from being applied on interfaces, interface objects and their fields. GraphQL spec currently does not define any interface inheritance rules and developers have to explicitly redefine all interface fields on their implementations. At runtime, GraphQL servers cannot return abstract types and always return concrete output types. Due to the above, applying auth directives on the interfaces may lead to unexpected runtime behavior as they won't have any effect at runtime. - Stricter merge rules for @requiresScopes and @Policy ([#3325](#3325)) Current merge policies for `@authenticated`, `@requiresScopes` and `@policy` were inconsistent. If a shared field uses the same authorization directives across subgraphs, composition merges them using `OR` logic. However, if a shared field uses different authorization directives across subgraphs composition merges them using `AND` logic. This simplified schema evolution, but weakened security requirements. Therefore, the behavior has been changed to always apply `AND` logic to authorization directives applied to the same field across subgraphs. Since `@policy` and `@requiresScopes` values represent boolean conditions in Disjunctive Normal Form, we can merge them conjunctively to get the final auth requirements. For example: ```graphql # subgraph A type T @authenticated { # requires scopes (A1 AND A2) OR A3 secret: String @requiresScopes(scopes: [["A1", "A2"], ["A3"]]) } # subgraph B type T { # requires scopes B1 OR B2 secret: String @requiresScopes(scopes: [["B1"], ["B2"]] } # composed supergraph type T @authenticated { secret: String @requiresScopes( scopes: [ ["A1", "A2", "B1"], ["A1", "A2", "B2"], ["A3", "B1"], ["A3", "B2"] ]) } ``` This algorithm also deduplicates redundant requirements, e.g. ```graphql # subgraph A type T { # requires A1 AND A2 scopes to access secret: String @requiresScopes(scopes: [["A1", "A2"]]) } # subgraph B type T { # requires only A1 scope to access secret: String @requiresScopes(scopes: [["A1"]]) } # composed supergraph type T { # requires only A1 scope to access as A2 is redundant secret: String @requiresScopes(scopes: [["A1"]]) } ``` ## @apollo/query-graphs@2.11.4 ### Patch Changes - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`d221ac04c3ee00a3c7a671d9d56e2cfa36943b49`](d221ac0), [`7730c03e128be6754b9e40c086d5cb5c4685ac66`](7730c03), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`6adbf7e86927de969aedab665b6a3a8dbf3a6095`](6adbf7e), [`2a20dc38dfc40e0b618d5cc826f18a19ddb91aff`](2a20dc3)]: - @apollo/federation-internals@2.11.4 ## @apollo/query-planner@2.11.4 ### Patch Changes - Fixes a bug where query planning may unexpectedly error due to attempting to generate a plan where a `@shareable` mutation field is called more than once across multiple subgraphs. ([#3304](#3304)) ([#3304](#3304)) - Updated dependencies \[[`d221ac04c3ee00a3c7a671d9d56e2cfa36943b49`](d221ac0), [`7730c03e128be6754b9e40c086d5cb5c4685ac66`](7730c03), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`f3ab499eaf62b1a1c0f08b838d2cbde5accb303a`](f3ab499), [`6adbf7e86927de969aedab665b6a3a8dbf3a6095`](6adbf7e), [`2a20dc38dfc40e0b618d5cc826f18a19ddb91aff`](2a20dc3)]: - @apollo/federation-internals@2.11.4 - @apollo/query-graphs@2.11.4 ## @apollo/subgraph@2.11.4 ### Patch Changes - Updated dependencies \[[`d221ac04c3ee00a3c7a671d9d56e2cfa36943b49`](d221ac0), [`7730c03e128be6754b9e40c086d5cb5c4685ac66`](7730c03), [`4bda3a498eba36e187dfd9ae673eca12d3f3502c`](4bda3a4), [`6adbf7e86927de969aedab665b6a3a8dbf3a6095`](6adbf7e), [`2a20dc38dfc40e0b618d5cc826f18a19ddb91aff`](2a20dc3)]: - @apollo/federation-internals@2.11.4 ## apollo-federation-integration-testsuite@2.11.4 Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
This PR fixes a bug where query planning may unexpectedly error while planning an operation with a satisfiable
@shareablemutation field.Specifically, this PR:
@keyedges at top-level (previously only root type resolution edges were ignored).This PR was originally filed as part of #3303, but was split off so it could be merged faster in the next patch release.