Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions docs/router/authentication-and-authorization.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ In the current router version, the configuration and behavior of authentication
- url: https://example.com/.well-known/jwks.json
refresh_interval: 1m
algorithms: ["RS256"]
refresh_unknown_kid:
enabled: true
max_wait: 2m
interval: 30s
burst: 5
- url: https://example2.com/.well-known/jwks.json
refresh_interval: 2m
# optional list of allowed algorithms per JWKS
Expand Down Expand Up @@ -89,3 +94,35 @@ Authentication information is also available to custom modules. See [Access Auth
### Forwarding authentication headers

By default, the router won't forward authentication headers to subgraphs, but if desired this can be configured using [Proxy capabilities](/router/proxy-capabilities).


### Refreshing Unknown KIDs on Demand

When `refresh_unknown_kid.enabled` is set to `true`, the router will automatically attempt to refresh JWKs whenever it encounters a valid token with an unknown KID (Key ID). This is useful when JWKs rotation has occurred but the router hasn't picked up the new keys in its regular refresh cycle.

To prevent overwhelming the JWKS endpoint, this feature includes rate limiting controlled by the following parameters:
- `burst`: Maximum number of concurrent refresh attempts allowed
- `interval`: Time that must pass between consecutive refresh attempts
- `max_wait`: Maximum time a request is allowed to wait

#### Rate Limiting Example

Let's examine how rate limiting works with these settings:
```yaml
refresh_unknown_kid:
enabled: true
burst: 1
interval: 30s
max_wait: 110s
```

If we send 6 simultaneous requests with unknown KIDs:
1. First request: Processed immediately
2. Second request: Blocked for 30s (interval × 1)
3. Third request: Blocked for 60s (interval × 2)
4. Fourth request: Blocked for 90s (interval × 3)
5. Fifth request: Returns error immediately (would require 120s wait > max_wait)
6. Sixth request: Returns error immediately (would require 150s wait > max_wait)
Comment thread
Noroth marked this conversation as resolved.
Outdated

The `max_wait` setting prevents excessive wait times. In this example, since the 5th and 6th requests would require waiting longer than the configured `max_wait` of 110s, they immediately return with an unauthorized status instead of attempting to refresh.

14 changes: 14 additions & 0 deletions docs/router/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,10 @@ This is useful when you want to connect to a JWKS endpoint
| url | <Icon icon="square-check" iconType="solid" /> | The URL of the JWKs. The JWKs are used to verify the JWT (JSON Web Token). The URL is specified as a string with the format 'scheme://host:port'. | |
| refresh_interval | <Icon icon="square" /> | The interval at which the JWKs are refreshed. The period is specified as a string with a number and a unit, e.g. 10ms, 1s, 1m, 1h. The supported units are 'ms', 's', 'm', 'h'. | 1m |
| algorithms | <Icon icon="square" /> | The allowed algorithms for the keys that are retrieved from the JWKs. An empty list means that all algorithms are allowed. The following algorithms are supported "RS256", "RS384", "RS512", "ES256", "ES384", "ES512", "PS256", "PS384", "PS512", "EdDSA" | [] (all allowed) |
| refresh_unknown_kid.enabled | <Icon icon="square" /> | Enable automatic refreshing of JWKs when encountering a valid token with an unknown KID. When enabled, the router will attempt to fetch updated JWKs hoping the matching KID has been added. | false |
| refresh_unknown_kid.max_wait | <Icon icon="square" /> | Maximum wait time allowed for rate-limited requests. If the computed wait duration would exceed this value, the request returns immediately with an unauthorized status instead of waiting. This prevents excessive wait times for subsequent requests. | 2m |
| refresh_unknown_kid.interval | <Icon icon="square" /> | Time interval that must pass between consecutive JWKs refresh attempts. With burst=1, each subsequent request within the interval must wait for (interval × attempt number) duration. | 30s |
| refresh_unknown_kid.burst | <Icon icon="square" /> | Maximum number of concurrent refresh attempts allowed. This helps prevent overloading the JWKS endpoint. When exceeded, subsequent requests are queued and subject to rate limiting based on the interval. | 2 |

#### Secret
This is useful when you have a symmetric key that you cannot expose through a JWKS endpoint, you can use the secret based configuration
Expand Down Expand Up @@ -1472,10 +1476,20 @@ authentication:
- url: "https://example.com/.well-known/jwks.json"
refresh_interval: 1m
# Leaving algorithms empty will allow all supported algorithms from the config docs
refresh_unknown_kid:
enabled: true
max_wait: 2m
interval: 30s
burst: 2
- url: "https://example2.com/.well-known/jwks.json"
refresh_interval: 2m
# optional list of allowed algorithms per JWKS
algorithms: ["RS256", "EdDSA", "HS512"]
refresh_unknown_kid:
enabled: false # These are defaults
max_wait: 2m
interval: 30s
burst: 2
header_name: Authorization # This is the default value
header_value_prefix: Bearer # This is the default value
header_sources:
Expand Down