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