...
1syntax = "proto3";
2
3package envoy.config.rbac.v3;
4
5import "envoy/config/core/v3/address.proto";
6import "envoy/config/route/v3/route_components.proto";
7import "envoy/type/matcher/v3/metadata.proto";
8import "envoy/type/matcher/v3/path.proto";
9import "envoy/type/matcher/v3/string.proto";
10
11import "google/api/expr/v1alpha1/checked.proto";
12import "google/api/expr/v1alpha1/syntax.proto";
13
14import "udpa/annotations/migrate.proto";
15import "udpa/annotations/status.proto";
16import "udpa/annotations/versioning.proto";
17import "validate/validate.proto";
18
19option java_package = "io.envoyproxy.envoy.config.rbac.v3";
20option java_outer_classname = "RbacProto";
21option java_multiple_files = true;
22option (udpa.annotations.file_status).package_version_status = ACTIVE;
23
24// [#protodoc-title: Role Based Access Control (RBAC)]
25
26// Role Based Access Control (RBAC) provides service-level and method-level access control for a
27// service. RBAC policies are additive. The policies are examined in order. Requests are allowed
28// or denied based on the `action` and whether a matching policy is found. For instance, if the
29// action is ALLOW and a matching policy is found the request should be allowed.
30//
31// RBAC can also be used to make access logging decisions by communicating with access loggers
32// through dynamic metadata. When the action is LOG and at least one policy matches, the
33// `access_log_hint` value in the shared key namespace 'envoy.common' is set to `true` indicating
34// the request should be logged.
35//
36// Here is an example of RBAC configuration. It has two policies:
37//
38// * Service account "cluster.local/ns/default/sa/admin" has full access to the service, and so
39// does "cluster.local/ns/default/sa/superuser".
40//
41// * Any user can read ("GET") the service at paths with prefix "/products", so long as the
42// destination port is either 80 or 443.
43//
44// .. code-block:: yaml
45//
46// action: ALLOW
47// policies:
48// "service-admin":
49// permissions:
50// - any: true
51// principals:
52// - authenticated:
53// principal_name:
54// exact: "cluster.local/ns/default/sa/admin"
55// - authenticated:
56// principal_name:
57// exact: "cluster.local/ns/default/sa/superuser"
58// "product-viewer":
59// permissions:
60// - and_rules:
61// rules:
62// - header: { name: ":method", exact_match: "GET" }
63// - url_path:
64// path: { prefix: "/products" }
65// - or_rules:
66// rules:
67// - destination_port: 80
68// - destination_port: 443
69// principals:
70// - any: true
71//
72message RBAC {
73 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.RBAC";
74
75 // Should we do safe-list or block-list style access control?
76 enum Action {
77 // The policies grant access to principals. The rest are denied. This is safe-list style
78 // access control. This is the default type.
79 ALLOW = 0;
80
81 // The policies deny access to principals. The rest are allowed. This is block-list style
82 // access control.
83 DENY = 1;
84
85 // The policies set the `access_log_hint` dynamic metadata key based on if requests match.
86 // All requests are allowed.
87 LOG = 2;
88 }
89
90 // The action to take if a policy matches. Every action either allows or denies a request,
91 // and can also carry out action-specific operations.
92 //
93 // Actions:
94 //
95 // * ALLOW: Allows the request if and only if there is a policy that matches
96 // the request.
97 // * DENY: Allows the request if and only if there are no policies that
98 // match the request.
99 // * LOG: Allows all requests. If at least one policy matches, the dynamic
100 // metadata key `access_log_hint` is set to the value `true` under the shared
101 // key namespace 'envoy.common'. If no policies match, it is set to `false`.
102 // Other actions do not modify this key.
103 //
104 Action action = 1 [(validate.rules).enum = {defined_only: true}];
105
106 // Maps from policy name to policy. A match occurs when at least one policy matches the request.
107 map<string, Policy> policies = 2;
108}
109
110// Policy specifies a role and the principals that are assigned/denied the role.
111// A policy matches if and only if at least one of its permissions match the
112// action taking place AND at least one of its principals match the downstream
113// AND the condition is true if specified.
114message Policy {
115 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Policy";
116
117 // Required. The set of permissions that define a role. Each permission is
118 // matched with OR semantics. To match all actions for this policy, a single
119 // Permission with the `any` field set to true should be used.
120 repeated Permission permissions = 1 [(validate.rules).repeated = {min_items: 1}];
121
122 // Required. The set of principals that are assigned/denied the role based on
123 // “action”. Each principal is matched with OR semantics. To match all
124 // downstreams for this policy, a single Principal with the `any` field set to
125 // true should be used.
126 repeated Principal principals = 2 [(validate.rules).repeated = {min_items: 1}];
127
128 // An optional symbolic expression specifying an access control
129 // :ref:`condition <arch_overview_condition>`. The condition is combined
130 // with the permissions and the principals as a clause with AND semantics.
131 // Only be used when checked_condition is not used.
132 google.api.expr.v1alpha1.Expr condition = 3
133 [(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"];
134
135 // [#not-implemented-hide:]
136 // An optional symbolic expression that has been successfully type checked.
137 // Only be used when condition is not used.
138 google.api.expr.v1alpha1.CheckedExpr checked_condition = 4
139 [(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"];
140}
141
142// Permission defines an action (or actions) that a principal can take.
143// [#next-free-field: 11]
144message Permission {
145 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission";
146
147 // Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context,
148 // each are applied with the associated behavior.
149 message Set {
150 option (udpa.annotations.versioning).previous_message_type =
151 "envoy.config.rbac.v2.Permission.Set";
152
153 repeated Permission rules = 1 [(validate.rules).repeated = {min_items: 1}];
154 }
155
156 oneof rule {
157 option (validate.required) = true;
158
159 // A set of rules that all must match in order to define the action.
160 Set and_rules = 1;
161
162 // A set of rules where at least one must match in order to define the action.
163 Set or_rules = 2;
164
165 // When any is set, it matches any action.
166 bool any = 3 [(validate.rules).bool = {const: true}];
167
168 // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only
169 // available for HTTP request.
170 // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path`
171 // field if you want to match the URL path without the query and fragment string.
172 route.v3.HeaderMatcher header = 4;
173
174 // A URL path on the incoming HTTP request. Only available for HTTP.
175 type.matcher.v3.PathMatcher url_path = 10;
176
177 // A CIDR block that describes the destination IP.
178 core.v3.CidrRange destination_ip = 5;
179
180 // A port number that describes the destination port connecting to.
181 uint32 destination_port = 6 [(validate.rules).uint32 = {lte: 65535}];
182
183 // Metadata that describes additional information about the action.
184 type.matcher.v3.MetadataMatcher metadata = 7;
185
186 // Negates matching the provided permission. For instance, if the value of
187 // `not_rule` would match, this permission would not match. Conversely, if
188 // the value of `not_rule` would not match, this permission would match.
189 Permission not_rule = 8;
190
191 // The request server from the client's connection request. This is
192 // typically TLS SNI.
193 //
194 // .. attention::
195 //
196 // The behavior of this field may be affected by how Envoy is configured
197 // as explained below.
198 //
199 // * If the :ref:`TLS Inspector <config_listener_filters_tls_inspector>`
200 // filter is not added, and if a `FilterChainMatch` is not defined for
201 // the :ref:`server name
202 // <envoy_api_field_config.listener.v3.FilterChainMatch.server_names>`,
203 // a TLS connection's requested SNI server name will be treated as if it
204 // wasn't present.
205 //
206 // * A :ref:`listener filter <arch_overview_listener_filters>` may
207 // overwrite a connection's requested server name within Envoy.
208 //
209 // Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn to
210 // setup SNI.
211 type.matcher.v3.StringMatcher requested_server_name = 9;
212 }
213}
214
215// Principal defines an identity or a group of identities for a downstream
216// subject.
217// [#next-free-field: 12]
218message Principal {
219 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal";
220
221 // Used in the `and_ids` and `or_ids` fields in the `identifier` oneof.
222 // Depending on the context, each are applied with the associated behavior.
223 message Set {
224 option (udpa.annotations.versioning).previous_message_type =
225 "envoy.config.rbac.v2.Principal.Set";
226
227 repeated Principal ids = 1 [(validate.rules).repeated = {min_items: 1}];
228 }
229
230 // Authentication attributes for a downstream.
231 message Authenticated {
232 option (udpa.annotations.versioning).previous_message_type =
233 "envoy.config.rbac.v2.Principal.Authenticated";
234
235 reserved 1;
236
237 // The name of the principal. If set, The URI SAN or DNS SAN in that order
238 // is used from the certificate, otherwise the subject field is used. If
239 // unset, it applies to any user that is authenticated.
240 type.matcher.v3.StringMatcher principal_name = 2;
241 }
242
243 oneof identifier {
244 option (validate.required) = true;
245
246 // A set of identifiers that all must match in order to define the
247 // downstream.
248 Set and_ids = 1;
249
250 // A set of identifiers at least one must match in order to define the
251 // downstream.
252 Set or_ids = 2;
253
254 // When any is set, it matches any downstream.
255 bool any = 3 [(validate.rules).bool = {const: true}];
256
257 // Authenticated attributes that identify the downstream.
258 Authenticated authenticated = 4;
259
260 // A CIDR block that describes the downstream IP.
261 // This address will honor proxy protocol, but will not honor XFF.
262 core.v3.CidrRange source_ip = 5 [deprecated = true];
263
264 // A CIDR block that describes the downstream remote/origin address.
265 // Note: This is always the physical peer even if the
266 // :ref:`remote_ip <envoy_api_field_config.rbac.v3.Principal.remote_ip>` is
267 // inferred from for example the x-forwarder-for header, proxy protocol,
268 // etc.
269 core.v3.CidrRange direct_remote_ip = 10;
270
271 // A CIDR block that describes the downstream remote/origin address.
272 // Note: This may not be the physical peer and could be different from the
273 // :ref:`direct_remote_ip
274 // <envoy_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the
275 // remote ip is inferred from for example the x-forwarder-for header, proxy
276 // protocol, etc.
277 core.v3.CidrRange remote_ip = 11;
278
279 // A header (or pseudo-header such as :path or :method) on the incoming HTTP
280 // request. Only available for HTTP request. Note: the pseudo-header :path
281 // includes the query and fragment string. Use the `url_path` field if you
282 // want to match the URL path without the query and fragment string.
283 route.v3.HeaderMatcher header = 6;
284
285 // A URL path on the incoming HTTP request. Only available for HTTP.
286 type.matcher.v3.PathMatcher url_path = 9;
287
288 // Metadata that describes additional information about the principal.
289 type.matcher.v3.MetadataMatcher metadata = 7;
290
291 // Negates matching the provided principal. For instance, if the value of
292 // `not_id` would match, this principal would not match. Conversely, if the
293 // value of `not_id` would not match, this principal would match.
294 Principal not_id = 8;
295 }
296}
View as plain text