Skip to content
Open
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 @@ -53,6 +53,14 @@ headers:
- op: "propagate"
named: "Subgraph-Secret"
default: "some-secret"

groups: # Apply rules to a cohort of subgraphs (list, regex, or both)
- id: "products-cohort"
subgraphs: [products]
matching: "^products-feature-.+$"
request:
- op: "propagate"
named: "X-Products-Auth"
```

### What does the snippet do?
Expand All @@ -61,6 +69,71 @@ With `all` we address all subgraph requests. Next, we can define several rules o

The `subgraphs` section allows to propagate headers for specific subgraphs. The name must match with the subgraph name in the Studio.

The `groups` section applies a bundle of rules to every subgraph that matches the group's selector. A group can list subgraphs explicitly (`subgraphs:`), match by regex (`matching:`), or both. This is useful for applying the same rules to a base subgraph and its feature variants without duplicating the same block under every entry.

### Rule evaluation order

For each subgraph the router builds a header set in this order:

1. `headers.all` rules.
2. `headers.groups` entries whose selector matches the subgraph (in config order).
3. `headers.subgraphs.<name>` rules for the exact subgraph name.

Exact-name rules apply last, so a `headers.subgraphs.products` rule can still override a broader group rule when both target the same header.

### Subgraph header groups

Each entry under `groups` accepts:

* `id` — A unique identifier for the group. Required. Used in router error messages.
* `subgraphs` — Explicit list of subgraph names this group applies to. Names are case-sensitive identifiers.
* `matching` — A Go regular expression evaluated against the subgraph name.
* `negate_match` — If `true`, the regex result is inverted. Subgraphs in the explicit `subgraphs` list are still included positively; `negate_match` only affects the regex.
* `request` — Request rules to apply when the group matches.
* `response` — Response rules to apply when the group matches.

At least one of `subgraphs` or `matching` must be specified, and at least one of `request` or `response` must be specified. Invalid configurations fail router startup.

A group with both `subgraphs` and `matching` matches a subgraph if it appears in either (the union — list-match OR regex-match). The group's rules apply at most once per subgraph regardless of how many parts of the selector match.

### Conflict resolution

When more than one rule targets the same header name for the same subgraph, the router applies rules in a strict deterministic order and the **last writer wins**. There is no warning, no error, and no validator that detects overlapping rules.

The full ordering across layers:

1. `headers.all` rules (in declared order).
2. `headers.groups` entries whose selector matches the subgraph, in **config order**. Within each group, rules apply in declared order.
3. `headers.subgraphs.<name>` rules (in declared order).

Concretely, **within the groups layer, group order in the YAML is the tiebreaker** — entries are merged first-to-last, and a later group's rule overrides an earlier group's rule for the same header name. The `headers.subgraphs.<name>` layer always runs last and overrides every group rule for that exact subgraph.

There is one subtle asymmetry between operations: an `op: propagate` rule with no client-supplied value and no `default:` is a no-op and does **not** clear an earlier value. An `op: set` rule, and an `op: propagate` rule with a `default:` set, always write a value.

```yaml
# Example: two groups targeting X-Foo on the same subgraph
headers:
groups:
- id: first
subgraphs: [products]
request:
- op: set
name: X-Foo
value: from-first
- id: second # second group runs after first
subgraphs: [products]
request:
- op: set
name: X-Foo
value: from-second # → wins; X-Foo == "from-second"
subgraphs:
products:
request:
- op: set
name: X-Foo
value: from-exact # → wins overall; exact runs last
```

### Supported header rules

Currently, we support the following header rules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,15 @@ headers:
named: "X-User-Id"
default: "456" # Set the value when the header was not set
algorithm: "last_write"

groups: # Apply rules to a cohort of subgraphs (list, regex, or both)
- id: "products-cohort"
subgraphs: [products]
matching: "^products-feature-.+$"
response:
- op: "propagate"
named: "X-Products-Trace"
algorithm: "last_write"
```

### What does the snippet do?
Expand All @@ -72,6 +81,8 @@ With `all` we address all subgraph requests. Next, we can define several rules o

The `subgraphs` section allows to propagate headers for specific subgraphs. The name must match with the subgraph name in the Studio.

The `groups` section applies a bundle of rules to every subgraph that matches the group's selector. A group can list subgraphs explicitly (`subgraphs:`), match by regex (`matching:`), or both. Groups apply after `all` and before exact `subgraphs` rules, so an exact subgraph rule can still override a group rule. See [Subgraph Request Headers Operations](/router/proxy-capabilities/subgraph-request-header-operations#subgraph-header-groups) for the full set of group fields and validation rules.

### Supported header rules

Currently, we support the following header rules:
Expand Down
Loading
Loading