diff --git a/.changeset/authz-directives.md b/.changeset/authz-directives.md deleted file mode 100644 index 3885996f..00000000 --- a/.changeset/authz-directives.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -router: minor -executor: minor -query-planner: minor ---- - -## Directive-Based Authorization - -Introducing directive-based authorization. This allows you to enforce fine-grained access control directly from your subgraph schemas using the `@authenticated` and `@requiresScopes` directives. - -This new authorization layer runs before the query planner, ensuring that unauthorized requests are handled efficiently without reaching your subgraphs. - -### Configuration - -You can configure how the router handles unauthorized requests with two modes: - -- **`filter`** (default): Silently removes any fields the user is not authorized to see from the query. The response will contain `null` for the removed fields and an error in the `errors` array. -- **`reject`**: Rejects the entire GraphQL operation if it requests any field the user is not authorized to access. - -To configure this, add the following to your `router.yaml` configuration file: - -```yaml -authentication: - directives: - unauthorized: - # "filter" (default): Removes unauthorized fields from the query and returns errors. - # "reject": Rejects the entire request if any unauthorized field is requested. - mode: reject -``` - -If this section is omitted, the router will use `filter` mode by default. - -### JWT Scope Requirements - -When using the `@requiresScopes` directive, the router expects the user's granted scopes to be present in the JWT payload. The scopes should be in an array of strings or a string (scopes separated by space), within a claim named `scope`. - -Here is an example of a JWT payload with the correct format: - -```json -{ - "sub": "user-123", - "scope": [ - "read:products", - "write:reviews" - ], - "iat": 1516239022 -} -``` diff --git a/.changeset/shared_utilities_to_handle_vrl_expressions.md b/.changeset/shared_utilities_to_handle_vrl_expressions.md deleted file mode 100644 index 1dce263f..00000000 --- a/.changeset/shared_utilities_to_handle_vrl_expressions.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -router: minor -config: minor -executor: minor ---- - -# Breaking - -Removed `pool_idle_timeout_seconds` from `traffic_shaping`, instead use `pool_idle_timeout` with duration format. - -```diff -traffic_shaping: -- pool_idle_timeout_seconds: 30 -+ pool_idle_timeout: 30s -``` - -#540 by @ardatan diff --git a/Cargo.lock b/Cargo.lock index 7ebd64ed..82084cdf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2011,7 +2011,7 @@ dependencies = [ [[package]] name = "hive-router" -version = "0.0.19" +version = "0.0.20" dependencies = [ "ahash", "arc-swap", @@ -2057,7 +2057,7 @@ dependencies = [ [[package]] name = "hive-router-config" -version = "0.0.11" +version = "0.0.12" dependencies = [ "config", "envconfig", @@ -2074,7 +2074,7 @@ dependencies = [ [[package]] name = "hive-router-plan-executor" -version = "6.0.1" +version = "6.1.0" dependencies = [ "ahash", "async-trait", @@ -2113,7 +2113,7 @@ dependencies = [ [[package]] name = "hive-router-query-planner" -version = "2.0.2" +version = "2.1.0" dependencies = [ "bitflags 2.10.0", "criterion", diff --git a/bin/router/CHANGELOG.md b/bin/router/CHANGELOG.md index fbb97c68..fe305654 100644 --- a/bin/router/CHANGELOG.md +++ b/bin/router/CHANGELOG.md @@ -116,6 +116,67 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other - *(deps)* update release-plz/action action to v0.5.113 ([#389](https://github.com/graphql-hive/router/pull/389)) +## 0.0.20 (2025-11-21) + +### Features + +- support authenticated and requiresScopes directives (#538) + +#### Directive-Based Authorization + +Introducing directive-based authorization. This allows you to enforce fine-grained access control directly from your subgraph schemas using the `@authenticated` and `@requiresScopes` directives. + +This new authorization layer runs before the query planner, ensuring that unauthorized requests are handled efficiently without reaching your subgraphs. + +#### Configuration + +You can configure how the router handles unauthorized requests with two modes: + +- **`filter`** (default): Silently removes any fields the user is not authorized to see from the query. The response will contain `null` for the removed fields and an error in the `errors` array. +- **`reject`**: Rejects the entire GraphQL operation if it requests any field the user is not authorized to access. + +To configure this, add the following to your `router.yaml` configuration file: + +```yaml +authentication: + directives: + unauthorized: + # "filter" (default): Removes unauthorized fields from the query and returns errors. + # "reject": Rejects the entire request if any unauthorized field is requested. + mode: reject +``` + +If this section is omitted, the router will use `filter` mode by default. + +#### JWT Scope Requirements + +When using the `@requiresScopes` directive, the router expects the user's granted scopes to be present in the JWT payload. The scopes should be in an array of strings or a string (scopes separated by space), within a claim named `scope`. + +Here is an example of a JWT payload with the correct format: + +```json +{ + "sub": "user-123", + "scope": [ + "read:products", + "write:reviews" + ], + "iat": 1516239022 +} +``` + +#### Breaking + +Removed `pool_idle_timeout_seconds` from `traffic_shaping`, instead use `pool_idle_timeout` with duration format. + +```diff +traffic_shaping: +- pool_idle_timeout_seconds: 30 ++ pool_idle_timeout: 30s +``` + +##540 by @ardatan + ## 0.0.19 (2025-11-19) ### Features diff --git a/bin/router/Cargo.toml b/bin/router/Cargo.toml index 69b405f2..5df1637d 100644 --- a/bin/router/Cargo.toml +++ b/bin/router/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hive-router" -version = "0.0.19" +version = "0.0.20" edition = "2021" description = "GraphQL router/gateway for Federation" license = "MIT" @@ -16,9 +16,9 @@ name = "hive_router" path = "src/main.rs" [dependencies] -hive-router-query-planner = { path = "../../lib/query-planner", version = "2.0.2" } -hive-router-plan-executor = { path = "../../lib/executor", version = "6.0.1" } -hive-router-config = { path = "../../lib/router-config", version = "0.0.11" } +hive-router-query-planner = { path = "../../lib/query-planner", version = "2.1.0" } +hive-router-plan-executor = { path = "../../lib/executor", version = "6.1.0" } +hive-router-config = { path = "../../lib/router-config", version = "0.0.12" } tokio = { workspace = true } futures = { workspace = true } diff --git a/lib/executor/CHANGELOG.md b/lib/executor/CHANGELOG.md index 60f2ec28..5f9ee945 100644 --- a/lib/executor/CHANGELOG.md +++ b/lib/executor/CHANGELOG.md @@ -94,6 +94,65 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other - *(deps)* update release-plz/action action to v0.5.113 ([#389](https://github.com/graphql-hive/router/pull/389)) +## 6.1.0 (2025-11-21) + +### Features + +#### Directive-Based Authorization + +Introducing directive-based authorization. This allows you to enforce fine-grained access control directly from your subgraph schemas using the `@authenticated` and `@requiresScopes` directives. + +This new authorization layer runs before the query planner, ensuring that unauthorized requests are handled efficiently without reaching your subgraphs. + +#### Configuration + +You can configure how the router handles unauthorized requests with two modes: + +- **`filter`** (default): Silently removes any fields the user is not authorized to see from the query. The response will contain `null` for the removed fields and an error in the `errors` array. +- **`reject`**: Rejects the entire GraphQL operation if it requests any field the user is not authorized to access. + +To configure this, add the following to your `router.yaml` configuration file: + +```yaml +authentication: + directives: + unauthorized: + # "filter" (default): Removes unauthorized fields from the query and returns errors. + # "reject": Rejects the entire request if any unauthorized field is requested. + mode: reject +``` + +If this section is omitted, the router will use `filter` mode by default. + +#### JWT Scope Requirements + +When using the `@requiresScopes` directive, the router expects the user's granted scopes to be present in the JWT payload. The scopes should be in an array of strings or a string (scopes separated by space), within a claim named `scope`. + +Here is an example of a JWT payload with the correct format: + +```json +{ + "sub": "user-123", + "scope": [ + "read:products", + "write:reviews" + ], + "iat": 1516239022 +} +``` + +#### Breaking + +Removed `pool_idle_timeout_seconds` from `traffic_shaping`, instead use `pool_idle_timeout` with duration format. + +```diff +traffic_shaping: +- pool_idle_timeout_seconds: 30 ++ pool_idle_timeout: 30s +``` + +##540 by @ardatan + ## 6.0.1 (2025-11-04) ### Fixes diff --git a/lib/executor/Cargo.toml b/lib/executor/Cargo.toml index 7d565252..d23c20ae 100644 --- a/lib/executor/Cargo.toml +++ b/lib/executor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hive-router-plan-executor" -version = "6.0.1" +version = "6.1.0" edition = "2021" description = "GraphQL query planner executor for Federation specification" license = "MIT" @@ -12,8 +12,8 @@ authors = ["The Guild"] [lib] [dependencies] -hive-router-query-planner = { path = "../query-planner", version = "2.0.2" } -hive-router-config = { path = "../router-config", version = "0.0.11" } +hive-router-query-planner = { path = "../query-planner", version = "2.1.0" } +hive-router-config = { path = "../router-config", version = "0.0.12" } graphql-parser = { workspace = true } graphql-tools = { workspace = true } diff --git a/lib/query-planner/CHANGELOG.md b/lib/query-planner/CHANGELOG.md index 83cfa040..4c2dae3f 100644 --- a/lib/query-planner/CHANGELOG.md +++ b/lib/query-planner/CHANGELOG.md @@ -30,3 +30,49 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other - *(deps)* update release-plz/action action to v0.5.113 ([#389](https://github.com/graphql-hive/router/pull/389)) +## 2.1.0 (2025-11-21) + +### Features + +#### Directive-Based Authorization + +Introducing directive-based authorization. This allows you to enforce fine-grained access control directly from your subgraph schemas using the `@authenticated` and `@requiresScopes` directives. + +This new authorization layer runs before the query planner, ensuring that unauthorized requests are handled efficiently without reaching your subgraphs. + +#### Configuration + +You can configure how the router handles unauthorized requests with two modes: + +- **`filter`** (default): Silently removes any fields the user is not authorized to see from the query. The response will contain `null` for the removed fields and an error in the `errors` array. +- **`reject`**: Rejects the entire GraphQL operation if it requests any field the user is not authorized to access. + +To configure this, add the following to your `router.yaml` configuration file: + +```yaml +authentication: + directives: + unauthorized: + # "filter" (default): Removes unauthorized fields from the query and returns errors. + # "reject": Rejects the entire request if any unauthorized field is requested. + mode: reject +``` + +If this section is omitted, the router will use `filter` mode by default. + +#### JWT Scope Requirements + +When using the `@requiresScopes` directive, the router expects the user's granted scopes to be present in the JWT payload. The scopes should be in an array of strings or a string (scopes separated by space), within a claim named `scope`. + +Here is an example of a JWT payload with the correct format: + +```json +{ + "sub": "user-123", + "scope": [ + "read:products", + "write:reviews" + ], + "iat": 1516239022 +} +``` diff --git a/lib/query-planner/Cargo.toml b/lib/query-planner/Cargo.toml index 361e60a8..6e6a1cc1 100644 --- a/lib/query-planner/Cargo.toml +++ b/lib/query-planner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hive-router-query-planner" -version = "2.0.2" +version = "2.1.0" edition = "2021" description = "GraphQL query planner for Federation specification" license = "MIT" diff --git a/lib/router-config/CHANGELOG.md b/lib/router-config/CHANGELOG.md index aef30831..e30f2bea 100644 --- a/lib/router-config/CHANGELOG.md +++ b/lib/router-config/CHANGELOG.md @@ -66,6 +66,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - *(hive-router)* fix docker image issues ([#394](https://github.com/graphql-hive/router/pull/394)) +## 0.0.12 (2025-11-21) + +### Features + +#### Breaking + +Removed `pool_idle_timeout_seconds` from `traffic_shaping`, instead use `pool_idle_timeout` with duration format. + +```diff +traffic_shaping: +- pool_idle_timeout_seconds: 30 ++ pool_idle_timeout: 30s +``` + +##540 by @ardatan + ## 0.0.11 (2025-11-04) ### Fixes diff --git a/lib/router-config/Cargo.toml b/lib/router-config/Cargo.toml index 8fc44807..06c2f064 100644 --- a/lib/router-config/Cargo.toml +++ b/lib/router-config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hive-router-config" -version = "0.0.11" +version = "0.0.12" edition = "2021" publish = true license = "MIT"