1syntax = "proto3"; 2 3package envoy.config.rbac.v3; 4 5import "envoy/config/core/v3/address.proto"; 6import "envoy/config/core/v3/extension.proto"; 7import "envoy/config/route/v3/route_components.proto"; 8import "envoy/type/matcher/v3/filter_state.proto"; 9import "envoy/type/matcher/v3/metadata.proto"; 10import "envoy/type/matcher/v3/path.proto"; 11import "envoy/type/matcher/v3/string.proto"; 12import "envoy/type/v3/range.proto"; 13 14import "google/api/expr/v1alpha1/checked.proto"; 15import "google/api/expr/v1alpha1/syntax.proto"; 16 17import "envoy/annotations/deprecation.proto"; 18import "udpa/annotations/migrate.proto"; 19import "udpa/annotations/status.proto"; 20import "udpa/annotations/versioning.proto"; 21import "validate/validate.proto"; 22 23option java_package = "io.envoyproxy.envoy.config.rbac.v3"; 24option java_outer_classname = "RbacProto"; 25option java_multiple_files = true; 26option go_package = "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3;rbacv3"; 27option (udpa.annotations.file_status).package_version_status = ACTIVE; 28 29// [#protodoc-title: Role Based Access Control (RBAC)] 30 31// Role Based Access Control (RBAC) provides service-level and method-level access control for a 32// service. Requests are allowed or denied based on the ``action`` and whether a matching policy is 33// found. For instance, if the action is ALLOW and a matching policy is found the request should be 34// allowed. 35// 36// RBAC can also be used to make access logging decisions by communicating with access loggers 37// through dynamic metadata. When the action is LOG and at least one policy matches, the 38// ``access_log_hint`` value in the shared key namespace 'envoy.common' is set to ``true`` indicating 39// the request should be logged. 40// 41// Here is an example of RBAC configuration. It has two policies: 42// 43// * Service account ``cluster.local/ns/default/sa/admin`` has full access to the service, and so 44// does "cluster.local/ns/default/sa/superuser". 45// 46// * Any user can read (``GET``) the service at paths with prefix ``/products``, so long as the 47// destination port is either 80 or 443. 48// 49// .. code-block:: yaml 50// 51// action: ALLOW 52// policies: 53// "service-admin": 54// permissions: 55// - any: true 56// principals: 57// - authenticated: 58// principal_name: 59// exact: "cluster.local/ns/default/sa/admin" 60// - authenticated: 61// principal_name: 62// exact: "cluster.local/ns/default/sa/superuser" 63// "product-viewer": 64// permissions: 65// - and_rules: 66// rules: 67// - header: 68// name: ":method" 69// string_match: 70// exact: "GET" 71// - url_path: 72// path: { prefix: "/products" } 73// - or_rules: 74// rules: 75// - destination_port: 80 76// - destination_port: 443 77// principals: 78// - any: true 79// 80message RBAC { 81 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.RBAC"; 82 83 // Should we do safe-list or block-list style access control? 84 enum Action { 85 // The policies grant access to principals. The rest are denied. This is safe-list style 86 // access control. This is the default type. 87 ALLOW = 0; 88 89 // The policies deny access to principals. The rest are allowed. This is block-list style 90 // access control. 91 DENY = 1; 92 93 // The policies set the ``access_log_hint`` dynamic metadata key based on if requests match. 94 // All requests are allowed. 95 LOG = 2; 96 } 97 98 message AuditLoggingOptions { 99 // Deny and allow here refer to RBAC decisions, not actions. 100 enum AuditCondition { 101 // Never audit. 102 NONE = 0; 103 104 // Audit when RBAC denies the request. 105 ON_DENY = 1; 106 107 // Audit when RBAC allows the request. 108 ON_ALLOW = 2; 109 110 // Audit whether RBAC allows or denies the request. 111 ON_DENY_AND_ALLOW = 3; 112 } 113 114 // [#not-implemented-hide:] 115 message AuditLoggerConfig { 116 // Typed logger configuration. 117 // 118 // [#extension-category: envoy.rbac.audit_loggers] 119 core.v3.TypedExtensionConfig audit_logger = 1; 120 121 // If true, when the logger is not supported, the data plane will not NACK but simply ignore it. 122 bool is_optional = 2; 123 } 124 125 // Condition for the audit logging to happen. 126 // If this condition is met, all the audit loggers configured here will be invoked. 127 // 128 // [#not-implemented-hide:] 129 AuditCondition audit_condition = 1 [(validate.rules).enum = {defined_only: true}]; 130 131 // Configurations for RBAC-based authorization audit loggers. 132 // 133 // [#not-implemented-hide:] 134 repeated AuditLoggerConfig logger_configs = 2; 135 } 136 137 // The action to take if a policy matches. Every action either allows or denies a request, 138 // and can also carry out action-specific operations. 139 // 140 // Actions: 141 // 142 // * ``ALLOW``: Allows the request if and only if there is a policy that matches 143 // the request. 144 // * ``DENY``: Allows the request if and only if there are no policies that 145 // match the request. 146 // * ``LOG``: Allows all requests. If at least one policy matches, the dynamic 147 // metadata key ``access_log_hint`` is set to the value ``true`` under the shared 148 // key namespace ``envoy.common``. If no policies match, it is set to ``false``. 149 // Other actions do not modify this key. 150 // 151 Action action = 1 [(validate.rules).enum = {defined_only: true}]; 152 153 // Maps from policy name to policy. A match occurs when at least one policy matches the request. 154 // The policies are evaluated in lexicographic order of the policy name. 155 map<string, Policy> policies = 2; 156 157 // Audit logging options that include the condition for audit logging to happen 158 // and audit logger configurations. 159 // 160 // [#not-implemented-hide:] 161 AuditLoggingOptions audit_logging_options = 3; 162} 163 164// Policy specifies a role and the principals that are assigned/denied the role. 165// A policy matches if and only if at least one of its permissions match the 166// action taking place AND at least one of its principals match the downstream 167// AND the condition is true if specified. 168message Policy { 169 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Policy"; 170 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 [(validate.rules).repeated = {min_items: 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 [(validate.rules).repeated = {min_items: 1}]; 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 [(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"]; 188 189 // [#not-implemented-hide:] 190 // An optional symbolic expression that has been successfully type checked. 191 // Only be used when condition is not used. 192 google.api.expr.v1alpha1.CheckedExpr checked_condition = 4 193 [(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"]; 194} 195 196// Permission defines an action (or actions) that a principal can take. 197// [#next-free-field: 13] 198message Permission { 199 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission"; 200 201 // Used in the ``and_rules`` and ``or_rules`` fields in the ``rule`` oneof. Depending on the context, 202 // each are applied with the associated behavior. 203 message Set { 204 option (udpa.annotations.versioning).previous_message_type = 205 "envoy.config.rbac.v2.Permission.Set"; 206 207 repeated Permission rules = 1 [(validate.rules).repeated = {min_items: 1}]; 208 } 209 210 oneof rule { 211 option (validate.required) = true; 212 213 // A set of rules that all must match in order to define the action. 214 Set and_rules = 1; 215 216 // A set of rules where at least one must match in order to define the action. 217 Set or_rules = 2; 218 219 // When any is set, it matches any action. 220 bool any = 3 [(validate.rules).bool = {const: true}]; 221 222 // A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only 223 // available for HTTP request. 224 // Note: the pseudo-header :path includes the query and fragment string. Use the ``url_path`` 225 // field if you want to match the URL path without the query and fragment string. 226 route.v3.HeaderMatcher header = 4; 227 228 // A URL path on the incoming HTTP request. Only available for HTTP. 229 type.matcher.v3.PathMatcher url_path = 10; 230 231 // A CIDR block that describes the destination IP. 232 core.v3.CidrRange destination_ip = 5; 233 234 // A port number that describes the destination port connecting to. 235 uint32 destination_port = 6 [(validate.rules).uint32 = {lte: 65535}]; 236 237 // A port number range that describes a range of destination ports connecting to. 238 type.v3.Int32Range destination_port_range = 11; 239 240 // Metadata that describes additional information about the action. 241 type.matcher.v3.MetadataMatcher metadata = 7; 242 243 // Negates matching the provided permission. For instance, if the value of 244 // ``not_rule`` would match, this permission would not match. Conversely, if 245 // the value of ``not_rule`` would not match, this permission would match. 246 Permission not_rule = 8; 247 248 // The request server from the client's connection request. This is 249 // typically TLS SNI. 250 // 251 // .. attention:: 252 // 253 // The behavior of this field may be affected by how Envoy is configured 254 // as explained below. 255 // 256 // * If the :ref:`TLS Inspector <config_listener_filters_tls_inspector>` 257 // filter is not added, and if a ``FilterChainMatch`` is not defined for 258 // the :ref:`server name 259 // <envoy_v3_api_field_config.listener.v3.FilterChainMatch.server_names>`, 260 // a TLS connection's requested SNI server name will be treated as if it 261 // wasn't present. 262 // 263 // * A :ref:`listener filter <arch_overview_listener_filters>` may 264 // overwrite a connection's requested server name within Envoy. 265 // 266 // Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn to 267 // setup SNI. 268 type.matcher.v3.StringMatcher requested_server_name = 9; 269 270 // Extension for configuring custom matchers for RBAC. 271 // [#extension-category: envoy.rbac.matchers] 272 core.v3.TypedExtensionConfig matcher = 12; 273 } 274} 275 276// Principal defines an identity or a group of identities for a downstream 277// subject. 278// [#next-free-field: 13] 279message Principal { 280 option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal"; 281 282 // Used in the ``and_ids`` and ``or_ids`` fields in the ``identifier`` oneof. 283 // Depending on the context, each are applied with the associated behavior. 284 message Set { 285 option (udpa.annotations.versioning).previous_message_type = 286 "envoy.config.rbac.v2.Principal.Set"; 287 288 repeated Principal ids = 1 [(validate.rules).repeated = {min_items: 1}]; 289 } 290 291 // Authentication attributes for a downstream. 292 message Authenticated { 293 option (udpa.annotations.versioning).previous_message_type = 294 "envoy.config.rbac.v2.Principal.Authenticated"; 295 296 reserved 1; 297 298 // The name of the principal. If set, The URI SAN or DNS SAN in that order 299 // is used from the certificate, otherwise the subject field is used. If 300 // unset, it applies to any user that is authenticated. 301 type.matcher.v3.StringMatcher principal_name = 2; 302 } 303 304 oneof identifier { 305 option (validate.required) = true; 306 307 // A set of identifiers that all must match in order to define the 308 // downstream. 309 Set and_ids = 1; 310 311 // A set of identifiers at least one must match in order to define the 312 // downstream. 313 Set or_ids = 2; 314 315 // When any is set, it matches any downstream. 316 bool any = 3 [(validate.rules).bool = {const: true}]; 317 318 // Authenticated attributes that identify the downstream. 319 Authenticated authenticated = 4; 320 321 // A CIDR block that describes the downstream IP. 322 // This address will honor proxy protocol, but will not honor XFF. 323 // 324 // This field is deprecated; either use :ref:`direct_remote_ip 325 // <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>` for the same 326 // behavior, or use 327 // :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>`. 328 core.v3.CidrRange source_ip = 5 329 [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; 330 331 // A CIDR block that describes the downstream remote/origin address. 332 // Note: This is always the physical peer even if the 333 // :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>` is 334 // inferred from for example the x-forwarder-for header, proxy protocol, 335 // etc. 336 core.v3.CidrRange direct_remote_ip = 10; 337 338 // A CIDR block that describes the downstream remote/origin address. 339 // Note: This may not be the physical peer and could be different from the 340 // :ref:`direct_remote_ip 341 // <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the 342 // remote ip is inferred from for example the x-forwarder-for header, proxy 343 // protocol, etc. 344 core.v3.CidrRange remote_ip = 11; 345 346 // A header (or pseudo-header such as :path or :method) on the incoming HTTP 347 // request. Only available for HTTP request. Note: the pseudo-header :path 348 // includes the query and fragment string. Use the ``url_path`` field if you 349 // want to match the URL path without the query and fragment string. 350 route.v3.HeaderMatcher header = 6; 351 352 // A URL path on the incoming HTTP request. Only available for HTTP. 353 type.matcher.v3.PathMatcher url_path = 9; 354 355 // Metadata that describes additional information about the principal. 356 type.matcher.v3.MetadataMatcher metadata = 7; 357 358 // Identifies the principal using a filter state object. 359 type.matcher.v3.FilterStateMatcher filter_state = 12; 360 361 // Negates matching the provided principal. For instance, if the value of 362 // ``not_id`` would match, this principal would not match. Conversely, if the 363 // value of ``not_id`` would not match, this principal would match. 364 Principal not_id = 8; 365 } 366} 367 368// Action defines the result of allowance or denial when a request matches the matcher. 369message Action { 370 // The name indicates the policy name. 371 string name = 1 [(validate.rules).string = {min_len: 1}]; 372 373 // The action to take if the matcher matches. Every action either allows or denies a request, 374 // and can also carry out action-specific operations. 375 // 376 // Actions: 377 // 378 // * ``ALLOW``: If the request gets matched on ALLOW, it is permitted. 379 // * ``DENY``: If the request gets matched on DENY, it is not permitted. 380 // * ``LOG``: If the request gets matched on LOG, it is permitted. Besides, the 381 // dynamic metadata key ``access_log_hint`` under the shared key namespace 382 // ``envoy.common`` will be set to the value ``true``. 383 // * If the request cannot get matched, it will fallback to ``DENY``. 384 // 385 // Log behavior: 386 // 387 // If the RBAC matcher contains at least one LOG action, the dynamic 388 // metadata key ``access_log_hint`` will be set based on if the request 389 // get matched on the LOG action. 390 // 391 RBAC.Action action = 2; 392} 393