1// 2// Copyright 2021 gRPC authors. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17// Local copy of Envoy xDS proto file, used for testing only. 18 19syntax = "proto3"; 20 21package envoy.config.rbac.v3; 22 23import "src/proto/grpc/testing/xds/v3/address.proto"; 24import "src/proto/grpc/testing/xds/v3/extension.proto"; 25import "src/proto/grpc/testing/xds/v3/route.proto"; 26import "src/proto/grpc/testing/xds/v3/metadata.proto"; 27import "src/proto/grpc/testing/xds/v3/path.proto"; 28import "src/proto/grpc/testing/xds/v3/string.proto"; 29import "src/proto/grpc/testing/xds/v3/range.proto"; 30 31import "src/proto/grpc/testing/xds/v3/expr.proto"; 32 33// [#protodoc-title: Role Based Access Control (RBAC)] 34 35// Role Based Access Control (RBAC) provides service-level and method-level access control for a 36// service. Requests are allowed or denied based on the `action` and whether a matching policy is 37// found. For instance, if the action is ALLOW and a matching policy is found the request should be 38// allowed. 39// 40// RBAC can also be used to make access logging decisions by communicating with access loggers 41// through dynamic metadata. When the action is LOG and at least one policy matches, the 42// `access_log_hint` value in the shared key namespace 'envoy.common' is set to `true` indicating 43// the request should be logged. 44// 45// Here is an example of RBAC configuration. It has two policies: 46// 47// * Service account "cluster.local/ns/default/sa/admin" has full access to the service, and so 48// does "cluster.local/ns/default/sa/superuser". 49// 50// * Any user can read ("GET") the service at paths with prefix "/products", so long as the 51// destination port is either 80 or 443. 52// 53// .. code-block:: yaml 54// 55// action: ALLOW 56// policies: 57// "service-admin": 58// permissions: 59// - any: true 60// principals: 61// - authenticated: 62// principal_name: 63// exact: "cluster.local/ns/default/sa/admin" 64// - authenticated: 65// principal_name: 66// exact: "cluster.local/ns/default/sa/superuser" 67// "product-viewer": 68// permissions: 69// - and_rules: 70// rules: 71// - header: 72// name: ":method" 73// string_match: 74// exact: "GET" 75// - url_path: 76// path: { prefix: "/products" } 77// - or_rules: 78// rules: 79// - destination_port: 80 80// - destination_port: 443 81// principals: 82// - any: true 83// 84message RBAC { 85 // Should we do safe-list or block-list style access control? 86 enum Action { 87 // The policies grant access to principals. The rest are denied. This is safe-list style 88 // access control. This is the default type. 89 ALLOW = 0; 90 91 // The policies deny access to principals. The rest are allowed. This is block-list style 92 // access control. 93 DENY = 1; 94 95 // The policies set the `access_log_hint` dynamic metadata key based on if requests match. 96 // All requests are allowed. 97 LOG = 2; 98 } 99 100 message AuditLoggingOptions { 101 // Deny and allow here refer to RBAC decisions, not actions. 102 enum AuditCondition { 103 // Never audit. 104 NONE = 0; 105 106 // Audit when RBAC denies the request. 107 ON_DENY = 1; 108 109 // Audit when RBAC allows the request. 110 ON_ALLOW = 2; 111 112 // Audit whether RBAC allows or denies the request. 113 ON_DENY_AND_ALLOW = 3; 114 } 115 116 // [#not-implemented-hide:] 117 message AuditLoggerConfig { 118 // Typed logger configuration. 119 // 120 // [#extension-category: envoy.rbac.audit_loggers] 121 core.v3.TypedExtensionConfig audit_logger = 1; 122 123 // If true, when the logger is not supported, the data plane will not NACK but simply ignore it. 124 bool is_optional = 2; 125 } 126 127 // Condition for the audit logging to happen. 128 // If this condition is met, all the audit loggers configured here will be invoked. 129 // 130 // [#not-implemented-hide:] 131 AuditCondition audit_condition = 1; 132 133 // Configurations for RBAC-based authorization audit loggers. 134 // 135 // [#not-implemented-hide:] 136 repeated AuditLoggerConfig logger_configs = 2; 137 } 138 139 // The action to take if a policy matches. Every action either allows or denies a request, 140 // and can also carry out action-specific operations. 141 // 142 // Actions: 143 // 144 // * ALLOW: Allows the request if and only if there is a policy that matches 145 // the request. 146 // * DENY: Allows the request if and only if there are no policies that 147 // match the request. 148 // * LOG: Allows all requests. If at least one policy matches, the dynamic 149 // metadata key `access_log_hint` is set to the value `true` under the shared 150 // key namespace 'envoy.common'. If no policies match, it is set to `false`. 151 // Other actions do not modify this key. 152 // 153 Action action = 1; 154 155 // Maps from policy name to policy. A match occurs when at least one policy matches the request. 156 // The policies are evaluated in lexicographic order of the policy name. 157 map<string, Policy> policies = 2; 158 159 // Audit logging options that include the condition for audit logging to happen 160 // and audit logger configurations. 161 // 162 // [#not-implemented-hide:] 163 AuditLoggingOptions audit_logging_options = 3; 164} 165 166// Policy specifies a role and the principals that are assigned/denied the role. 167// A policy matches if and only if at least one of its permissions match the 168// action taking place AND at least one of its principals match the downstream 169// AND the condition is true if specified. 170message Policy { 171 // Required. The set of permissions that define a role. Each permission is 172 // matched with OR semantics. To match all actions for this policy, a single 173 // Permission with the `any` field set to true should be used. 174 repeated Permission permissions = 1; 175 176 // Required. The set of principals that are assigned/denied the role based on 177 // “action”. Each principal is matched with OR semantics. To match all 178 // downstreams for this policy, a single Principal with the `any` field set to 179 // true should be used. 180 repeated Principal principals = 2; 181 182 // An optional symbolic expression specifying an access control 183 // :ref:`condition <arch_overview_condition>`. The condition is combined 184 // with the permissions and the principals as a clause with AND semantics. 185 // Only be used when checked_condition is not used. 186 google.api.expr.v1alpha1.Expr condition = 3; 187 188 // [#not-implemented-hide:] 189 // An optional symbolic expression that has been successfully type checked. 190 // Only be used when condition is not used. 191 google.api.expr.v1alpha1.CheckedExpr checked_condition = 4; 192} 193 194// Permission defines an action (or actions) that a principal can take. 195// [#next-free-field: 13] 196message Permission { 197 // Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context, 198 // each are applied with the associated behavior. 199 message Set { 200 repeated Permission rules = 1; 201 } 202 203 oneof rule { 204 // A set of rules that all must match in order to define the action. 205 Set and_rules = 1; 206 207 // A set of rules where at least one must match in order to define the action. 208 Set or_rules = 2; 209 210 // When any is set, it matches any action. 211 bool any = 3; 212 213 // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only 214 // available for HTTP request. 215 // Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` 216 // field if you want to match the URL path without the query and fragment string. 217 route.v3.HeaderMatcher header = 4; 218 219 // A URL path on the incoming HTTP request. Only available for HTTP. 220 type.matcher.v3.PathMatcher url_path = 10; 221 222 // A CIDR block that describes the destination IP. 223 core.v3.CidrRange destination_ip = 5; 224 225 // A port number that describes the destination port connecting to. 226 uint32 destination_port = 6; 227 228 // A port number range that describes a range of destination ports connecting to. 229 type.v3.Int32Range destination_port_range = 11; 230 231 // Metadata that describes additional information about the action. 232 type.matcher.v3.MetadataMatcher metadata = 7; 233 234 // Negates matching the provided permission. For instance, if the value of 235 // `not_rule` would match, this permission would not match. Conversely, if 236 // the value of `not_rule` would not match, this permission would match. 237 Permission not_rule = 8; 238 239 // The request server from the client's connection request. This is 240 // typically TLS SNI. 241 // 242 // .. attention:: 243 // 244 // The behavior of this field may be affected by how Envoy is configured 245 // as explained below. 246 // 247 // * If the :ref:`TLS Inspector <config_listener_filters_tls_inspector>` 248 // filter is not added, and if a `FilterChainMatch` is not defined for 249 // the :ref:`server name 250 // <envoy_v3_api_field_config.listener.v3.FilterChainMatch.server_names>`, 251 // a TLS connection's requested SNI server name will be treated as if it 252 // wasn't present. 253 // 254 // * A :ref:`listener filter <arch_overview_listener_filters>` may 255 // overwrite a connection's requested server name within Envoy. 256 // 257 // Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn to 258 // setup SNI. 259 type.matcher.v3.StringMatcher requested_server_name = 9; 260 261 // Extension for configuring custom matchers for RBAC. 262 // [#extension-category: envoy.rbac.matchers] 263 core.v3.TypedExtensionConfig matcher = 12; 264 } 265} 266 267// Principal defines an identity or a group of identities for a downstream 268// subject. 269// [#next-free-field: 12] 270message Principal { 271 // Used in the `and_ids` and `or_ids` fields in the `identifier` oneof. 272 // Depending on the context, each are applied with the associated behavior. 273 message Set { 274 repeated Principal ids = 1; 275 } 276 277 // Authentication attributes for a downstream. 278 message Authenticated { 279 reserved 1; 280 281 // The name of the principal. If set, The URI SAN or DNS SAN in that order 282 // is used from the certificate, otherwise the subject field is used. If 283 // unset, it applies to any user that is authenticated. 284 type.matcher.v3.StringMatcher principal_name = 2; 285 } 286 287 oneof identifier { 288 // A set of identifiers that all must match in order to define the 289 // downstream. 290 Set and_ids = 1; 291 292 // A set of identifiers at least one must match in order to define the 293 // downstream. 294 Set or_ids = 2; 295 296 // When any is set, it matches any downstream. 297 bool any = 3; 298 299 // Authenticated attributes that identify the downstream. 300 Authenticated authenticated = 4; 301 302 // A CIDR block that describes the downstream IP. 303 // This address will honor proxy protocol, but will not honor XFF. 304 core.v3.CidrRange source_ip = 5; 305 306 // A CIDR block that describes the downstream remote/origin address. 307 // Note: This is always the physical peer even if the 308 // :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>` is 309 // inferred from for example the x-forwarder-for header, proxy protocol, 310 // etc. 311 core.v3.CidrRange direct_remote_ip = 10; 312 313 // A CIDR block that describes the downstream remote/origin address. 314 // Note: This may not be the physical peer and could be different from the 315 // :ref:`direct_remote_ip 316 // <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the 317 // remote ip is inferred from for example the x-forwarder-for header, proxy 318 // protocol, etc. 319 core.v3.CidrRange remote_ip = 11; 320 321 // A header (or pseudo-header such as :path or :method) on the incoming HTTP 322 // request. Only available for HTTP request. Note: the pseudo-header :path 323 // includes the query and fragment string. Use the `url_path` field if you 324 // want to match the URL path without the query and fragment string. 325 route.v3.HeaderMatcher header = 6; 326 327 // A URL path on the incoming HTTP request. Only available for HTTP. 328 type.matcher.v3.PathMatcher url_path = 9; 329 330 // Metadata that describes additional information about the principal. 331 type.matcher.v3.MetadataMatcher metadata = 7; 332 333 // Negates matching the provided principal. For instance, if the value of 334 // `not_id` would match, this principal would not match. Conversely, if the 335 // value of `not_id` would not match, this principal would match. 336 Principal not_id = 8; 337 } 338} 339