rbac: add metadata support to rbac filter (#3638)
Signed-off-by: Yangmin Zhu <ymzhu@google.com> Mirrored from https://github.com/envoyproxy/envoy @ 9e7a3ab6fdf4c55557c3a06a6f7f1fa9c7a4ad7epull/620/head
parent
b0e08feced
commit
5c1d0b213e
10 changed files with 268 additions and 43 deletions
@ -0,0 +1,50 @@ |
||||
load("//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library") |
||||
|
||||
licenses(["notice"]) # Apache 2 |
||||
|
||||
api_proto_library( |
||||
name = "metadata", |
||||
srcs = ["metadata.proto"], |
||||
visibility = ["//visibility:public"], |
||||
deps = [ |
||||
":number", |
||||
":string", |
||||
], |
||||
) |
||||
|
||||
api_go_proto_library( |
||||
name = "metadata", |
||||
proto = ":metadata", |
||||
deps = [ |
||||
":number_go_proto", |
||||
":string_go_proto", |
||||
], |
||||
) |
||||
|
||||
api_proto_library( |
||||
name = "number", |
||||
srcs = ["number.proto"], |
||||
visibility = ["//visibility:public"], |
||||
deps = [ |
||||
"//envoy/type:range", |
||||
], |
||||
) |
||||
|
||||
api_go_proto_library( |
||||
name = "number", |
||||
proto = ":number", |
||||
deps = [ |
||||
"//envoy/type:range_go_proto", |
||||
], |
||||
) |
||||
|
||||
api_proto_library( |
||||
name = "string", |
||||
srcs = ["string.proto"], |
||||
visibility = ["//visibility:public"], |
||||
) |
||||
|
||||
api_go_proto_library( |
||||
name = "string", |
||||
proto = ":string", |
||||
) |
@ -0,0 +1,123 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.type.matcher; |
||||
option go_package = "matcher"; |
||||
|
||||
import "envoy/type/matcher/string.proto"; |
||||
import "envoy/type/matcher/number.proto"; |
||||
|
||||
import "validate/validate.proto"; |
||||
|
||||
// [#protodoc-title: MetadataMatcher] |
||||
|
||||
// MetadataMatcher provides a general interface to check if a given value is matched in |
||||
// :ref:`Metadata <envoy_api_msg_core.Metadata>`. It uses `filter` and `path` to retrieve the value |
||||
// from the Metadata and then check if it's matched to the specified value. |
||||
// |
||||
// For example, for the following Metadata: |
||||
// |
||||
// .. code-block:: yaml |
||||
// |
||||
// filter_metadata: |
||||
// envoy.filters.http.rbac: |
||||
// fields: |
||||
// a: |
||||
// struct_value: |
||||
// fields: |
||||
// b: |
||||
// struct_value: |
||||
// fields: |
||||
// c: |
||||
// string_value: pro |
||||
// t: |
||||
// list_value: |
||||
// values: |
||||
// - string_value: m |
||||
// - string_value: n |
||||
// |
||||
// The following MetadataMatcher is matched as the path [a, b, c] will retrieve a string value "pro" |
||||
// from the Metadata which is matched to the specified prefix match. |
||||
// |
||||
// .. code-block:: yaml |
||||
// |
||||
// filter: envoy.filters.http.rbac |
||||
// path: |
||||
// - key: a |
||||
// - key: b |
||||
// - key: c |
||||
// value: |
||||
// string_match: |
||||
// prefix: pr |
||||
// |
||||
// The following MetadataMatcher is not matched as the path [a, t] is pointing to a list value in |
||||
// the Metadata which is not supported for now. |
||||
// |
||||
// .. code-block:: yaml |
||||
// |
||||
// filter: envoy.filters.http.rbac |
||||
// path: |
||||
// - key: a |
||||
// - key: t |
||||
// value: |
||||
// string_match: |
||||
// exact: m |
||||
// |
||||
// An example use of MetadataMatcher is specifying additional metadata in envoy.filters.http.rbac to |
||||
// enforce access control based on dynamic metadata in a request. See :ref:`Permission |
||||
// <envoy_api_msg_config.rbac.v2alpha.Permission>` and :ref:`Principal |
||||
// <envoy_api_msg_config.rbac.v2alpha.Principal>`. |
||||
message MetadataMatcher { |
||||
// Specifies the segment in a path to retrieve value from Metadata. |
||||
// Note: Currently it's not supported to retrieve a value from a list in Metadata. This means it |
||||
// will always be not matched if the associated value of the key is a list. |
||||
message PathSegment { |
||||
oneof segment { |
||||
option (validate.required) = true; |
||||
|
||||
// If specified, use the key to retrieve the value in a Struct. |
||||
string key = 1 [(validate.rules).string.min_bytes = 1]; |
||||
} |
||||
} |
||||
|
||||
// Specifies the value to match. Only primitive value are supported. For non-primitive values, the |
||||
// result is always not matched. |
||||
message Value { |
||||
// NullMatch is an empty message to specify a null value. |
||||
message NullMatch { |
||||
} |
||||
|
||||
// Specifies how to match a value. |
||||
oneof match_pattern { |
||||
option (validate.required) = true; |
||||
|
||||
// If specified, a match occurs if and only if the target value is a NullValue. |
||||
NullMatch null_match = 1; |
||||
|
||||
// If specified, a match occurs if and only if the target value is a double value and is |
||||
// matched to this field. |
||||
DoubleMatcher double_match = 2; |
||||
|
||||
// If specified, a match occurs if and only if the target value is a string value and is |
||||
// matched to this field. |
||||
StringMatcher string_match = 3; |
||||
|
||||
// If specified, a match occurs if and only if the target value is a bool value and is equal |
||||
// to this field. |
||||
bool bool_match = 4; |
||||
|
||||
// If specified, value match will be performed based on whether the path is referring to a |
||||
// valid primitive value in the metadata. If the path is referring to a non-primitive value, |
||||
// the result is always not matched. |
||||
bool present_match = 5; |
||||
} |
||||
} |
||||
|
||||
// The filter name to retrieve the Struct from the Metadata. |
||||
string filter = 1 [(validate.rules).string.min_bytes = 1]; |
||||
|
||||
// The path to retrieve the Value from the Struct. |
||||
repeated PathSegment path = 2 [(validate.rules).repeated .min_items = 1]; |
||||
|
||||
// The MetadataMatcher is matched if the value retrieved by path is matched to this value. |
||||
Value value = 3 [(validate.rules).message.required = true]; |
||||
} |
@ -0,0 +1,24 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.type.matcher; |
||||
option go_package = "matcher"; |
||||
|
||||
import "envoy/type/range.proto"; |
||||
|
||||
import "validate/validate.proto"; |
||||
|
||||
// [#protodoc-title: NumberMatcher] |
||||
|
||||
// Specifies the way to match a double value. |
||||
message DoubleMatcher { |
||||
oneof match_pattern { |
||||
option (validate.required) = true; |
||||
|
||||
// If specified, the input double value must be in the range specified here. |
||||
// Note: The range is using half-open interval semantics [start, end). |
||||
envoy.type.DoubleRange range = 1; |
||||
|
||||
// If specified, the input double value must be equal to the value specified here. |
||||
double exact = 2; |
||||
} |
||||
} |
@ -0,0 +1,49 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.type.matcher; |
||||
option go_package = "matcher"; |
||||
|
||||
import "validate/validate.proto"; |
||||
|
||||
// [#protodoc-title: StringMatcher] |
||||
|
||||
// Specifies the way to match a string. |
||||
message StringMatcher { |
||||
oneof match_pattern { |
||||
option (validate.required) = true; |
||||
|
||||
// The input string must match exactly the string specified here. |
||||
// |
||||
// Examples: |
||||
// |
||||
// * *abc* only matches the value *abc*. |
||||
string exact = 1; |
||||
|
||||
// The input string must have the prefix specified here. |
||||
// Note: empty prefix is not allowed, please use regex instead. |
||||
// |
||||
// Examples: |
||||
// |
||||
// * *abc* matches the value *abc.xyz* |
||||
string prefix = 2 [(validate.rules).string.min_bytes = 1]; |
||||
|
||||
// The input string must have the suffix specified here. |
||||
// Note: empty prefix is not allowed, please use regex instead. |
||||
// |
||||
// Examples: |
||||
// |
||||
// * *abc* matches the value *xyz.abc* |
||||
string suffix = 3 [(validate.rules).string.min_bytes = 1]; |
||||
|
||||
// The input string must match the regular expression specified here. |
||||
// The regex grammar is defined `here |
||||
// <http://en.cppreference.com/w/cpp/regex/ecmascript>`_. |
||||
// |
||||
// Examples: |
||||
// |
||||
// * The regex *\d{3}* matches the value *123* |
||||
// * The regex *\d{3}* does not match the value *1234* |
||||
// * The regex *\d{3}* does not match the value *123.456* |
||||
string regex = 4; |
||||
} |
||||
} |
@ -1,30 +0,0 @@ |
||||
syntax = "proto3"; |
||||
|
||||
package envoy.type; |
||||
option go_package = "envoy_type"; |
||||
|
||||
import "gogoproto/gogo.proto"; |
||||
|
||||
option (gogoproto.equal_all) = true; |
||||
|
||||
// [#protodoc-title: StringMatch] |
||||
|
||||
// Specifies the way to match a string. |
||||
message StringMatch { |
||||
oneof match_pattern { |
||||
// The input string must match exactly the string specified here. |
||||
// Or it is a "*", which means that it matches any string. |
||||
string simple = 1; |
||||
|
||||
// The input string must have the prefix specified here. |
||||
string prefix = 2; |
||||
|
||||
// The input string must have the suffix specified here. |
||||
string suffix = 3; |
||||
|
||||
// The input string must match the regular expression specified here. |
||||
// The regex grammar is defined `here |
||||
// <http://en.cppreference.com/w/cpp/regex/ecmascript>`_. |
||||
string regex = 4; |
||||
} |
||||
} |
Loading…
Reference in new issue