From 524ccba45b73b646885a430a3003e11e4893a701 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 21 Feb 2025 19:37:46 +0000 Subject: [PATCH 01/26] WIP --- A90-xds-ext-authz.md | 78 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 A90-xds-ext-authz.md diff --git a/A90-xds-ext-authz.md b/A90-xds-ext-authz.md new file mode 100644 index 000000000..9434e2f64 --- /dev/null +++ b/A90-xds-ext-authz.md @@ -0,0 +1,78 @@ +A90: xDS ExtAuthz Support +---- +* Author(s): @markdroth +* Approver: @ejona86, @dfawley +* Status: {Draft, In Review, Ready for Implementation, Implemented} +* Implemented in: +* Last updated: 2025-02-20 +* Discussion at: (filled after thread exists) + +## Abstract + +We will add support for the xDS ext_authz filter in the gRPC server. + +## Background + +The ext_authz filter provides support for servers making side-channel +call-outs to perform authorization decisions. + +### Related Proposals: +* A list of proposals this proposal builds on or supersedes. + +## Proposal + +Fields to support: +- grpc_service +- failure_mode_allow +- failure_mode_allow_header_add +- status_on_error +- allowed_headers -- note: may need to have some security control here? +- disallowed_headers +- encode_raw_headers (maybe only support true?) +==> CACHING! + +Fields that we will not support: +- http_service -- don't plan to support this +- stat_prefix +- charge_cluster_response_stats +- emit_filter_state_stats + +- filter_enabled -- seems like this is superceded by the "disable" field in the filter framework. should we support that? +- filter_enabled_metadata +- deny_at_disable + +- metadata_context_namespaces +- typed_metadata_context_namespaces +- route_metadata_context_namespaces +- route_typed_metadata_context_namespaces +- bootstrap_metadata_labels_key +- enable_dynamic_metadata_ingestion +- filter_metadata + +Not sure: +- transport_api_version +- with_request_body -- would need to solve gRPC framing problem +- include_peer_certificate +- include_tls_session + +Fields related to header mutation -- should we support these? +- clear_route_cache +- validate_mutations +- decoder_header_mutation_rules + +### Temporary environment variable protection + +[Name the environment variable(s) used to enable/disable the feature(s) this proposal introduces and their default(s). Generally, features that are enabled by I/O should include this type of control until they have passed some testing criteria, which should also be detailed here. This section may be omitted if there are none.] + +## Rationale + +[A discussion of alternate approaches and the trade offs, advantages, and disadvantages of the specified approach.] + + +## Implementation + +[A description of the steps in the implementation, who will do them, and when. If a particular language is going to get the implementation first, this section should list the proposed order.] + +## Open issues (if applicable) + +[A discussion of issues relating to this proposal for which the author does not know the solution. This section may be omitted if there are none.] From 17c8c9cc362dca5244a420dce90736790eed25e5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 11 Mar 2025 00:29:31 +0000 Subject: [PATCH 02/26] start filling in --- A90-xds-ext-authz.md | 78 ------------------- A92-xds-ext-authz.md | 179 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+), 78 deletions(-) delete mode 100644 A90-xds-ext-authz.md create mode 100644 A92-xds-ext-authz.md diff --git a/A90-xds-ext-authz.md b/A90-xds-ext-authz.md deleted file mode 100644 index 9434e2f64..000000000 --- a/A90-xds-ext-authz.md +++ /dev/null @@ -1,78 +0,0 @@ -A90: xDS ExtAuthz Support ----- -* Author(s): @markdroth -* Approver: @ejona86, @dfawley -* Status: {Draft, In Review, Ready for Implementation, Implemented} -* Implemented in: -* Last updated: 2025-02-20 -* Discussion at: (filled after thread exists) - -## Abstract - -We will add support for the xDS ext_authz filter in the gRPC server. - -## Background - -The ext_authz filter provides support for servers making side-channel -call-outs to perform authorization decisions. - -### Related Proposals: -* A list of proposals this proposal builds on or supersedes. - -## Proposal - -Fields to support: -- grpc_service -- failure_mode_allow -- failure_mode_allow_header_add -- status_on_error -- allowed_headers -- note: may need to have some security control here? -- disallowed_headers -- encode_raw_headers (maybe only support true?) -==> CACHING! - -Fields that we will not support: -- http_service -- don't plan to support this -- stat_prefix -- charge_cluster_response_stats -- emit_filter_state_stats - -- filter_enabled -- seems like this is superceded by the "disable" field in the filter framework. should we support that? -- filter_enabled_metadata -- deny_at_disable - -- metadata_context_namespaces -- typed_metadata_context_namespaces -- route_metadata_context_namespaces -- route_typed_metadata_context_namespaces -- bootstrap_metadata_labels_key -- enable_dynamic_metadata_ingestion -- filter_metadata - -Not sure: -- transport_api_version -- with_request_body -- would need to solve gRPC framing problem -- include_peer_certificate -- include_tls_session - -Fields related to header mutation -- should we support these? -- clear_route_cache -- validate_mutations -- decoder_header_mutation_rules - -### Temporary environment variable protection - -[Name the environment variable(s) used to enable/disable the feature(s) this proposal introduces and their default(s). Generally, features that are enabled by I/O should include this type of control until they have passed some testing criteria, which should also be detailed here. This section may be omitted if there are none.] - -## Rationale - -[A discussion of alternate approaches and the trade offs, advantages, and disadvantages of the specified approach.] - - -## Implementation - -[A description of the steps in the implementation, who will do them, and when. If a particular language is going to get the implementation first, this section should list the proposed order.] - -## Open issues (if applicable) - -[A discussion of issues relating to this proposal for which the author does not know the solution. This section may be omitted if there are none.] diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md new file mode 100644 index 000000000..0da41f74f --- /dev/null +++ b/A92-xds-ext-authz.md @@ -0,0 +1,179 @@ +A92: xDS ExtAuthz Support +---- +* Author(s): @markdroth +* Approver: @ejona86, @dfawley +* Status: {Draft, In Review, Ready for Implementation, Implemented} +* Implemented in: +* Last updated: 2025-03-10 +* Discussion at: (filled after thread exists) + +## Abstract + +We will add support for the xDS ext_authz filter in the gRPC server. + +## Background + +The ext_authz filter provides support for servers making side-channel +call-outs to perform authorization decisions. + +The ext_authz filter will use the existing infrastructure for xDS HTTP +servers in the gRPC server, which was originally introduced in gRFCs [A39] +and [A36]. This infrastructure has previously been used for the RBAC +filter, described in [A41], and the rate-limiting filter, described in +[A77]. + +Note that this filter will make use of the `allowed_grpc_services` map in +the bootstrap config, described in [A77]. It will also make use of the +`trusted_xds_server` server feature introduced in [A81]. + +### Related Proposals: +* [A39: xDS HTTP Filter Support][A39] +* [A36: xDS-Enabled Servers][A36] +* [A41: xDS RBAC Support][A41] +* [A77: xDS Server-Side Rate Limiting][A77] (pending) +* [A81: xDS Authority Rewriting][A81] + +[A36]: A36-xds-for-servers.md +[A39]: A39-xds-http-filters.md +[A41]: A41-xds-rbac.md +[A77]: https://github.com/grpc/proposal/pull/414 +[A81]: A81-xds-authority-rewriting.md + +## Proposal + +### Filter Configuration + +We will support the following fields: +- grpc_service: This field must be present. Inside of it: + - google_grpc: This field must be present. Inside of it: + - target_uri: This field must be non-empty and must be a valid + target URI. The value specified here must be present in the + `allowed_grpc_services` map in the bootstrap config, which will + also determine the credentials to use, as described in [A77]. + - Note: All other fields are ignored. + - timeout: Used to set the RPC deadline. If unset, there is no deadline. + - All other fields are ignored. +- failure_mode_allow +- failure_mode_allow_header_add +- status_on_error: Note that this field specifies an HTTP status code, + not a gRPC status code. The gRPC status code will be determined using + the normal [HTTP-to-gRPC status conversion + rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). +- allowed_headers: TODO: Want to not allow sending certain sensitive + headers unless `trusted_xds_server` is present, but hard with regex + matches... Maybe just don't allow matchers to match against sensitive + headers? +- disallowed_headers +- decoder_header_mutation_rules: Optional. Inside of it: + - allow_all_routing: This field will control only whether the + ext_authz server can overwrite the `:authority` header. If this + field is set to true and the `trusted_xds_server` server feature is + not present in the bootstrap config, we will reject the config. + - TODO: Figure out how to handle allow_expression w.r.t. it matching a + restricted header. Maybe just don't allow it to match against those? +- include_peer_certificate +- TODO: CACHING! + +The following fields will be ignored by gRPC: +- http_service: It doesn't make sense for gRPC to support non-gRPC + mechanisms for contacting the ext_authz server. +- stat_prefix, charge_cluster_response_stats, emit_filter_state_stats: + These do not apply to gRPC. +- transport_api_version: Not relevant, since gRPC supports only xDS v3. +- with_request_body: This feature is structured around an HTTP request + and doesn't really make sense for gRPC, both because it's unclear how + it would work for streaming RPCs and because it would include only the + first message on the stream, not the raw HTTP DATA frame content. +- validate_mutations: We will unconditionally reject invalid mutations. +- clear_route_cache: We don't currently support recomputing the route. + We could consider adding this in the future if we have a use-case for + it. +- encode_raw_headers: We will unconditionally encode headers in raw form. +- metadata_context_namespaces, typed_metadata_context_namespaces, + route_metadata_context_namespaces, route_typed_metadata_context_namespaces, + enable_dynamic_metadata_ingestion, filter_metadata: gRPC does not currently + support dynamic metadata. +- bootstrap_metadata_labels_key: We have no current use-case for this. We + could consider adding it in the future if there is a need. +- filter_enabled, filter_enabled_metadata, deny_at_disable: We don't currently + support the runtime system. +- include_tls_session: We do not currently have a use-case for this, but + we could consider adding it in the future if we do encounter such a + use-case. + +We will not support per-route config overrides for this filter. TODO: +If we need the `disabled` flag, maybe just support that via the +`FilterConfig.disabled` field in `typed_per_filter_config` instead of +doing it in an ext_authz-specific way? Just make sure that the +semantics are the same -- ext_authz config says "If disabled is +specified in multiple per-filter-configs, the most specific one will be +used." + +### Communication With the ext_authz Server + +The `AttributeContext` message sent to the server will be populated as +follows: +- source: Will always be set. Inside it: + - address and service will be set. + - labels will not be set. + - principal will be set if the client provided a cert and we validates + it, unset otherwise. + - certificate: This will be populated if configured. +- destination: This field will not be populated, because there is no + destination on a gRPC server. +- request: Will always be set. Inside it: + - id: TODO: how do we set this? + - method: Will always be "POST". + - header_map: Will be set based on config. + - path: Will always be set. + - scheme: TODO: set based on whether TLS is used? + - size: Will always be set to -1. TODO: For unary, could maybe set it + to the size of the message payload. + - protocol: Always set to "HTTP/2". + - headers, query, fragment, body, raw_body: Will *not* be set. +- context_extensions, metadata_context, route_metadata_context, + tls_session: Will *not* be set. + +We will handle the `CheckResponse` as follows: +- status: Supported. +- denied_response: + - status: The HTTP status to fail the RPC with. We apply the normal + [HTTP-to-gRPC status conversion + rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). + - headers: TODO: Figure out what restrictions to apply here. + - body: Ignored; does not apply to gRPC. +- ok_response: + - headers, headers_to_remove, response_headers_to_add: See [header + rewriting](#header-rewriting) below for details. + - query_parameters_to_set, query_parameters_to_remove: Ignored; these + do not apply to gRPC. +- dynamic_metadata: Ignored. + +### Header Rewriting + +gRPC will support rewriting the `:authority` field only if the +`trusted_xds_server` server feature is present in the bootstrap config, +regardless of what settings are present in the ext_authz filter config. + +If the ext_authz server attempts to overwrite the `host` header, that +change will actually apply to the `:authority` header instead. + +Note that gRPC will not support rewriting the `:scheme` or `:method` +headers, regardless of the value of this field. + +### Temporary environment variable protection + +[Name the environment variable(s) used to enable/disable the feature(s) this proposal introduces and their default(s). Generally, features that are enabled by I/O should include this type of control until they have passed some testing criteria, which should also be detailed here. This section may be omitted if there are none.] + +## Rationale + +[A discussion of alternate approaches and the trade offs, advantages, and disadvantages of the specified approach.] + + +## Implementation + +[A description of the steps in the implementation, who will do them, and when. If a particular language is going to get the implementation first, this section should list the proposed order.] + +## Open issues (if applicable) + +[A discussion of issues relating to this proposal for which the author does not know the solution. This section may be omitted if there are none.] From 5d4e313ba396d7dc42c4d82f7129c32061ee519c Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 11 Mar 2025 21:40:16 +0000 Subject: [PATCH 03/26] add links --- A92-xds-ext-authz.md | 139 ++++++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 49 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 0da41f74f..3ed744bc7 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -43,35 +43,53 @@ the bootstrap config, described in [A77]. It will also make use of the ### Filter Configuration -We will support the following fields: -- grpc_service: This field must be present. Inside of it: - - google_grpc: This field must be present. Inside of it: - - target_uri: This field must be non-empty and must be a valid - target URI. The value specified here must be present in the - `allowed_grpc_services` map in the bootstrap config, which will - also determine the credentials to use, as described in [A77]. +We will support the following fields in the [`ExtAuthz` +proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L34): +- [grpc_service](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L45): + This field must be present. Inside of it: + - [google_grpc](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L303): + This field must be present. Inside of it: + - [target_uri](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L254): + This field must be non-empty and must be a valid target URI. The + value specified here must be present in the `allowed_grpc_services` + map in the bootstrap config, which will also determine the credentials + to use, as described in [A77]. - Note: All other fields are ignored. - - timeout: Used to set the RPC deadline. If unset, there is no deadline. + - [timeout](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L308): + Specifies the deadline for the RPCs sent to the ext_authz server. + If unset, there is no deadline. The value must obey the restrictions + specified in the [`google.protobuf.Duration` + documentation](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration), + and it must have a positive value. - All other fields are ignored. -- failure_mode_allow -- failure_mode_allow_header_add -- status_on_error: Note that this field specifies an HTTP status code, +- [failure_mode_allow](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L68) +- [failure_mode_allow_header_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L74) +- [status_on_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L95): Note that this field specifies an HTTP status code, not a gRPC status code. The gRPC status code will be determined using the normal [HTTP-to-gRPC status conversion rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). -- allowed_headers: TODO: Want to not allow sending certain sensitive - headers unless `trusted_xds_server` is present, but hard with regex - matches... Maybe just don't allow matchers to match against sensitive - headers? -- disallowed_headers -- decoder_header_mutation_rules: Optional. Inside of it: - - allow_all_routing: This field will control only whether the +- [allowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L229): + TODO: Want to not allow sending certain sensitive headers unless + `trusted_xds_server` is present, but hard with regex matches... + Maybe just don't allow matchers to match against sensitive headers? +- [disallowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L233) +- [decoder_header_mutation_rules](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L282): + Optional. Inside of it: + - [allow_all_routing](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L52): This field will control only whether the ext_authz server can overwrite the `:authority` header. If this field is set to true and the `trusted_xds_server` server feature is not present in the bootstrap config, we will reject the config. - - TODO: Figure out how to handle allow_expression w.r.t. it matching a - restricted header. Maybe just don't allow it to match against those? -- include_peer_certificate + - [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59C29-L59C40): + TODO: Do we need this? Those headers aren't really special to gRPC. + - [disallow_system](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L65C29-L65C44): + TODO: Should we allow these headers to be modified at all? + - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70C29-L70C41) + - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75C32-L75C48): + TODO: Figure out how to handle matching a restricted header. Maybe just + don't allow it to match against those? + - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79C32-L79C51) + - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87C29-L87C46) +- [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) - TODO: CACHING! The following fields will be ignored by gRPC: @@ -83,7 +101,8 @@ The following fields will be ignored by gRPC: - with_request_body: This feature is structured around an HTTP request and doesn't really make sense for gRPC, both because it's unclear how it would work for streaming RPCs and because it would include only the - first message on the stream, not the raw HTTP DATA frame content. + first message on the stream (after gRPC deframing), not the raw HTTP + DATA frame content. - validate_mutations: We will unconditionally reject invalid mutations. - clear_route_cache: We don't currently support recomputing the route. We could consider adding this in the future if we have a use-case for @@ -111,40 +130,62 @@ used." ### Communication With the ext_authz Server -The `AttributeContext` message sent to the server will be populated as -follows: -- source: Will always be set. Inside it: - - address and service will be set. +The [`AttributeContext` +message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L43) +sent to the server will be populated as follows: +- [source](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L192): Will always be set. Inside it: + - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) + and [service](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L65) + will be set. - labels will not be set. - - principal will be set if the client provided a cert and we validates - it, unset otherwise. - - certificate: This will be populated if configured. -- destination: This field will not be populated, because there is no - destination on a gRPC server. -- request: Will always be set. Inside it: - - id: TODO: how do we set this? - - method: Will always be "POST". - - header_map: Will be set based on config. - - path: Will always be set. - - scheme: TODO: set based on whether TLS is used? - - size: Will always be set to -1. TODO: For unary, could maybe set it - to the size of the message payload. - - protocol: Always set to "HTTP/2". - - headers, query, fragment, body, raw_body: Will *not* be set. + - [principal](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L82) + will be set if the client provided a cert and we validates it, unset + otherwise. + - [certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L86): This will be populated if configured. +- [destination](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L197): + This field will not be populated, because there is no destination on a gRPC + server. +- [request](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L200): + Will always be set. Inside it: + - [time](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L95): + Will be set to the RPC's start time. + - [http](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L98): + Will always be set. Inside of it: + - [id](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L112): TODO: how do we set this? + - [method](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L115): + Will always be "POST". + - [header_map](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L143): + Will be set based on config. + - [path](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L148): + Will always be set. + - [scheme](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L154): + TODO: set based on whether TLS is used? + - [size](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L165): + Will always be set to -1. + - [protocol](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L171): + Always set to "HTTP/2". + - headers, query, fragment, body, raw_body: Will *not* be set. - context_extensions, metadata_context, route_metadata_context, tls_session: Will *not* be set. -We will handle the `CheckResponse` as follows: -- status: Supported. -- denied_response: - - status: The HTTP status to fail the RPC with. We apply the normal +We will handle the [`CheckResponse`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L117) +as follows: +- [status](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L124): + Supported. +- [denied_response](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L131): + Supported. Inside of it: + - [status](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L50): + The HTTP status to fail the RPC with. We apply the normal [HTTP-to-gRPC status conversion rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). - - headers: TODO: Figure out what restrictions to apply here. + - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55): + TODO: Figure out what restrictions to apply here. - body: Ignored; does not apply to gRPC. -- ok_response: - - headers, headers_to_remove, response_headers_to_add: See [header - rewriting](#header-rewriting) below for details. +- [ok_response](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L134): + - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L75), + [headers_to_remove](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L92), + [response_headers_to_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L104): + See [header rewriting](#header-rewriting) below for details. - query_parameters_to_set, query_parameters_to_remove: Ignored; these do not apply to gRPC. - dynamic_metadata: Ignored. From 7900be659b0c5da206315a55cf47d1efabbff119 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 13 Mar 2025 20:41:58 +0000 Subject: [PATCH 04/26] fix some links --- A92-xds-ext-authz.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 3ed744bc7..b148775ab 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -79,16 +79,16 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f ext_authz server can overwrite the `:authority` header. If this field is set to true and the `trusted_xds_server` server feature is not present in the bootstrap config, we will reject the config. - - [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59C29-L59C40): + - [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59): TODO: Do we need this? Those headers aren't really special to gRPC. - - [disallow_system](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L65C29-L65C44): + - [disallow_system](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L65): TODO: Should we allow these headers to be modified at all? - - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70C29-L70C41) - - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75C32-L75C48): + - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70) + - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75): TODO: Figure out how to handle matching a restricted header. Maybe just don't allow it to match against those? - - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79C32-L79C51) - - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87C29-L87C46) + - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79) + - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87) - [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) - TODO: CACHING! From 86bca69138f90cf0f557b94b00072c7d044f0409 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 16 Jun 2025 19:46:35 +0000 Subject: [PATCH 05/26] add env var --- A92-xds-ext-authz.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index b148775ab..986b1a5ff 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -204,7 +204,9 @@ headers, regardless of the value of this field. ### Temporary environment variable protection -[Name the environment variable(s) used to enable/disable the feature(s) this proposal introduces and their default(s). Generally, features that are enabled by I/O should include this type of control until they have passed some testing criteria, which should also be detailed here. This section may be omitted if there are none.] +Support for the `ext_authz` filter will be guarded by the +`GRPC_EXPERIMENTAL_XDS_EXT_AUTHZ` environment variable. This guard will +be removed once the feature passes interop tests. ## Rationale From 5de2312f73a3bf2c1670e905721d96d737a7951e Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 17 Jun 2025 22:41:20 +0000 Subject: [PATCH 06/26] caching is out of scope -- will be in a future gRFC instead --- A92-xds-ext-authz.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 986b1a5ff..aa95d2953 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-03-10 +* Last updated: 2025-06-17 * Discussion at: (filled after thread exists) ## Abstract @@ -90,7 +90,6 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79) - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87) - [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) -- TODO: CACHING! The following fields will be ignored by gRPC: - http_service: It doesn't make sense for gRPC to support non-gRPC @@ -210,8 +209,12 @@ be removed once the feature passes interop tests. ## Rationale -[A discussion of alternate approaches and the trade offs, advantages, and disadvantages of the specified approach.] - +We will ultimately need caching support for performance reasons, since +it will not scale to make an ext_authz RPC for every data plane RPC. +However, the design discussions around caching are still ongoing, and +we have use-cases that require use of ext_authz today. Therefore, we +are decoupling the caching discussion to a separate gRFC to be published +later. ## Implementation From 5ffbc88018463b3dcce271554dd4194a56a3da93 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 17 Jun 2025 22:47:45 +0000 Subject: [PATCH 07/26] don't set scheme in ext_authz request --- A92-xds-ext-authz.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index aa95d2953..ae3a8eacf 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -157,13 +157,11 @@ sent to the server will be populated as follows: Will be set based on config. - [path](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L148): Will always be set. - - [scheme](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L154): - TODO: set based on whether TLS is used? - [size](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L165): Will always be set to -1. - [protocol](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L171): Always set to "HTTP/2". - - headers, query, fragment, body, raw_body: Will *not* be set. + - scheme, headers, query, fragment, body, raw_body: Will *not* be set. - context_extensions, metadata_context, route_metadata_context, tls_session: Will *not* be set. From 55e27020896d9b1ee3a7338242244df904d091b9 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 17 Jun 2025 23:25:48 +0000 Subject: [PATCH 08/26] flesh out setting source and destination in ext_authz request --- A92-xds-ext-authz.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index ae3a8eacf..6cbf7d1f4 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -134,16 +134,27 @@ message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba sent to the server will be populated as follows: - [source](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L192): Will always be set. Inside it: - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) - and [service](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L65) - will be set. - - labels will not be set. - - [principal](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L82) - will be set if the client provided a cert and we validates it, unset - otherwise. + will be set to the peer address of the connection that the request + came in on. + - [principal](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L82): + If TLS is used and the client provided a valid certificate, this will be + set to the cert's first URI SAN if set, otherwise the cert's first DNS + SAN if set, otherwise the subject field of the certificate in RFC + 2253 format. If TLS is not used or the client did not provide a + cert, this field will be unset. - [certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L86): This will be populated if configured. + - service, labels: Will *not* be set. - [destination](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L197): - This field will not be populated, because there is no destination on a gRPC - server. + Will always be set. Inside it: + - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) + will be set to the local address of the connection that the request + came in on. + - [principal](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L82): + If TLS is used, this will be set to the server's cert's first URI SAN + if set, otherwise the cert's first DNS SAN if set, otherwise the + subject field of the certificate in RFC 2253 format. If TLS is not + used, this field will be unset. + - certificate, service, labels: Will *not* be set. - [request](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L200): Will always be set. Inside it: - [time](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L95): From a8b67dfcd22835844d303023456a08f17ec29125 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 17 Jun 2025 23:33:10 +0000 Subject: [PATCH 09/26] don't set request ID in ext_authz request --- A92-xds-ext-authz.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 6cbf7d1f4..56a5f7123 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -161,7 +161,6 @@ sent to the server will be populated as follows: Will be set to the RPC's start time. - [http](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L98): Will always be set. Inside of it: - - [id](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L112): TODO: how do we set this? - [method](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L115): Will always be "POST". - [header_map](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L143): @@ -172,7 +171,7 @@ sent to the server will be populated as follows: Will always be set to -1. - [protocol](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L171): Always set to "HTTP/2". - - scheme, headers, query, fragment, body, raw_body: Will *not* be set. + - id, scheme, headers, query, fragment, body, raw_body: Will *not* be set. - context_extensions, metadata_context, route_metadata_context, tls_session: Will *not* be set. From 15fee5d438d1315cadd2fbe1ceffb0137f342774 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 27 Jun 2025 17:47:14 +0000 Subject: [PATCH 10/26] clarify header rewriting rules --- A92-xds-ext-authz.md | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 56a5f7123..db4e0b756 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-06-17 +* Last updated: 2025-06-27 * Discussion at: (filled after thread exists) ## Abstract @@ -68,27 +68,26 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f not a gRPC status code. The gRPC status code will be determined using the normal [HTTP-to-gRPC status conversion rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). -- [allowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L229): - TODO: Want to not allow sending certain sensitive headers unless - `trusted_xds_server` is present, but hard with regex matches... - Maybe just don't allow matchers to match against sensitive headers? +- [allowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L229) - [disallowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L233) - [decoder_header_mutation_rules](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L282): Optional. Inside of it: - - [allow_all_routing](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L52): This field will control only whether the - ext_authz server can overwrite the `:authority` header. If this - field is set to true and the `trusted_xds_server` server feature is - not present in the bootstrap config, we will reject the config. - - [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59): - TODO: Do we need this? Those headers aren't really special to gRPC. + - [allow_all_routing](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L52): + This field will control only whether the ext_authz server can overwrite + the `:authority` header. If this field is set to true and the + `trusted_xds_server` server feature is not present in the bootstrap + config, we will reject the config. - [disallow_system](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L65): - TODO: Should we allow these headers to be modified at all? + This field will control only whether the ext_authz server can overwrite + the `:authority` header. If this field is set to true and the + `trusted_xds_server` server feature is not present in the bootstrap + config, we will reject the config. - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70) - - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75): - TODO: Figure out how to handle matching a restricted header. Maybe just - don't allow it to match against those? + - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75) - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79) - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87) + - The [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59) + field will be ignored, since those headers aren't really special to gRPC. - [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) The following fields will be ignored by gRPC: @@ -185,8 +184,7 @@ as follows: The HTTP status to fail the RPC with. We apply the normal [HTTP-to-gRPC status conversion rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). - - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55): - TODO: Figure out what restrictions to apply here. + - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55) - body: Ignored; does not apply to gRPC. - [ok_response](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L134): - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L75), @@ -199,6 +197,10 @@ as follows: ### Header Rewriting +gRPC will not support rewriting the `:scheme`, `:method`, or `:path` +headers, regardless of what settings are present in the ext_authz +filter config. + gRPC will support rewriting the `:authority` field only if the `trusted_xds_server` server feature is present in the bootstrap config, regardless of what settings are present in the ext_authz filter config. @@ -206,9 +208,6 @@ regardless of what settings are present in the ext_authz filter config. If the ext_authz server attempts to overwrite the `host` header, that change will actually apply to the `:authority` header instead. -Note that gRPC will not support rewriting the `:scheme` or `:method` -headers, regardless of the value of this field. - ### Temporary environment variable protection Support for the `ext_authz` filter will be guarded by the From acbf2538a5d9dba126599f41c7bf9c58bed6f958 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 27 Jun 2025 18:18:43 +0000 Subject: [PATCH 11/26] filter config overrides --- A39-xds-http-filters.md | 1 + A92-xds-ext-authz.md | 32 +++++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/A39-xds-http-filters.md b/A39-xds-http-filters.md index a7f0bd54a..2a9de862e 100644 --- a/A39-xds-http-filters.md +++ b/A39-xds-http-filters.md @@ -6,6 +6,7 @@ A39: xDS HTTP Filter Support * Implemented in: C-core * Last updated: 2021-07-20 * Discussion at: https://groups.google.com/g/grpc-io/c/M-l8k2v5snY +* Updated by: [gRFC A92: xDS ExtAuthz](A92-xds-ext-authz.md) ## Abstract diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index db4e0b756..3d00ba339 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -118,13 +118,31 @@ The following fields will be ignored by gRPC: we could consider adding it in the future if we do encounter such a use-case. -We will not support per-route config overrides for this filter. TODO: -If we need the `disabled` flag, maybe just support that via the -`FilterConfig.disabled` field in `typed_per_filter_config` instead of -doing it in an ext_authz-specific way? Just make sure that the -semantics are the same -- ext_authz config says "If disabled is -specified in multiple per-filter-configs, the most specific one will be -used." +### Filter Configuration Overrides + +We will support `typed_per_filter_config` config overrides for this +filter, as described in [A39]. + +The override config for this filter is encoded as an [`ExtAuthzPerRoute` +proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L460). +However, we will ignore all of the fields in the proto; the only reason +for supporting it is so that we can disable the filter for individual +virtual hosts, routes, or cluster weights. + +Note that we will not use the [`disabled` +field](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L469) +in the `ExtAuthzPerRoute` proto itself; instead, we will support disabling +via a more generic mechanism that can apply to any filter. Specifically, +we will honor both the `disabled` field in both the [`HttpFilter` +message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#L1229) +in the HCM config and in the [`FilterConfig` wrapper +message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/route/v3/route_components.proto#L2562) +that can be used in `typed_per_filter_config` fields. + +Note that the most specific `typed_per_filter_config` will be used. For +example, if there is an override config at the virtual host level that +disables the filter but then another config at the route level that does +not disable the filter, the filter will be enabled. ### Communication With the ext_authz Server From f36c4e232f0b93f0cff53555ae3207276d052809 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 27 Jun 2025 18:40:20 +0000 Subject: [PATCH 12/26] add filter disable percentage --- A92-xds-ext-authz.md | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 3d00ba339..91ab95c20 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -32,12 +32,14 @@ the bootstrap config, described in [A77]. It will also make use of the * [A41: xDS RBAC Support][A41] * [A77: xDS Server-Side Rate Limiting][A77] (pending) * [A81: xDS Authority Rewriting][A81] +* [A33: xDS Fault Injection][A33] [A36]: A36-xds-for-servers.md [A39]: A39-xds-http-filters.md [A41]: A41-xds-rbac.md [A77]: https://github.com/grpc/proposal/pull/414 [A81]: A81-xds-authority-rewriting.md +[A33]: A33-Fault-Injection.md ## Proposal @@ -62,6 +64,22 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f documentation](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration), and it must have a positive value. - All other fields are ignored. +- [filter_enabled](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L158): + Optional; if unset, the filter is enabled. This field will be validated + the same way as in the fault injection filter (see [A33]). Within it: + - [default_value](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L648): + This field must be present. The configured value will be capped at 100%. + - The `runtime_key` field will be ignored, since gRPC does not have a + runtime system. +- [deny_at_disable](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L175C18-L175C36): + Optional; if unset, requests are allowed when the filter is disabled. + If set, then within this field: + - [default_value](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L298): + Must be present. If true, then when the filter is disabled, the + request will be failed with a status based on the `status_on_error` + field (see below). + - The `runtime_key` field will be ignored, since gRPC does not have a + runtime system. - [failure_mode_allow](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L68) - [failure_mode_allow_header_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L74) - [status_on_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L95): Note that this field specifies an HTTP status code, @@ -108,12 +126,10 @@ The following fields will be ignored by gRPC: - encode_raw_headers: We will unconditionally encode headers in raw form. - metadata_context_namespaces, typed_metadata_context_namespaces, route_metadata_context_namespaces, route_typed_metadata_context_namespaces, - enable_dynamic_metadata_ingestion, filter_metadata: gRPC does not currently - support dynamic metadata. + enable_dynamic_metadata_ingestion, filter_metadata, filter_enabled_metadata: + gRPC does not currently support dynamic metadata. - bootstrap_metadata_labels_key: We have no current use-case for this. We could consider adding it in the future if there is a need. -- filter_enabled, filter_enabled_metadata, deny_at_disable: We don't currently - support the runtime system. - include_tls_session: We do not currently have a use-case for this, but we could consider adding it in the future if we do encounter such a use-case. From 18713455734fc9d3e4b98bb442237cc0b5b679b7 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 27 Jun 2025 23:48:24 +0000 Subject: [PATCH 13/26] add more info about GoogleGrpc --- A92-xds-ext-authz.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 91ab95c20..26d869007 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -52,10 +52,19 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f - [google_grpc](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L303): This field must be present. Inside of it: - [target_uri](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L254): - This field must be non-empty and must be a valid target URI. The - value specified here must be present in the `allowed_grpc_services` - map in the bootstrap config, which will also determine the credentials - to use, as described in [A77]. + This field must be non-empty and must be a valid target URI. If + the `trusted_xds_server` server feature (see [A81]) is *not* set in + the bootstrap config, then the value specified here must be present + in the `allowed_grpc_services` map in the bootstrap config, which + will also determine the credentials to use, as described in [A77]. + - [channel_credentials](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L256): + Used only if `trusted_xds_server` server feature is present in the + bootstrap config. + TODO: flesh this out + - [call_credentials](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L260): + Used only if `trusted_xds_server` server feature is present in the + bootstrap config. + TODO: flesh this out - Note: All other fields are ignored. - [timeout](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L308): Specifies the deadline for the RPCs sent to the ext_authz server. @@ -259,8 +268,4 @@ later. ## Implementation -[A description of the steps in the implementation, who will do them, and when. If a particular language is going to get the implementation first, this section should list the proposed order.] - -## Open issues (if applicable) - -[A discussion of issues relating to this proposal for which the author does not know the solution. This section may be omitted if there are none.] +Will be implemented in C-core, Java, Go, and Node. From 14758e5b6f2a76da067c1bc20554c7b9742058db Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Mon, 7 Jul 2025 20:29:16 +0000 Subject: [PATCH 14/26] don't allow `:authority` header rewriting, since that's not useful on the server side --- A92-xds-ext-authz.md | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 26d869007..fd6253017 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-06-27 +* Last updated: 2025-07-07 * Discussion at: (filled after thread exists) ## Abstract @@ -99,22 +99,12 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f - [disallowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L233) - [decoder_header_mutation_rules](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L282): Optional. Inside of it: - - [allow_all_routing](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L52): - This field will control only whether the ext_authz server can overwrite - the `:authority` header. If this field is set to true and the - `trusted_xds_server` server feature is not present in the bootstrap - config, we will reject the config. - - [disallow_system](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L65): - This field will control only whether the ext_authz server can overwrite - the `:authority` header. If this field is set to true and the - `trusted_xds_server` server feature is not present in the bootstrap - config, we will reject the config. - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70) - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75) - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79) - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87) - - The [allow_envoy](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L59) - field will be ignored, since those headers aren't really special to gRPC. + - allow_all_routing, disallow_system, allow_envoy: These fields will + be ignored. - [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) The following fields will be ignored by gRPC: @@ -240,16 +230,10 @@ as follows: ### Header Rewriting -gRPC will not support rewriting the `:scheme`, `:method`, or `:path` -headers, regardless of what settings are present in the ext_authz -filter config. - -gRPC will support rewriting the `:authority` field only if the -`trusted_xds_server` server feature is present in the bootstrap config, -regardless of what settings are present in the ext_authz filter config. - -If the ext_authz server attempts to overwrite the `host` header, that -change will actually apply to the `:authority` header instead. +gRPC will not support rewriting the `:scheme`, `:method`, `:path`, +`:authority`, or `host` headers, regardless of what settings are present +in the ext_authz filter config. If the server specifies a rewrite for +one of these headers, that rewrite will be ignored. ### Temporary environment variable protection From 8abd1faf238999f1319adbb44d1569b1d551416a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 8 Jul 2025 00:02:35 +0000 Subject: [PATCH 15/26] add support for channel creds extensions --- A92-xds-ext-authz.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index fd6253017..3971654c8 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -65,6 +65,13 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f Used only if `trusted_xds_server` server feature is present in the bootstrap config. TODO: flesh this out + - [credentials_factory_name](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L276) + and + [config](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L280): + These fields are used to configure channel credentials using the + same channel credentials registry that we use in the xDS bootstrap + file. If `credentials_factory_name` is set, it takes precedence + over `channel_credentials`. - Note: All other fields are ignored. - [timeout](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L308): Specifies the deadline for the RPCs sent to the ext_authz server. From ad0cbfbdd5c2da5bc4972e2474ff743509b8dc5a Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 10 Jul 2025 22:11:47 +0000 Subject: [PATCH 16/26] fix grammar --- A92-xds-ext-authz.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 3971654c8..beba50741 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -155,7 +155,7 @@ Note that we will not use the [`disabled` field](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L469) in the `ExtAuthzPerRoute` proto itself; instead, we will support disabling via a more generic mechanism that can apply to any filter. Specifically, -we will honor both the `disabled` field in both the [`HttpFilter` +we will honor the `disabled` field in both the [`HttpFilter` message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto#L1229) in the HCM config and in the [`FilterConfig` wrapper message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/route/v3/route_components.proto#L2562) From e5f16532f80d89244dc31e708d3156c6272405c5 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 22 Aug 2025 00:18:34 +0000 Subject: [PATCH 17/26] reference A102 and add client side support --- A92-xds-ext-authz.md | 56 +++++++++----------------------------------- 1 file changed, 11 insertions(+), 45 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index beba50741..6ddd5498c 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,42 +4,39 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-07-07 +* Last updated: 2025-08-21 * Discussion at: (filled after thread exists) ## Abstract -We will add support for the xDS ext_authz filter in the gRPC server. +We will add support for the xDS ext_authz filter in both the gRPC client +and server. ## Background -The ext_authz filter provides support for servers making side-channel -call-outs to perform authorization decisions. +The ext_authz filter provides support for making side-channel call-outs +to perform authorization decisions. The ext_authz filter will use the existing infrastructure for xDS HTTP -servers in the gRPC server, which was originally introduced in gRFCs [A39] -and [A36]. This infrastructure has previously been used for the RBAC -filter, described in [A41], and the rate-limiting filter, described in -[A77]. +filters, described in [A39]. We will support this filter on both +the gRPC client and server side. Note that this filter will make use of the `allowed_grpc_services` map in -the bootstrap config, described in [A77]. It will also make use of the +the bootstrap config, described in [A102]. It will also make use of the `trusted_xds_server` server feature introduced in [A81]. ### Related Proposals: * [A39: xDS HTTP Filter Support][A39] * [A36: xDS-Enabled Servers][A36] -* [A41: xDS RBAC Support][A41] -* [A77: xDS Server-Side Rate Limiting][A77] (pending) * [A81: xDS Authority Rewriting][A81] * [A33: xDS Fault Injection][A33] +* [A102: xDS GrpcService Support][A102] (pending) [A36]: A36-xds-for-servers.md [A39]: A39-xds-http-filters.md -[A41]: A41-xds-rbac.md -[A77]: https://github.com/grpc/proposal/pull/414 [A81]: A81-xds-authority-rewriting.md [A33]: A33-Fault-Injection.md +[A102]: https://github.com/grpc/proposal/pull/510 ## Proposal @@ -48,38 +45,7 @@ the bootstrap config, described in [A77]. It will also make use of the We will support the following fields in the [`ExtAuthz` proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L34): - [grpc_service](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L45): - This field must be present. Inside of it: - - [google_grpc](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L303): - This field must be present. Inside of it: - - [target_uri](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L254): - This field must be non-empty and must be a valid target URI. If - the `trusted_xds_server` server feature (see [A81]) is *not* set in - the bootstrap config, then the value specified here must be present - in the `allowed_grpc_services` map in the bootstrap config, which - will also determine the credentials to use, as described in [A77]. - - [channel_credentials](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L256): - Used only if `trusted_xds_server` server feature is present in the - bootstrap config. - TODO: flesh this out - - [call_credentials](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L260): - Used only if `trusted_xds_server` server feature is present in the - bootstrap config. - TODO: flesh this out - - [credentials_factory_name](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L276) - and - [config](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L280): - These fields are used to configure channel credentials using the - same channel credentials registry that we use in the xDS bootstrap - file. If `credentials_factory_name` is set, it takes precedence - over `channel_credentials`. - - Note: All other fields are ignored. - - [timeout](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/grpc_service.proto#L308): - Specifies the deadline for the RPCs sent to the ext_authz server. - If unset, there is no deadline. The value must obey the restrictions - specified in the [`google.protobuf.Duration` - documentation](https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Duration), - and it must have a positive value. - - All other fields are ignored. + This field must be present. It will be handled as described in [A102]. - [filter_enabled](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L158): Optional; if unset, the filter is enabled. This field will be validated the same way as in the fault injection filter (see [A33]). Within it: From 4dc82c16f03de3f5fe7af33eb9b503d06410e24d Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 10 Sep 2025 21:23:40 +0000 Subject: [PATCH 18/26] document filter behavior, and some cleanups --- A92-xds-ext-authz.md | 66 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 6ddd5498c..df6090ed2 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-08-21 +* Last updated: 2025-09-10 * Discussion at: (filled after thread exists) ## Abstract @@ -132,12 +132,46 @@ example, if there is an override config at the virtual host level that disables the filter but then another config at the route level that does not disable the filter, the filter will be enabled. -### Communication With the ext_authz Server +### Filter Behavior + +TODO: ExtAuthz channel retention (simple approach for now, probably +globally shared channel is fine?) + +On both the gRPC client and server side, the ext_authz filter will perform +the per-RPC authorization check when it sees the client's initial metadata +(i.e., at the start of the stream). + +If the `filter_enabled` config field is set to a value less than +100%, the filter will generate a random number in the range [0, +100] for the RPC, and if that random number is greater than or +equal to the configured `filter_enabled` value, then the ext_authz +filter is not considered enabled for that RPC. In that case, if +the `deny_at_disable` config field is set to true, then the RPC +will be failed with the status derived from the `status_on_error` +config field, using the normal [HTTP-to-gRPC status conversion +rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). +Otherwise, the RPC will be passed to the next filter without modification. + +If the filter is enabled for the RPC, it will then send an RPC to the +ext_authz service to determine if the RPC should be allowed. + +If the RPC to the ext_authz service fails, then if the +`failure_mode_allow` config field is set to false, the data plane RPC +will be failed with the status derived from the `status_on_error` +config field, using the normal [HTTP-to-gRPC status conversion +rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). +Otherwise, the data plane RPC will be allowed. If the +`failure_mode_allow_header_add` config field is true, then the filter +will add a `x-envoy-auth-failure-mode-allowed: true` header to the data +plane RPC. + +#### Constructing the ext_authz Request The [`AttributeContext` message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L43) sent to the server will be populated as follows: - [source](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L192): Will always be set. Inside it: + - TODO: will this be set on client side? - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) will be set to the peer address of the connection that the request came in on. @@ -147,10 +181,13 @@ sent to the server will be populated as follows: SAN if set, otherwise the subject field of the certificate in RFC 2253 format. If TLS is not used or the client did not provide a cert, this field will be unset. - - [certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L86): This will be populated if configured. + - [certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L86): + This will be populated if the `include_peer_certificate` config + field is set to true. - service, labels: Will *not* be set. - [destination](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L197): Will always be set. Inside it: + - TODO: will this be set on client side? - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) will be set to the local address of the connection that the request came in on. @@ -169,7 +206,12 @@ sent to the server will be populated as follows: - [method](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L115): Will always be "POST". - [header_map](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L143): - Will be set based on config. + The filter will iterate through each header on the data plane RPC. + For each header, if the header is matched by the `disallowed_headers` + config field, it will not be added to this map. Otherwise, + if the `allowed_headers` config field is unset or matches the header, + the header will be added to this map. Otherwise, the header will + be excluded from this map. - [path](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L148): Will always be set. - [size](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L165): @@ -180,6 +222,8 @@ sent to the server will be populated as follows: - context_extensions, metadata_context, route_metadata_context, tls_session: Will *not* be set. +### Handling the ext_authz Response + We will handle the [`CheckResponse`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L117) as follows: - [status](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L124): @@ -196,18 +240,16 @@ as follows: - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L75), [headers_to_remove](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L92), [response_headers_to_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L104): - See [header rewriting](#header-rewriting) below for details. + gRPC will not support rewriting the `:scheme`, `:method`, `:path`, + `:authority`, or `host` headers, regardless of what settings are present + in the filter's config. If the server specifies a rewrite for one of + these headers, that rewrite will be ignored. Otherwise, header + rewriting will be allowed based on the `decoder_header_mutation_rules` + config field. - query_parameters_to_set, query_parameters_to_remove: Ignored; these do not apply to gRPC. - dynamic_metadata: Ignored. -### Header Rewriting - -gRPC will not support rewriting the `:scheme`, `:method`, `:path`, -`:authority`, or `host` headers, regardless of what settings are present -in the ext_authz filter config. If the server specifies a rewrite for -one of these headers, that rewrite will be ignored. - ### Temporary environment variable protection Support for the `ext_authz` filter will be guarded by the From 3136b18ea3a5c1280c2a280278b7331d6ee824b6 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 12 Sep 2025 20:05:26 +0000 Subject: [PATCH 19/26] trace propagation --- A92-xds-ext-authz.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index df6090ed2..bae5b6e64 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-09-10 +* Last updated: 2025-09-12 * Discussion at: (filled after thread exists) ## Abstract @@ -153,7 +153,10 @@ rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md) Otherwise, the RPC will be passed to the next filter without modification. If the filter is enabled for the RPC, it will then send an RPC to the -ext_authz service to determine if the RPC should be allowed. +ext_authz service to determine if the RPC should be allowed. The filter +will pass the trace context from the data plane RPC to the ext_authz +RPC, so that the ext_authz RPC appears as a child span on the data plane +RPC's trace. If the RPC to the ext_authz service fails, then if the `failure_mode_allow` config field is set to false, the data plane RPC From caea5ff0dea1b3e6584be064ef329fd695ce98ba Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 12 Sep 2025 20:10:08 +0000 Subject: [PATCH 20/26] reorganize a bit --- A92-xds-ext-authz.md | 85 +++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 36 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index bae5b6e64..56bf114a9 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -40,8 +40,51 @@ the bootstrap config, described in [A102]. It will also make use of the ## Proposal +We will support the ext_authz filter on both the gRPC client and server +side. + +### Filter Behavior + +TODO: ExtAuthz channel retention (simple approach for now, probably +globally shared channel is fine?) + +On both the gRPC client and server side, the ext_authz filter will perform +the per-RPC authorization check when it sees the client's initial metadata +(i.e., at the start of the stream). + +If the `filter_enabled` config field is set to a value less than +100%, the filter will generate a random number in the range [0, +100] for the RPC, and if that random number is greater than or +equal to the configured `filter_enabled` value, then the ext_authz +filter is not considered enabled for that RPC. In that case, if +the `deny_at_disable` config field is set to true, then the RPC +will be failed with the status derived from the `status_on_error` +config field, using the normal [HTTP-to-gRPC status conversion +rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). +Otherwise, the RPC will be passed to the next filter without modification. + +If the filter is enabled for the RPC, it will then send an RPC to the +ext_authz service to determine if the RPC should be allowed. The filter +will pass the trace context from the data plane RPC to the ext_authz +RPC, so that the ext_authz RPC appears as a child span on the data plane +RPC's trace. + +If the RPC to the ext_authz service fails, then if the +`failure_mode_allow` config field is set to false, the data plane RPC +will be failed with the status derived from the `status_on_error` +config field, using the normal [HTTP-to-gRPC status conversion +rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). +Otherwise, the data plane RPC will be allowed. If the +`failure_mode_allow_header_add` config field is true, then the filter +will add a `x-envoy-auth-failure-mode-allowed: true` header to the data +plane RPC. + ### Filter Configuration +The filter supports both a top-level configuration and an override config. + +#### Top-Level Configuration + We will support the following fields in the [`ExtAuthz` proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L34): - [grpc_service](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L45): @@ -106,7 +149,7 @@ The following fields will be ignored by gRPC: we could consider adding it in the future if we do encounter such a use-case. -### Filter Configuration Overrides +#### Override Configuration We will support `typed_per_filter_config` config overrides for this filter, as described in [A39]. @@ -132,41 +175,9 @@ example, if there is an override config at the virtual host level that disables the filter but then another config at the route level that does not disable the filter, the filter will be enabled. -### Filter Behavior - -TODO: ExtAuthz channel retention (simple approach for now, probably -globally shared channel is fine?) +### The ext_authz Protocol -On both the gRPC client and server side, the ext_authz filter will perform -the per-RPC authorization check when it sees the client's initial metadata -(i.e., at the start of the stream). - -If the `filter_enabled` config field is set to a value less than -100%, the filter will generate a random number in the range [0, -100] for the RPC, and if that random number is greater than or -equal to the configured `filter_enabled` value, then the ext_authz -filter is not considered enabled for that RPC. In that case, if -the `deny_at_disable` config field is set to true, then the RPC -will be failed with the status derived from the `status_on_error` -config field, using the normal [HTTP-to-gRPC status conversion -rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). -Otherwise, the RPC will be passed to the next filter without modification. - -If the filter is enabled for the RPC, it will then send an RPC to the -ext_authz service to determine if the RPC should be allowed. The filter -will pass the trace context from the data plane RPC to the ext_authz -RPC, so that the ext_authz RPC appears as a child span on the data plane -RPC's trace. - -If the RPC to the ext_authz service fails, then if the -`failure_mode_allow` config field is set to false, the data plane RPC -will be failed with the status derived from the `status_on_error` -config field, using the normal [HTTP-to-gRPC status conversion -rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). -Otherwise, the data plane RPC will be allowed. If the -`failure_mode_allow_header_add` config field is true, then the filter -will add a `x-envoy-auth-failure-mode-allowed: true` header to the data -plane RPC. +This section describes the ext_authz protocol. #### Constructing the ext_authz Request @@ -225,7 +236,7 @@ sent to the server will be populated as follows: - context_extensions, metadata_context, route_metadata_context, tls_session: Will *not* be set. -### Handling the ext_authz Response +#### Handling the ext_authz Response We will handle the [`CheckResponse`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L117) as follows: @@ -255,6 +266,8 @@ as follows: ### Temporary environment variable protection +TODO: do we need a separate env var for client and server sides? + Support for the `ext_authz` filter will be guarded by the `GRPC_EXPERIMENTAL_XDS_EXT_AUTHZ` environment variable. This guard will be removed once the feature passes interop tests. From 86b3fd60754f5f3049165f8457ad8e4610650b8b Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Tue, 16 Sep 2025 17:55:57 +0000 Subject: [PATCH 21/26] add metrics --- A92-xds-ext-authz.md | 48 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 56bf114a9..6fea3a92d 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-09-12 +* Last updated: 2025-09-16 * Discussion at: (filled after thread exists) ## Abstract @@ -31,12 +31,20 @@ the bootstrap config, described in [A102]. It will also make use of the * [A81: xDS Authority Rewriting][A81] * [A33: xDS Fault Injection][A33] * [A102: xDS GrpcService Support][A102] (pending) +* [A60: xDS-Based Stateful Session Affinity for Weighted Clusters][A60] +* [A79: Non-Per-Call Metrics Architecture][A79] +* [A66: OpenTelemetry Metrics][A66] +* [A89: Backend Service Metric Label][A89] [A36]: A36-xds-for-servers.md [A39]: A39-xds-http-filters.md [A81]: A81-xds-authority-rewriting.md [A33]: A33-Fault-Injection.md [A102]: https://github.com/grpc/proposal/pull/510 +[A60]: A60-xds-stateful-session-affinity-weighted-clusters.md +[A79]: A79-non-per-call-metrics-architecture.md +[A89]: A89-backend-service-metric-label.md +[A66]: A66-otel-stats.md ## Proposal @@ -264,6 +272,44 @@ as follows: do not apply to gRPC. - dynamic_metadata: Ignored. +### Metrics + +The ext_authz filter will export metrics using the non-per-call metrics +architecture defined in [A79]. There will be a separate set of metrics +on client side and server side, because (a) there are additional labels +that are relevant on the client but not on the server, and (b) it may be +useful to differentiate between authorization behavior on the client vs. +the server. + +#### Client-Side Metrics + +The client-side metrics will have the following labels: + +| Name | Disposition | Description | +| ----------- | ----------- | ----------- | +| grpc.target | required | The target of the gRPC channel in which ext_authz is used, as the defined in [A66]. | +| grpc.lb.backend_service | optional | The backend service to which the traffic is being sent, as defined in [A89]. This will be populated from the xDS cluster name, which will be passed to the ext_authz filter as described in [A60]. | + +The following client-side metrics will be exported: + +| Name | Type | Unit | Labels | Description | +| ------------- | ----- | ----- | ------- | ----------- | +| grpc.client_ext_authz.allowed_rpcs | Counter | {RPCs} | grpc.target, grpc.lb.backend_service | Number of RPCs that were allowed by the ext_authz server. | +| grpc.client_ext_authz.denied_rpcs | Counter | {RPCs} | grpc.target, grpc.lb.backend_service | Number of RPCs that were denied by the ext_authz server. | +| grpc.client_ext_authz.filter_disabled_rpcs | Counter | {RPCs} | grpc.target, grpc.lb.backend_service | Number of RPCs for which the filter was disabled. | +| grpc.client_ext_authz.failed_rpcs | Counter | {RPCs} | grpc.target, grpc.lb.backend_service | Number of RPCs for which the ext_authz call-out failed. | + +#### Server-Side Metrics + +The following server-side metrics will be exported: + +| Name | Type | Unit | Labels | Description | +| ------------- | ----- | ----- | ------- | ----------- | +| grpc.server_ext_authz.allowed_rpcs | Counter | {RPCs} | | Number of RPCs that were allowed by the ext_authz server. | +| grpc.server_ext_authz.denied_rpcs | Counter | {RPCs} | | Number of RPCs that were denied by the ext_authz server. | +| grpc.server_ext_authz.filter_disabled_rpcs | Counter | {RPCs} | | Number of RPCs for which the filter was disabled. | +| grpc.server_ext_authz.failed_rpcs | Counter | {RPCs} | | Number of RPCs for which the ext_authz call-out failed. | + ### Temporary environment variable protection TODO: do we need a separate env var for client and server sides? From 6b53080b95084797a15f715ad5f8c97beb6148e0 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Wed, 17 Sep 2025 19:51:27 +0000 Subject: [PATCH 22/26] address some TODOs --- A92-xds-ext-authz.md | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 6fea3a92d..6a0f3790b 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-09-16 +* Last updated: 2025-09-17 * Discussion at: (filled after thread exists) ## Abstract @@ -29,6 +29,7 @@ the bootstrap config, described in [A102]. It will also make use of the * [A39: xDS HTTP Filter Support][A39] * [A36: xDS-Enabled Servers][A36] * [A81: xDS Authority Rewriting][A81] +* [A83: xDS GCP Authentication Filter][A83] * [A33: xDS Fault Injection][A33] * [A102: xDS GrpcService Support][A102] (pending) * [A60: xDS-Based Stateful Session Affinity for Weighted Clusters][A60] @@ -39,6 +40,7 @@ the bootstrap config, described in [A102]. It will also make use of the [A36]: A36-xds-for-servers.md [A39]: A39-xds-http-filters.md [A81]: A81-xds-authority-rewriting.md +[A83]: A83-xds-gcp-authn-filter.md [A33]: A33-Fault-Injection.md [A102]: https://github.com/grpc/proposal/pull/510 [A60]: A60-xds-stateful-session-affinity-weighted-clusters.md @@ -53,9 +55,6 @@ side. ### Filter Behavior -TODO: ExtAuthz channel retention (simple approach for now, probably -globally shared channel is fine?) - On both the gRPC client and server side, the ext_authz filter will perform the per-RPC authorization check when it sees the client's initial metadata (i.e., at the start of the stream). @@ -87,6 +86,19 @@ Otherwise, the data plane RPC will be allowed. If the will add a `x-envoy-auth-failure-mode-allowed: true` header to the data plane RPC. +#### ExtAuthz Side Channel + +The ext_authz filter will create a gRPC channel to the ext_authz server. +It will use the mechanism described in [A102] to determine the server to +talk to and the channel credentials to use. + +We do not want to recreate this channel on LDS updates, unless the +target URI or channel credentials changes. The ext_authz filter will +use the filter state retention mechanism described in [A83] to retain +the channel across updates. + +TODO: stats plugin propagation? + ### Filter Configuration The filter supports both a top-level configuration and an override config. @@ -192,8 +204,8 @@ This section describes the ext_authz protocol. The [`AttributeContext` message](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L43) sent to the server will be populated as follows: -- [source](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L192): Will always be set. Inside it: - - TODO: will this be set on client side? +- [source](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L192): + Will be set only on gRPC server side. Inside it: - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) will be set to the peer address of the connection that the request came in on. @@ -208,8 +220,7 @@ sent to the server will be populated as follows: field is set to true. - service, labels: Will *not* be set. - [destination](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L197): - Will always be set. Inside it: - - TODO: will this be set on client side? + Will be set only on gRPC server side. Inside it: - [address](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/attribute_context.proto#L58) will be set to the local address of the connection that the request came in on. From 838c7fa294bb16adb4709cd645f9a74682aa59ba Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 18 Sep 2025 22:57:44 +0000 Subject: [PATCH 23/26] add mailing list link --- A92-xds-ext-authz.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 6a0f3790b..bd1d11abb 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -5,7 +5,7 @@ A92: xDS ExtAuthz Support * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: * Last updated: 2025-09-17 -* Discussion at: (filled after thread exists) +* Discussion at: https://groups.google.com/g/grpc-io/c/sPfb9NoB474 ## Abstract From e4893d835debdc3f9c10471351d390cf8f286d41 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 10 Oct 2025 19:17:18 +0000 Subject: [PATCH 24/26] fleshed out details on header rewriting --- A92-xds-ext-authz.md | 67 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 13 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index bd1d11abb..295fa0d44 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -4,7 +4,7 @@ A92: xDS ExtAuthz Support * Approver: @ejona86, @dfawley * Status: {Draft, In Review, Ready for Implementation, Implemented} * Implemented in: -* Last updated: 2025-09-17 +* Last updated: 2025-10-10 * Discussion at: https://groups.google.com/g/grpc-io/c/sPfb9NoB474 ## Abstract @@ -267,22 +267,63 @@ as follows: The HTTP status to fail the RPC with. We apply the normal [HTTP-to-gRPC status conversion rules](https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md). - - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55) + - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55): + In gRPC, failing an RPC involves sending a Trailers-Only response, + so this field will be used to modify trailers on the data plane RPC + rather than response headers. See [Header Rewriting](#header-rewriting) + below. - body: Ignored; does not apply to gRPC. - [ok_response](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L134): - - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L75), - [headers_to_remove](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L92), - [response_headers_to_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L104): - gRPC will not support rewriting the `:scheme`, `:method`, `:path`, - `:authority`, or `host` headers, regardless of what settings are present - in the filter's config. If the server specifies a rewrite for one of - these headers, that rewrite will be ignored. Otherwise, header - rewriting will be allowed based on the `decoder_header_mutation_rules` - config field. - - query_parameters_to_set, query_parameters_to_remove: Ignored; these - do not apply to gRPC. + - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L75) + and + [headers_to_remove](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L92): + Modifications to the data plane RPC's request headers. See + [Header Rewriting](#header-rewriting) below. + - [response_headers_to_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L104): + Modifications to the data plane RPC's response headers. See + [Header Rewriting](#header-rewriting) below. + - query_parameters_to_set, query_parameters_to_remove, dynamic_metadata: + Ignored; these do not apply to gRPC. - dynamic_metadata: Ignored. +##### Header Rewriting + +The response from the ext_authz server may indicate header modifications +to make on the data plane RPC. When the data plane RPC is allowed, +modifications may be made to the data plane RPC's request headers or +response headers. And when the data plane RPC is denied, modifications +may be made to the response trailers as part of a Trailers-Only response. + +gRPC will not support modifying or removing any header name starting with +`:` or the `host` header, regardless of what settings are present in +the filter's config. If the server specifies a rewrite for one of these +headers, that rewrite will be ignored. Otherwise, header rewriting will +be allowed based on the `decoder_header_mutation_rules` config field. + +Header additions and modifications are expressed via an +[`envoy.config.core.v3.HeaderValueOption`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L429) +message, which is not specific to the ext_authz filter and will be used +in other places in the future. We will validate this message as follows: +- [header](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L458): + Required. Within it: + - [key](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L404): + The header name. Must be non-empty and all lower-case. Length + must not exceed 16384. The entry will be ignored if the key is + `host` or starts with a `:`. + - [value](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L415): + The header value, used when the header name does not end with `-bin`. + Length must not exceed 16384. + - [raw_value](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L422): + The header value, used when the header name ends with `-bin`. Length + must not exceed 16384. +- [append_action](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L476): + We honor the 4 enum values as described in the proto file. +- [keep_empty_value](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L480): + By default, any header mutation that results in a header with an + empty value will cause the header key to be removed. If this field + is set to true, then such empty headers will be kept. +- We do not support the deprecated append field. + ### Metrics The ext_authz filter will export metrics using the non-per-call metrics From 90b0eedaf350c644ed03c021494ff382b49a2479 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 10 Oct 2025 23:42:45 +0000 Subject: [PATCH 25/26] more detail on header mutations --- A92-xds-ext-authz.md | 69 ++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index 295fa0d44..b4259adbf 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -134,13 +134,7 @@ proto](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4f - [allowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L229) - [disallowed_headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L233) - [decoder_header_mutation_rules](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L282): - Optional. Inside of it: - - [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70) - - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75) - - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79) - - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87) - - allow_all_routing, disallow_system, allow_envoy: These fields will - be ignored. + Optional. See [Header Mutations](#header-mutations) below for details. - [include_peer_certificate](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/extensions/filters/http/ext_authz/v3/ext_authz.proto#L181) The following fields will be ignored by gRPC: @@ -270,7 +264,7 @@ as follows: - [headers](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L55): In gRPC, failing an RPC involves sending a Trailers-Only response, so this field will be used to modify trailers on the data plane RPC - rather than response headers. See [Header Rewriting](#header-rewriting) + rather than response headers. See [Header Mutations](#header-mutations) below. - body: Ignored; does not apply to gRPC. - [ok_response](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L134): @@ -278,32 +272,49 @@ as follows: and [headers_to_remove](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L92): Modifications to the data plane RPC's request headers. See - [Header Rewriting](#header-rewriting) below. + [Header Mutations](#header-mutations) below. - [response_headers_to_add](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/service/auth/v3/external_auth.proto#L104): Modifications to the data plane RPC's response headers. See - [Header Rewriting](#header-rewriting) below. + [Header Mutations](#header-mutations) below. - query_parameters_to_set, query_parameters_to_remove, dynamic_metadata: Ignored; these do not apply to gRPC. - dynamic_metadata: Ignored. -##### Header Rewriting - -The response from the ext_authz server may indicate header modifications -to make on the data plane RPC. When the data plane RPC is allowed, -modifications may be made to the data plane RPC's request headers or -response headers. And when the data plane RPC is denied, modifications -may be made to the response trailers as part of a Trailers-Only response. - -gRPC will not support modifying or removing any header name starting with -`:` or the `host` header, regardless of what settings are present in -the filter's config. If the server specifies a rewrite for one of these -headers, that rewrite will be ignored. Otherwise, header rewriting will -be allowed based on the `decoder_header_mutation_rules` config field. +##### Header Mutations + +The response from the ext_authz server may indicate header mutations +(additions, modifications, or removals) to make on the data plane RPC. +When the data plane RPC is allowed, mutations may be made to the data +plane RPC's request headers or response headers. And when the data +plane RPC is denied, mutations may be made to the response trailers as +part of a Trailers-Only response. + +The `decoder_header_mutation_rules` config field controls which header +mutations are allowed. This field is an +[`envoy.config.common.mutation_rules.v3.HeaderMutationRules`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L47C9-L47C28) +message, which will be used as follows: +- [disallow_all](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L70): + If true, all header mutations are disallowed, regardless of any other + setting. +- [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79): + Optional. If a header name matches this regex, then it will be disallowed, + regardless of any other setting. +- [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75): + Optional. If a header name matches this regex and does not match + `disallow_expression`, it will be allowed. If unset, then all headers + not matching `disallow_expression` are allowed. +- [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87): + If false, a disallowed header mutation will simply be ignored. If + true, the data plane RPC will be failed. +- allow_all_routing, disallow_system: These fields are ignored. gRPC + will never allow modifications to headers starting with `:` or to the + `host` header, regardless of what these fields are set to. +- allow_envoy: This field will be ignored, since `x-envoy-*` headers are + not generally meaningful to gRPC. Header additions and modifications are expressed via an [`envoy.config.core.v3.HeaderValueOption`](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L429) -message, which is not specific to the ext_authz filter and will be used -in other places in the future. We will validate this message as follows: +message, which will be used as follows: - [header](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L458): Required. Within it: - [key](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/core/v3/base.proto#L404): @@ -324,6 +335,14 @@ in other places in the future. We will validate this message as follows: is set to true, then such empty headers will be kept. - We do not support the deprecated append field. +Header removals are encoded separately from additions and modifications +but are still subject to the mutation rules in the filter's config. + +Note that use of these xDS messages and the underlying header mutation +functionality is not specific to the ext_authz filter and will be +used in other places in the future, so they should be implemented in a +reusable way. + ### Metrics The ext_authz filter will export metrics using the non-per-call metrics From 4b4d49e9de26c7927382daf0e5ff5dea5498f482 Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Fri, 10 Oct 2025 23:55:44 +0000 Subject: [PATCH 26/26] check regexes as part of resource validation --- A92-xds-ext-authz.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/A92-xds-ext-authz.md b/A92-xds-ext-authz.md index b4259adbf..97968af04 100644 --- a/A92-xds-ext-authz.md +++ b/A92-xds-ext-authz.md @@ -298,11 +298,13 @@ message, which will be used as follows: setting. - [disallow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L79): Optional. If a header name matches this regex, then it will be disallowed, - regardless of any other setting. + regardless of any other setting. Note that regexes should be checked for + validity as part of resource validation. - [allow_expression](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L75): Optional. If a header name matches this regex and does not match `disallow_expression`, it will be allowed. If unset, then all headers - not matching `disallow_expression` are allowed. + not matching `disallow_expression` are allowed. Note that regexes + should be checked for validity as part of resource validation. - [disallow_is_error](https://github.com/envoyproxy/envoy/blob/cdd19052348f7f6d85910605d957ba4fe0538aec/api/envoy/config/common/mutation_rules/v3/mutation_rules.proto#L87): If false, a disallowed header mutation will simply be ignored. If true, the data plane RPC will be failed.