Skip to content

Commit 416f618

Browse files
committed
docs(rfc): simplify interceptor mutation phase
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
1 parent ff69d71 commit 416f618

1 file changed

Lines changed: 29 additions & 38 deletions

File tree

rfc/0010-gateway-interceptors/README.md

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ The design keeps two boundaries intact:
101101

102102
A gateway interceptor runs during a gateway API operation, such as creating a
103103
sandbox, importing provider profiles, updating policy, or applying sandbox
104-
configuration. It may modify an RPC request or operation input only in
105-
modification phases. It may reject in validation phases. It may attach warnings
106-
and audit annotations in all phases.
104+
configuration. It may modify a gateway-prepared operation only in
105+
`modify_operation`. It may reject in `modify_operation` or `validate`. It may
106+
attach warnings and audit annotations in all phases.
107107

108108
Gateway interceptor services expose one or more bindings. A binding is a
109109
service-declared rule that maps the service to phases, gateway RPC methods, and
@@ -140,11 +140,14 @@ gateway interceptor authors and operators do not need per-RPC phase rules.
140140

141141
| Phase | Modification allowed | Purpose | Examples |
142142
|---|---:|---|---|
143-
| `pre_request` | yes | Normalize or reject the RPC request after auth and basic size limits. | Normalize labels, require a sandbox name prefix, or reject requests with unsupported request fields. |
144-
| `modify_operation` | yes | Apply defaults or controlled changes after the gateway prepares the operation input. | Stamp a default sandbox policy, select a provider profile, or clamp resource limits to deployment defaults. |
143+
| `modify_operation` | yes | Apply deployment defaults or controlled changes after the gateway prepares the operation input. | Normalize labels, stamp a default sandbox policy, select a provider profile, or clamp resource limits to deployment defaults. |
145144
| `validate` | no | Enforce deployment-specific rules before persistence, provisioning, or other side effects. | Enforce tenant quotas, reject policy updates that allow internet egress, or verify driver config against an approved schema. |
146145
| `post_commit` | no | Emit audit or notify external systems after successful persistence or provisioning. | Send audit records, notify an inventory system, or trigger a reconciliation job after a successful write. |
147146

