rbac: add metadata support to rbac filter (#3638)

Signed-off-by: Yangmin Zhu <ymzhu@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 9e7a3ab6fdf4c55557c3a06a6f7f1fa9c7a4ad7e
pull/620/head
data-plane-api(CircleCI) 7 years ago
parent b0e08feced
commit 5c1d0b213e
  1. 3
      docs/BUILD
  2. 4
      envoy/config/rbac/v2alpha/BUILD
  3. 7
      envoy/config/rbac/v2alpha/rbac.proto
  4. 11
      envoy/type/BUILD
  5. 50
      envoy/type/matcher/BUILD
  6. 123
      envoy/type/matcher/metadata.proto
  7. 24
      envoy/type/matcher/number.proto
  8. 49
      envoy/type/matcher/string.proto
  9. 10
      envoy/type/range.proto
  10. 30
      envoy/type/string_match.proto

@ -67,5 +67,8 @@ proto_library(
"//envoy/service/metrics/v2:metrics_service",
"//envoy/type:percent",
"//envoy/type:range",
"//envoy/type/matcher:metadata",
"//envoy/type/matcher:number",
"//envoy/type/matcher:string",
],
)

@ -9,7 +9,7 @@ api_proto_library(
deps = [
"//envoy/api/v2/core:address",
"//envoy/api/v2/route",
"//envoy/type:string_match",
"//envoy/type/matcher:metadata",
],
)
@ -19,6 +19,6 @@ api_go_proto_library(
deps = [
"//envoy/api/v2/core:address_go_proto",
"//envoy/api/v2/route:route_go_proto",
"//envoy/type:string_match_go_proto",
"//envoy/type/matcher:metadata_go_proto",
],
)

@ -3,6 +3,7 @@ syntax = "proto3";
import "validate/validate.proto";
import "envoy/api/v2/core/address.proto";
import "envoy/api/v2/route/route.proto";
import "envoy/type/matcher/metadata.proto";
package envoy.config.rbac.v2alpha;
option go_package = "v2alpha";
@ -111,6 +112,9 @@ message Permission {
// 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.
envoy.type.matcher.MetadataMatcher metadata = 7;
}
}
@ -150,5 +154,8 @@ message Principal {
// A header (or psuedo-header such as :path or :method) on the incoming HTTP request.
envoy.api.v2.route.HeaderMatcher header = 6;
// Metadata that describes additional information about the principal.
envoy.type.matcher.MetadataMatcher metadata = 7;
}
}

@ -34,14 +34,3 @@ api_go_proto_library(
name = "range",
proto = ":range",
)
api_proto_library(
name = "string_match",
srcs = ["string_match.proto"],
visibility = ["//visibility:public"],
)
api_go_proto_library(
name = "string_match",
proto = ":string_match",
)

@ -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;
}
}

@ -18,3 +18,13 @@ message Int64Range {
// end of the range (exclusive)
int64 end = 2;
}
// Specifies the double start and end of the range using half-open interval semantics [start,
// end).
message DoubleRange {
// start of the range (inclusive)
double start = 1;
// end of the range (exclusive)
double end = 2;
}

@ -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…
Cancel
Save