Docs
Launch GraphOS Studio

Enforcing operation limits in the Apollo Router

With GraphOS Enterprise


⚠️ This is an Enterprise feature of the Apollo Router. It requires an organization with a GraphOS Enterprise plan. It is currently in preview.

If your organization doesn't currently have an Enterprise plan, you can test out this functionality by signing up for a free Enterprise trial.

You can define operation limits in your router's configuration to reject potentially malicious requests. An operation that exceeds any specified limit is rejected (unless you run your router in warn_only mode).

Setup

To use operation limits, you must run v1.17 or later of the Apollo Router. Download the latest version.

You define operation limits in your router's YAML config file, like so:

router.yaml
preview_operation_limits:
max_depth: 100
max_height: 200
max_aliases: 30
max_root_fields: 20
# Uncomment to enable warn_only mode
# warn_only: true

Each limit takes an integer value. You can define any combination of supported limits.

Supported limits

max_depth

Limits the deepest nesting of selection sets in an operation, including fields in fragments.

The GetBook operation below has depth three:

query GetBook {
book { # Depth 1 (root field)
...bookDetails
}
}
fragment bookDetails on Book {
details { # Depth 2 (nested under `book`)
... on ProductDetailsBook {
country # Depth 3 (nested under `details`)
}
}
}

max_height

Limits the number of unique fields included in an operation, including fields of fragments. If a particular field is included multiple times via aliases, it's counted only once.

The GetUser operation below has height three:

query GetUser {
user { # 1
id # 2
name # 3
username: name # Aliased duplicate (not counted)
}
}

Each unique field increments an operation's height by one, regardless of that field's return type (scalar, object, or list).

max_aliases

Limits the total number of aliased fields in an operation, including fields of fragments.

The GetUser operation below includes three aliases:

query GetUser {
user {
nickname: name # 1
username: name # 2
handle: name # 3
}
}

Each aliased field increments the alias count by one, regardless of that field's return type (scalar, object, or list).

max_root_fields

Limits the number of root fields in an operation, including root fields in fragments. If a particular root field is included multiple times via aliases, each usage is counted.

The following operation includes three root fields:

query GetTopProducts {
topBooks { # 1
id
}
topMovies { # 2
id
}
topGames { # 3
id
}
}

warn_only mode

If you run your router in warn_only mode, operations that exceed defined limits are not rejected. Instead, the router processes these operations as usual and emits a WARN trace that notes all exceeded limits, like so:

2023-03-15T19:08:23.123456Z WARN apollo_router::operation_limits: max_depth exceeded, max_depth: 3, current_op_depth: 5, operation: "query GetOwnerLocation {cat {owner {location {postalCode}}}}"

Running in warn_only mode can be useful while you're testing to determine the most appropriate limits to set for your supergraph.

You can enable or disable warn_only mode in your router's YAML config file, like so:

router.yaml
preview_operation_limits:
warn_only: true # warn_only mode always enabled
Previous
JWT Authentication
Next
Privacy and data collection
Edit on GitHubEditForumsDiscord