147+
The gateway rejects malformed raw API requests before gateway interceptor
148+
execution. Gateway interceptors operate on valid gateway operations, not
149+
low-level request decoding or shape repair.
150+
148151
Gateway invariants run after modification so gateway interceptors cannot leave
149152
invalid objects in the system. Operation-specific built-in validation, including
150153
driver validation where applicable, remains part of the gateway-owned execution
@@ -166,10 +169,9 @@ message DescribeRequest {}
166169
167170
enum GatewayInterceptorPhase {
168171
GATEWAY_INTERCEPTOR_PHASE_UNSPECIFIED = 0;
169-
GATEWAY_INTERCEPTOR_PHASE_PRE_REQUEST = 1;
170-
GATEWAY_INTERCEPTOR_PHASE_MODIFY_OPERATION = 2;
171-
GATEWAY_INTERCEPTOR_PHASE_VALIDATE = 3;
172-
GATEWAY_INTERCEPTOR_PHASE_POST_COMMIT = 4;
172+
GATEWAY_INTERCEPTOR_PHASE_MODIFY_OPERATION = 1;
173+
GATEWAY_INTERCEPTOR_PHASE_VALIDATE = 2;
174+
GATEWAY_INTERCEPTOR_PHASE_POST_COMMIT = 3;
173175
}
174176
```
175177

@@ -193,22 +195,15 @@ message InterceptorEvaluation {
193195
map<string, string> context = 6;
194196
195197
oneof phase {
196-
// Evaluation before the gateway prepares operation-specific input.
197-
PreRequestEvaluation pre_request = 7;
198198
// Evaluation that may modify the prepared gateway operation.
199-
ModifyOperationEvaluation modify_operation = 8;
199+
ModifyOperationEvaluation modify_operation = 7;
200200
// Evaluation that may reject, but not mutate, the prepared operation.
201-
ValidateEvaluation validate = 9;
201+
ValidateEvaluation validate = 8;
202202
// Evaluation after the gateway operation has committed.
203-
PostCommitEvaluation post_commit = 10;
203+
PostCommitEvaluation post_commit = 9;
204204
}
205205
}
206206
207-
message PreRequestEvaluation {
208-
// Raw public gateway API request.
209-
google.protobuf.Struct api_request = 1;
210-
}
211-
212207
message ModifyOperationEvaluation {
213208
// Gateway-prepared operation the gateway proposes to execute.
214209
google.protobuf.Struct proposed_operation = 1;
@@ -239,7 +234,6 @@ qualified RPC selector used by bindings. For example,
239234

240235
The gateway sets exactly one `phase` variant per evaluation. The active variant
241236
identifies the selected phase and determines which payload is available.
242-
`pre_request.api_request` is the raw public gateway API request.
243237
`proposed_operation` is the gateway-prepared operation after state loading,
244238
defaulting, and prior patches; it is present for `modify_operation`, `validate`,
245239
and `post_commit`. `current_state` accompanies prepared-operation phases as
@@ -261,16 +255,14 @@ message InterceptorResult {
261255

262256
The gateway projects a valid `InterceptorResult` onto the gateway operation.
263257
`allowed = true` lets the operation continue. `allowed = false` rejects the
264-
gateway API operation in `pre_request`, `modify_operation`, or `validate`,
265-
using `status_code` and `reason`. Only modification phases accept patches:
266-
`pre_request` patches apply to `pre_request.api_request`, and
267-
`modify_operation` patches apply to
268-
`modify_operation.proposed_operation`. `current_state` is read-only context and
269-
is never patched. `warnings` and `audit_annotations` are projected into gateway
270-
response metadata and logs where applicable. `post_commit` runs after the
271-
gateway operation has committed, so it cannot reject or mutate the operation. A
272-
`post_commit` result with `allowed = false` or patches is a gateway interceptor
273-
contract violation.
258+
gateway API operation in `modify_operation` or `validate`, using `status_code`
259+
and `reason`. Only `modify_operation` accepts patches, and those patches apply
260+
to `modify_operation.proposed_operation`. `current_state` is read-only context
261+
and is never patched. `warnings` and `audit_annotations` are projected into
262+
gateway response metadata and logs where applicable. `post_commit` runs after
263+
the gateway operation has committed, so it cannot reject or mutate the
264+
operation. A `post_commit` result with `allowed = false` or patches is a gateway
265+
interceptor contract violation.
274266

275267
The `binding_id` is owned by the gateway interceptor service. It identifies the
276268
service-declared binding that selected the evaluation.
@@ -326,8 +318,8 @@ allows expansion.
326318
Empty selector fields match all values. A gateway override can narrow a
327319
service-declared selector, such as limiting a binding to a specific RPC.
328320
Patch capability is derived from the selected phase, not from a separate binding
329-
flag. A binding in `pre_request` or `modify_operation` may return zero or more
330-
patches. A binding in `validate` or `post_commit` must not return patches.
321+
flag. A binding in `modify_operation` may return zero or more patches. A
322+
binding in `validate` or `post_commit` must not return patches.
331323

332324
Gateway config example for a remote policy provider:
333325

@@ -365,8 +357,8 @@ Failure policy is gateway control-plane behavior for cases where the gateway
365357
cannot obtain or apply a valid gateway interceptor result. Examples include
366358
timeout, transport failure, service error, invalid response, response-size
367359
violation, invalid phase behavior, or patch limit violation. A valid
368-
`allowed = false` result in `pre_request`, `modify_operation`, or `validate` is
369-
not an error-policy case; the gateway must project it as an operation rejection.
360+
`allowed = false` result in `modify_operation` or `validate` is not an
361+
error-policy case; the gateway must project it as an operation rejection.
370362

371363
Each binding has an effective failure policy. The gateway starts with the
372364
service-declared binding `on_error` value, applies the gateway interceptor
@@ -380,8 +372,7 @@ service-level gateway config, then applies any binding override.
380372

381373
Defaults:
382374

383-
- `pre_request`, `modify_operation`, and `validate` bindings default to
384-
`fail_closed`.
375+
- `modify_operation` and `validate` bindings default to `fail_closed`.
385376
- `post_commit` bindings default to `ignore`.
386377

387378
The gateway enforces a timeout and response size limit for every gateway
@@ -523,8 +514,8 @@ This example illustrates the general gateway interceptor design loop:
523514
4. Build an execution plan from service manifests plus gateway-configured
524515
overrides.
525516
5. Wire gateway interceptor execution into the gateway API operation pipeline so
526-
all gateway operations can pass through `pre_request`, `modify_operation`,
527-
`validate`, and `post_commit` where applicable.
517+
all gateway operations can pass through `modify_operation`, `validate`, and
518+
`post_commit` where applicable.
528519
6. Audit existing gateway operations and route each resource-affecting path
529520
through the shared gateway interceptor pipeline.
530521
7. Add gateway interceptor result audit logging and metrics.

0 commit comments

Comments
 (0)