Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,33 @@ Type is `boolean` and default is `false`.

### `require_id`

If `true`, requests must contain a resolvable persisted document ID. If Router cannot extract an
ID, it returns `PERSISTED_DOCUMENT_ID_REQUIRED`. Type is `boolean` and default is `false`.
Controls whether requests must contain a resolvable persisted document ID. If a request lacks an
ID and `require_id` is enforced, Router returns `PERSISTED_DOCUMENT_ID_REQUIRED`.

Accepts a static boolean (`true` or `false`, default is `false`) or an **expression** that is
evaluated per-request. The expression can reference:

| Variable | Description |
| ------------------ | ------------------------------------ |
| `.request.headers` | HTTP headers of the incoming request |
| `.request.method` | HTTP method (`GET`, `POST`, etc.) |
| `.request.url` | Full request URL |
| `env("VAR")` | Environment variable at request time |

When the expression returns `true`, the document ID requirement is enforced, but when `false` it is
skipped for that request.

```yaml
persisted_documents:
require_id:
expression: |
is_null(env("BYPASS_SECRET"))
|| .request.headers."x-bypass-require-id" != env("BYPASS_SECRET")
```

You can also bypass the requirement on a per-request basis at runtime by setting
`"hive::persisted_documents::skip_enforcement": true` in the request context - see
[Persisted Documents security guide](/docs/router/security/persisted-documents#per-request-bypass).

### `log_missing_id`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,12 @@ The `include.context` property supports three forms:
| `hive::telemetry::client_name` | ✅ | The name of the client application |
| `hive::telemetry::client_version` | ✅ | The version of the client application |

### Persisted Documents

| Property | Mutable | Description |
| --------------------------------------------- | :-----: | --------------------------------------------------------------------------------- |
| `hive::persisted_documents::skip_enforcement` | ✅ | Skip the `require_id` check for this request. Set to `true` to bypass enforcement |

## Body

- Some stages allow body mutation, but `graphql.analysis` does not.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,35 @@ With `require_id: false` (default), regular GraphQL requests (with `query`) are
With `require_id: true`, incoming requests must provide a persisted document ID.
During migration, `log_missing_id: true` helps you find requests that still arrive without an ID.

### Conditional enforcement with expressions

In addition to a static boolean, `require_id` accepts an **expression** evaluated per-request.
The expression can inspect the request headers, method, URL, and environment variables.
When it returns `true`, the ID is required, otherwise it is not.

```yaml
persisted_documents:
require_id:
expression: |
is_null(env("BYPASS_SECRET"))
|| .request.headers."x-bypass-require-id" != env("BYPASS_SECRET")
```

### Per-request bypass

If you need to skip the `require_id` check on individual requests (for example during a gradual
migration or for trusted internal clients), set the `hive::persisted_documents::skip_enforcement`
flag to `true` in the request context.

The flag is writable from:

- `OnHttpRequest` plugin hook
- `OnGraphqlParams` plugin hook
- `router.request` coprocessor stage

When `skip_enforcement` is `true`, requests with a full operation string pass through even when
`persisted_documents.require_id` is enabled.

## Path selector and GraphQL endpoint compatibility

If you use `url_path_param`, do not use root GraphQL endpoint (`http.graphql_endpoint: "/"`).
Expand Down
Loading