You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
13 KiB
311 lines
13 KiB
syntax = "proto3"; |
|
|
|
package envoy.config.rbac.v3; |
|
|
|
import "envoy/config/core/v3/address.proto"; |
|
import "envoy/config/core/v3/extension.proto"; |
|
import "envoy/config/route/v3/route_components.proto"; |
|
import "envoy/type/matcher/v3/metadata.proto"; |
|
import "envoy/type/matcher/v3/path.proto"; |
|
import "envoy/type/matcher/v3/string.proto"; |
|
import "envoy/type/v3/range.proto"; |
|
|
|
import "google/api/expr/v1alpha1/checked.proto"; |
|
import "google/api/expr/v1alpha1/syntax.proto"; |
|
|
|
import "envoy/annotations/deprecation.proto"; |
|
import "udpa/annotations/migrate.proto"; |
|
import "udpa/annotations/status.proto"; |
|
import "udpa/annotations/versioning.proto"; |
|
import "validate/validate.proto"; |
|
|
|
option java_package = "io.envoyproxy.envoy.config.rbac.v3"; |
|
option java_outer_classname = "RbacProto"; |
|
option java_multiple_files = true; |
|
option (udpa.annotations.file_status).package_version_status = ACTIVE; |
|
|
|
// [#protodoc-title: Role Based Access Control (RBAC)] |
|
|
|
// Role Based Access Control (RBAC) provides service-level and method-level access control for a |
|
// service. Requests are allowed or denied based on the `action` and whether a matching policy is |
|
// found. For instance, if the action is ALLOW and a matching policy is found the request should be |
|
// allowed. |
|
// |
|
// RBAC can also be used to make access logging decisions by communicating with access loggers |
|
// through dynamic metadata. When the action is LOG and at least one policy matches, the |
|
// `access_log_hint` value in the shared key namespace 'envoy.common' is set to `true` indicating |
|
// the request should be logged. |
|
// |
|
// Here is an example of RBAC configuration. It has two policies: |
|
// |
|
// * Service account "cluster.local/ns/default/sa/admin" has full access to the service, and so |
|
// does "cluster.local/ns/default/sa/superuser". |
|
// |
|
// * Any user can read ("GET") the service at paths with prefix "/products", so long as the |
|
// destination port is either 80 or 443. |
|
// |
|
// .. code-block:: yaml |
|
// |
|
// action: ALLOW |
|
// policies: |
|
// "service-admin": |
|
// permissions: |
|
// - any: true |
|
// principals: |
|
// - authenticated: |
|
// principal_name: |
|
// exact: "cluster.local/ns/default/sa/admin" |
|
// - authenticated: |
|
// principal_name: |
|
// exact: "cluster.local/ns/default/sa/superuser" |
|
// "product-viewer": |
|
// permissions: |
|
// - and_rules: |
|
// rules: |
|
// - header: |
|
// name: ":method" |
|
// string_match: |
|
// exact: "GET" |
|
// - url_path: |
|
// path: { prefix: "/products" } |
|
// - or_rules: |
|
// rules: |
|
// - destination_port: 80 |
|
// - destination_port: 443 |
|
// principals: |
|
// - any: true |
|
// |
|
message RBAC { |
|
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.RBAC"; |
|
|
|
// Should we do safe-list or block-list style access control? |
|
enum Action { |
|
// The policies grant access to principals. The rest are denied. This is safe-list style |
|
// access control. This is the default type. |
|
ALLOW = 0; |
|
|
|
// The policies deny access to principals. The rest are allowed. This is block-list style |
|
// access control. |
|
DENY = 1; |
|
|
|
// The policies set the `access_log_hint` dynamic metadata key based on if requests match. |
|
// All requests are allowed. |
|
LOG = 2; |
|
} |
|
|
|
// The action to take if a policy matches. Every action either allows or denies a request, |
|
// and can also carry out action-specific operations. |
|
// |
|
// Actions: |
|
// |
|
// * ALLOW: Allows the request if and only if there is a policy that matches |
|
// the request. |
|
// * DENY: Allows the request if and only if there are no policies that |
|
// match the request. |
|
// * LOG: Allows all requests. If at least one policy matches, the dynamic |
|
// metadata key `access_log_hint` is set to the value `true` under the shared |
|
// key namespace 'envoy.common'. If no policies match, it is set to `false`. |
|
// Other actions do not modify this key. |
|
// |
|
Action action = 1 [(validate.rules).enum = {defined_only: true}]; |
|
|
|
// Maps from policy name to policy. A match occurs when at least one policy matches the request. |
|
// The policies are evaluated in lexicographic order of the policy name. |
|
map<string, Policy> policies = 2; |
|
} |
|
|
|
// Policy specifies a role and the principals that are assigned/denied the role. |
|
// A policy matches if and only if at least one of its permissions match the |
|
// action taking place AND at least one of its principals match the downstream |
|
// AND the condition is true if specified. |
|
message Policy { |
|
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Policy"; |
|
|
|
// Required. The set of permissions that define a role. Each permission is |
|
// matched with OR semantics. To match all actions for this policy, a single |
|
// Permission with the `any` field set to true should be used. |
|
repeated Permission permissions = 1 [(validate.rules).repeated = {min_items: 1}]; |
|
|
|
// Required. The set of principals that are assigned/denied the role based on |
|
// “action”. Each principal is matched with OR semantics. To match all |
|
// downstreams for this policy, a single Principal with the `any` field set to |
|
// true should be used. |
|
repeated Principal principals = 2 [(validate.rules).repeated = {min_items: 1}]; |
|
|
|
// An optional symbolic expression specifying an access control |
|
// :ref:`condition <arch_overview_condition>`. The condition is combined |
|
// with the permissions and the principals as a clause with AND semantics. |
|
// Only be used when checked_condition is not used. |
|
google.api.expr.v1alpha1.Expr condition = 3 |
|
[(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"]; |
|
|
|
// [#not-implemented-hide:] |
|
// An optional symbolic expression that has been successfully type checked. |
|
// Only be used when condition is not used. |
|
google.api.expr.v1alpha1.CheckedExpr checked_condition = 4 |
|
[(udpa.annotations.field_migrate).oneof_promotion = "expression_specifier"]; |
|
} |
|
|
|
// Permission defines an action (or actions) that a principal can take. |
|
// [#next-free-field: 13] |
|
message Permission { |
|
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Permission"; |
|
|
|
// Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context, |
|
// each are applied with the associated behavior. |
|
message Set { |
|
option (udpa.annotations.versioning).previous_message_type = |
|
"envoy.config.rbac.v2.Permission.Set"; |
|
|
|
repeated Permission rules = 1 [(validate.rules).repeated = {min_items: 1}]; |
|
} |
|
|
|
oneof rule { |
|
option (validate.required) = true; |
|
|
|
// A set of rules that all must match in order to define the action. |
|
Set and_rules = 1; |
|
|
|
// A set of rules where at least one must match in order to define the action. |
|
Set or_rules = 2; |
|
|
|
// When any is set, it matches any action. |
|
bool any = 3 [(validate.rules).bool = {const: true}]; |
|
|
|
// A header (or pseudo-header such as :path or :method) on the incoming HTTP request. Only |
|
// available for HTTP request. |
|
// Note: the pseudo-header :path includes the query and fragment string. Use the `url_path` |
|
// field if you want to match the URL path without the query and fragment string. |
|
route.v3.HeaderMatcher header = 4; |
|
|
|
// A URL path on the incoming HTTP request. Only available for HTTP. |
|
type.matcher.v3.PathMatcher url_path = 10; |
|
|
|
// A CIDR block that describes the destination IP. |
|
core.v3.CidrRange destination_ip = 5; |
|
|
|
// A port number that describes the destination port connecting to. |
|
uint32 destination_port = 6 [(validate.rules).uint32 = {lte: 65535}]; |
|
|
|
// A port number range that describes a range of destination ports connecting to. |
|
type.v3.Int32Range destination_port_range = 11; |
|
|
|
// Metadata that describes additional information about the action. |
|
type.matcher.v3.MetadataMatcher metadata = 7; |
|
|
|
// Negates matching the provided permission. For instance, if the value of |
|
// `not_rule` would match, this permission would not match. Conversely, if |
|
// the value of `not_rule` would not match, this permission would match. |
|
Permission not_rule = 8; |
|
|
|
// The request server from the client's connection request. This is |
|
// typically TLS SNI. |
|
// |
|
// .. attention:: |
|
// |
|
// The behavior of this field may be affected by how Envoy is configured |
|
// as explained below. |
|
// |
|
// * If the :ref:`TLS Inspector <config_listener_filters_tls_inspector>` |
|
// filter is not added, and if a `FilterChainMatch` is not defined for |
|
// the :ref:`server name |
|
// <envoy_v3_api_field_config.listener.v3.FilterChainMatch.server_names>`, |
|
// a TLS connection's requested SNI server name will be treated as if it |
|
// wasn't present. |
|
// |
|
// * A :ref:`listener filter <arch_overview_listener_filters>` may |
|
// overwrite a connection's requested server name within Envoy. |
|
// |
|
// Please refer to :ref:`this FAQ entry <faq_how_to_setup_sni>` to learn to |
|
// setup SNI. |
|
type.matcher.v3.StringMatcher requested_server_name = 9; |
|
|
|
// Extension for configuring custom matchers for RBAC. |
|
// [#extension-category: envoy.rbac.matchers] |
|
core.v3.TypedExtensionConfig matcher = 12; |
|
} |
|
} |
|
|
|
// Principal defines an identity or a group of identities for a downstream |
|
// subject. |
|
// [#next-free-field: 12] |
|
message Principal { |
|
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v2.Principal"; |
|
|
|
// Used in the `and_ids` and `or_ids` fields in the `identifier` oneof. |
|
// Depending on the context, each are applied with the associated behavior. |
|
message Set { |
|
option (udpa.annotations.versioning).previous_message_type = |
|
"envoy.config.rbac.v2.Principal.Set"; |
|
|
|
repeated Principal ids = 1 [(validate.rules).repeated = {min_items: 1}]; |
|
} |
|
|
|
// Authentication attributes for a downstream. |
|
message Authenticated { |
|
option (udpa.annotations.versioning).previous_message_type = |
|
"envoy.config.rbac.v2.Principal.Authenticated"; |
|
|
|
reserved 1; |
|
|
|
// The name of the principal. If set, The URI SAN or DNS SAN in that order |
|
// is used from the certificate, otherwise the subject field is used. If |
|
// unset, it applies to any user that is authenticated. |
|
type.matcher.v3.StringMatcher principal_name = 2; |
|
} |
|
|
|
oneof identifier { |
|
option (validate.required) = true; |
|
|
|
// A set of identifiers that all must match in order to define the |
|
// downstream. |
|
Set and_ids = 1; |
|
|
|
// A set of identifiers at least one must match in order to define the |
|
// downstream. |
|
Set or_ids = 2; |
|
|
|
// When any is set, it matches any downstream. |
|
bool any = 3 [(validate.rules).bool = {const: true}]; |
|
|
|
// Authenticated attributes that identify the downstream. |
|
Authenticated authenticated = 4; |
|
|
|
// A CIDR block that describes the downstream IP. |
|
// This address will honor proxy protocol, but will not honor XFF. |
|
core.v3.CidrRange source_ip = 5 |
|
[deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"]; |
|
|
|
// A CIDR block that describes the downstream remote/origin address. |
|
// Note: This is always the physical peer even if the |
|
// :ref:`remote_ip <envoy_v3_api_field_config.rbac.v3.Principal.remote_ip>` is |
|
// inferred from for example the x-forwarder-for header, proxy protocol, |
|
// etc. |
|
core.v3.CidrRange direct_remote_ip = 10; |
|
|
|
// A CIDR block that describes the downstream remote/origin address. |
|
// Note: This may not be the physical peer and could be different from the |
|
// :ref:`direct_remote_ip |
|
// <envoy_v3_api_field_config.rbac.v3.Principal.direct_remote_ip>`. E.g, if the |
|
// remote ip is inferred from for example the x-forwarder-for header, proxy |
|
// protocol, etc. |
|
core.v3.CidrRange remote_ip = 11; |
|
|
|
// A header (or pseudo-header such as :path or :method) on the incoming HTTP |
|
// request. Only available for HTTP request. Note: the pseudo-header :path |
|
// includes the query and fragment string. Use the `url_path` field if you |
|
// want to match the URL path without the query and fragment string. |
|
route.v3.HeaderMatcher header = 6; |
|
|
|
// A URL path on the incoming HTTP request. Only available for HTTP. |
|
type.matcher.v3.PathMatcher url_path = 9; |
|
|
|
// Metadata that describes additional information about the principal. |
|
type.matcher.v3.MetadataMatcher metadata = 7; |
|
|
|
// Negates matching the provided principal. For instance, if the value of |
|
// `not_id` would match, this principal would not match. Conversely, if the |
|
// value of `not_id` would not match, this principal would match. |
|
Principal not_id = 8; |
|
} |
|
}
|
|
|