rbac: add remote_ip for matching downstream remote IP. (#10460)
Signed-off-by: Yangmin Zhu <ymzhu@google.com> Mirrored from https://github.com/envoyproxy/envoy @ 4b6e81c112e204ef04445318d2cbfa168cf22ca7master-ci-test
parent
b742ddcaa0
commit
bebbf79d96
8 changed files with 433 additions and 4 deletions
@ -0,0 +1,16 @@ |
||||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. |
||||
|
||||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") |
||||
|
||||
licenses(["notice"]) # Apache 2 |
||||
|
||||
api_proto_package( |
||||
deps = [ |
||||
"//envoy/config/core/v4alpha:pkg", |
||||
"//envoy/config/rbac/v3:pkg", |
||||
"//envoy/config/route/v4alpha:pkg", |
||||
"//envoy/type/matcher/v3:pkg", |
||||
"@com_github_cncf_udpa//udpa/annotations:pkg", |
||||
"@com_google_googleapis//google/api/expr/v1alpha1:syntax_proto", |
||||
], |
||||
) |
@ -0,0 +1,258 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.config.rbac.v4alpha; |
||||
|
||||
import "envoy/config/core/v4alpha/address.proto"; |
||||
import "envoy/config/route/v4alpha/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 "google/api/expr/v1alpha1/syntax.proto"; |
||||
|
||||
import "udpa/annotations/status.proto"; |
||||
import "udpa/annotations/versioning.proto"; |
||||
import "validate/validate.proto"; |
||||
|
||||
option java_package = "io.envoyproxy.envoy.config.rbac.v4alpha"; |
||||
option java_outer_classname = "RbacProto"; |
||||
option java_multiple_files = true; |
||||
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; |
||||
|
||||
// [#protodoc-title: Role Based Access Control (RBAC)] |
||||
|
||||
// Role Based Access Control (RBAC) provides service-level and method-level access control for a |
||||
// service. RBAC policies are additive. The policies are examined in order. A request is allowed |
||||
// once a matching policy is found (suppose the `action` is ALLOW). |
||||
// |
||||
// 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", exact_match: "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.v3.RBAC"; |
||||
|
||||
// Should we do safe-list or block-list style access control? |
||||
enum Action { |
||||
// The policies grant access to principals. The rest is denied. This is safe-list style |
||||
// access control. This is the default type. |
||||
ALLOW = 0; |
||||
|
||||
// The policies deny access to principals. The rest is allowed. This is block-list style |
||||
// access control. |
||||
DENY = 1; |
||||
} |
||||
|
||||
// The action to take if a policy matches. The request is allowed if and only if: |
||||
// |
||||
// * `action` is "ALLOWED" and at least one policy matches |
||||
// * `action` is "DENY" and none of the policies match |
||||
Action action = 1; |
||||
|
||||
// Maps from policy name to policy. A match occurs when at least one policy matches the request. |
||||
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.v3.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. |
||||
google.api.expr.v1alpha1.Expr condition = 3; |
||||
} |
||||
|
||||
// Permission defines an action (or actions) that a principal can take. |
||||
// [#next-free-field: 11] |
||||
message Permission { |
||||
option (udpa.annotations.versioning).previous_message_type = "envoy.config.rbac.v3.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.v3.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.v4alpha.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.v4alpha.CidrRange destination_ip = 5; |
||||
|
||||
// A port number that describes the destination port connecting to. |
||||
uint32 destination_port = 6 [(validate.rules).uint32 = {lte: 65535}]; |
||||
|
||||
// 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_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; |
||||
} |
||||
} |
||||
|
||||
// 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.v3.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.v3.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.v3.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; |
||||
} |
||||
|
||||
reserved 5; |
||||
|
||||
reserved "source_ip"; |
||||
|
||||
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 remote/origin address. |
||||
// Note: This is always the physical peer even if the |
||||
// :ref:`remote_ip <envoy_api_field_config.rbac.v4alpha.Principal.remote_ip>` is inferred |
||||
// from for example the x-forwarder-for header, proxy protocol, etc. |
||||
core.v4alpha.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_api_field_config.rbac.v4alpha.Principal.direct_remote_ip>`. |
||||
// E.g, if the remote ip is inferred from for example the x-forwarder-for header, |
||||
// proxy protocol, etc. |
||||
core.v4alpha.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.v4alpha.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; |
||||
} |
||||
} |
@ -0,0 +1,13 @@ |
||||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. |
||||
|
||||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") |
||||
|
||||
licenses(["notice"]) # Apache 2 |
||||
|
||||
api_proto_package( |
||||
deps = [ |
||||
"//envoy/config/rbac/v4alpha:pkg", |
||||
"//envoy/extensions/filters/http/rbac/v3:pkg", |
||||
"@com_github_cncf_udpa//udpa/annotations:pkg", |
||||
], |
||||
) |
@ -0,0 +1,44 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.extensions.filters.http.rbac.v4alpha; |
||||
|
||||
import "envoy/config/rbac/v4alpha/rbac.proto"; |
||||
|
||||
import "udpa/annotations/status.proto"; |
||||
import "udpa/annotations/versioning.proto"; |
||||
import "validate/validate.proto"; |
||||
|
||||
option java_package = "io.envoyproxy.envoy.extensions.filters.http.rbac.v4alpha"; |
||||
option java_outer_classname = "RbacProto"; |
||||
option java_multiple_files = true; |
||||
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; |
||||
|
||||
// [#protodoc-title: RBAC] |
||||
// Role-Based Access Control :ref:`configuration overview <config_http_filters_rbac>`. |
||||
// [#extension: envoy.filters.http.rbac] |
||||
|
||||
// RBAC filter config. |
||||
message RBAC { |
||||
option (udpa.annotations.versioning).previous_message_type = |
||||
"envoy.extensions.filters.http.rbac.v3.RBAC"; |
||||
|
||||
// Specify the RBAC rules to be applied globally. |
||||
// If absent, no enforcing RBAC policy will be applied. |
||||
config.rbac.v4alpha.RBAC rules = 1; |
||||
|
||||
// Shadow rules are not enforced by the filter (i.e., returning a 403) |
||||
// but will emit stats and logs and can be used for rule testing. |
||||
// If absent, no shadow RBAC policy will be applied. |
||||
config.rbac.v4alpha.RBAC shadow_rules = 2; |
||||
} |
||||
|
||||
message RBACPerRoute { |
||||
option (udpa.annotations.versioning).previous_message_type = |
||||
"envoy.extensions.filters.http.rbac.v3.RBACPerRoute"; |
||||
|
||||
reserved 1; |
||||
|
||||
// Override the global configuration of the filter with this new config. |
||||
// If absent, the global RBAC policy will be disabled for this route. |
||||
RBAC rbac = 2; |
||||
} |
@ -0,0 +1,13 @@ |
||||
# DO NOT EDIT. This file is generated by tools/proto_sync.py. |
||||
|
||||
load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") |
||||
|
||||
licenses(["notice"]) # Apache 2 |
||||
|
||||
api_proto_package( |
||||
deps = [ |
||||
"//envoy/config/rbac/v4alpha:pkg", |
||||
"//envoy/extensions/filters/network/rbac/v3:pkg", |
||||
"@com_github_cncf_udpa//udpa/annotations:pkg", |
||||
], |
||||
) |
@ -0,0 +1,57 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.extensions.filters.network.rbac.v4alpha; |
||||
|
||||
import "envoy/config/rbac/v4alpha/rbac.proto"; |
||||
|
||||
import "udpa/annotations/status.proto"; |
||||
import "udpa/annotations/versioning.proto"; |
||||
import "validate/validate.proto"; |
||||
|
||||
option java_package = "io.envoyproxy.envoy.extensions.filters.network.rbac.v4alpha"; |
||||
option java_outer_classname = "RbacProto"; |
||||
option java_multiple_files = true; |
||||
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; |
||||
|
||||
// [#protodoc-title: RBAC] |
||||
// Role-Based Access Control :ref:`configuration overview <config_network_filters_rbac>`. |
||||
// [#extension: envoy.filters.network.rbac] |
||||
|
||||
// RBAC network filter config. |
||||
// |
||||
// Header should not be used in rules/shadow_rules in RBAC network filter as |
||||
// this information is only available in :ref:`RBAC http filter <config_http_filters_rbac>`. |
||||
message RBAC { |
||||
option (udpa.annotations.versioning).previous_message_type = |
||||
"envoy.extensions.filters.network.rbac.v3.RBAC"; |
||||
|
||||
enum EnforcementType { |
||||
// Apply RBAC policies when the first byte of data arrives on the connection. |
||||
ONE_TIME_ON_FIRST_BYTE = 0; |
||||
|
||||
// Continuously apply RBAC policies as data arrives. Use this mode when |
||||
// using RBAC with message oriented protocols such as Mongo, MySQL, Kafka, |
||||
// etc. when the protocol decoders emit dynamic metadata such as the |
||||
// resources being accessed and the operations on the resources. |
||||
CONTINUOUS = 1; |
||||
} |
||||
|
||||
// Specify the RBAC rules to be applied globally. |
||||
// If absent, no enforcing RBAC policy will be applied. |
||||
config.rbac.v4alpha.RBAC rules = 1; |
||||
|
||||
// Shadow rules are not enforced by the filter but will emit stats and logs |
||||
// and can be used for rule testing. |
||||
// If absent, no shadow RBAC policy will be applied. |
||||
config.rbac.v4alpha.RBAC shadow_rules = 2; |
||||
|
||||
// The prefix to use when emitting statistics. |
||||
string stat_prefix = 3 [(validate.rules).string = {min_bytes: 1}]; |
||||
|
||||
// RBAC enforcement strategy. By default RBAC will be enforced only once |
||||
// when the first byte of data arrives from the downstream. When used in |
||||
// conjunction with filters that emit dynamic metadata after decoding |
||||
// every payload (e.g., Mongo, MySQL, Kafka) set the enforcement type to |
||||
// CONTINUOUS to enforce RBAC policies on every message boundary. |
||||
EnforcementType enforcement_type = 4; |
||||
} |
Loading…
Reference in new issue