RBAC filters allow or deny traffic based on declarative policies — no external calls, no policy language. Network RBAC runs when a connection is accepted; HTTP RBAC runs per request inside the HTTP connection manager. Use them for IP allowlists, port and SNI restrictions, and header- or path-based rules.
How policies decide
Both filters share one shape: an action (ALLOW or DENY) and named policies. A policy matches when any of its permissions and any of its principals match. Policies are checked in the lexicographical order of their names; with ALLOW, traffic passes only if some policy matches, with DENY it passes only if none does. A denied request gets 403 with body RBAC: access denied; a denied connection is closed.
Network RBAC
List envoy.filters.network.rbac in a filter chain's filters, before the HTTP connection manager or TCP proxy. Several RBAC filters may be stacked; each must permit the connection.
filters:
- name: envoy.filters.network.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
rules:
action: ALLOW
policies:
internal-only:
permissions:
- any: true
principals:
- direct_remote_ip: { address_prefix: 10.0.0.0, prefix_len: 8 }
- name: https_gateway
# http_connection_manager ...
Supported permission kinds: any, destination_ip, destination_port, destination_port_range, requested_server_name (a string matcher against the SNI — add the TLS inspector listener filter so it is available). Supported principal kind besides any: direct_remote_ip (the peer address of the accepted connection).
HTTP RBAC
Add envoy.filters.http.rbac to http_filters, before the router.
http_filters:
- name: envoy.filters.http.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: DENY
policies:
no-admin:
permissions:
- header:
name: ":path"
string_match: { prefix: /admin }
principals:
- any: true
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
At the HTTP level both permissions and principals support exactly two kinds: any and header. That is less restrictive than it sounds — header matchers also target the :method, :path and :scheme pseudo-headers, and support exact, prefix, suffix, contains and safe_regex patterns (plus present_match, invert_match, ignore_case and treat_missing_header_as_empty). A "principal" is therefore anything a header can express, such as a claim_to_headers value stamped by JWT authentication.
Per-route override
A route can replace the HTTP RBAC policy or switch the filter off. The key under typed_per_filter_config must equal the filter's name in http_filters:
routes:
- match: { prefix: /public }
route: { cluster: api }
typed_per_filter_config:
envoy.filters.http.rbac:
"@type": type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
# empty: no RBAC on this route; add `rbac: { rules: ... }` to replace the policyVerify
curl -i http://127.0.0.1:8080/admin/users
Expected: HTTP/1.1 403 Forbidden with body RBAC: access denied. With debug logging enabled, the log names the policy that enforced the decision.
Limits
- Shadow rules (
shadow_rules,shadow_matcher) and the newer matcher API are not supported; neither are CEL conditions on policies. - The
LOGaction is not supported — onlyALLOWandDENY. - Principal kinds beyond the ones listed (for example
authenticatedmTLS identities,remote_ipbehind a proxy,url_path, metadata) are refused at startup. - Network RBAC ignores
stat_prefix(with a warning) and does not supportenforcement_typeordelay_deny. - For identity-aware rules richer than header matching, use Cedar policies.