authz: RBAC filter config PBs + flexibility changes (#3477)

Signed-off-by: Chris Roche <croche@lyft.com>

Mirrored from https://github.com/envoyproxy/envoy @ 9d0f0a844d070ce01f7106b8926e539c4cbe49b1
pull/620/head
data-plane-api(CircleCI) 7 years ago
parent c443373859
commit 1478f3332d
  1. 9
      envoy/config/filter/http/rbac/v2/BUILD
  2. 29
      envoy/config/filter/http/rbac/v2/rbac.proto
  3. 3
      envoy/config/rbac/v2alpha/BUILD
  4. 171
      envoy/config/rbac/v2alpha/rbac.proto

@ -0,0 +1,9 @@
load("//bazel:api_build_system.bzl", "api_proto_library")
licenses(["notice"]) # Apache 2
api_proto_library(
name = "rbac",
srcs = ["rbac.proto"],
deps = ["//envoy/config/rbac/v2alpha:rbac"],
)

@ -0,0 +1,29 @@
syntax = "proto3";
package envoy.config.filter.http.rbac.v2;
option go_package = "v2";
import "envoy/config/rbac/v2alpha/rbac.proto";
import "validate/validate.proto";
import "gogoproto/gogo.proto";
// [#protodoc-title: RBAC]
// Role-Based Access Control :ref:`configuration overview <config_http_filters_rbac>`.
message RBAC {
// Specify the RBAC rules to be applied globally
config.rbac.v2alpha.RBAC rules = 1 [(validate.rules).message.required = true];
}
message RBACPerRoute {
oneof override {
option (validate.required) = true;
// Disable the filter for this particular vhost or route.
bool disabled = 1 [(validate.rules).bool.const = true];
// Override the global configuration of the filter with this new config.
RBAC rbac = 2 [(validate.rules).message.required = true];
}
}

@ -5,8 +5,10 @@ load("//bazel:api_build_system.bzl", "api_proto_library", "api_go_proto_library"
api_proto_library( api_proto_library(
name = "rbac", name = "rbac",
srcs = ["rbac.proto"], srcs = ["rbac.proto"],
visibility = ["//visibility:public"],
deps = [ deps = [
"//envoy/api/v2/core:address", "//envoy/api/v2/core:address",
"//envoy/api/v2/route",
"//envoy/type:string_match", "//envoy/type:string_match",
], ],
) )
@ -16,6 +18,7 @@ api_go_proto_library(
proto = ":rbac", proto = ":rbac",
deps = [ deps = [
"//envoy/api/v2/core:address_go_proto", "//envoy/api/v2/core:address_go_proto",
"//envoy/api/v2/route:route_go_proto",
"//envoy/type:string_match_go_proto", "//envoy/type:string_match_go_proto",
], ],
) )

@ -2,7 +2,7 @@ syntax = "proto3";
import "validate/validate.proto"; import "validate/validate.proto";
import "envoy/api/v2/core/address.proto"; import "envoy/api/v2/core/address.proto";
import "envoy/type/string_match.proto"; import "envoy/api/v2/route/route.proto";
package envoy.config.rbac.v2alpha; package envoy.config.rbac.v2alpha;
option go_package = "v2alpha"; option go_package = "v2alpha";
@ -16,33 +16,39 @@ option go_package = "v2alpha";
// matching policy is found (suppose the `action` is ALLOW). // matching policy is found (suppose the `action` is ALLOW).
// //
// Here is an example of RBAC configuration. It has two policies: // Here is an example of RBAC configuration. It has two policies:
//
// * Service account "cluster.local/ns/default/sa/admin" has full access (empty permission entry // * Service account "cluster.local/ns/default/sa/admin" has full access (empty permission entry
// means full access) to the service. // means full access) to the service.
//
// * Any user (empty principal entry means any user) can read ("GET") the service at paths with // * Any user (empty principal entry means any user) can read ("GET") the service at paths with
// prefix "/products" or suffix "/reviews" when request header "version" set to either "v1" or // prefix "/products" or suffix "/reviews" when request header "version" set to either "v1" or
// "v2". // "v2".
// //
// .. code-block:: yaml
//
// action: ALLOW // action: ALLOW
// policies: // policies:
// "service-admin": // "service-admin":
// permissions: // permissions:
// - // - any: true
// principals: // principals:
// authenticated: // - authenticated: { name: "cluster.local/ns/default/sa/admin" }
// name: "cluster.local/ns/default/sa/admin" // - authenticated: { name: "cluster.local/ns/default/sa/superuser" }
// "product-viewer": // "product-viewer":
// permissions: // permissions:
// - paths: [prefix: "/products", suffix: "/reviews"] // - and_rules:
// methods: ["GET"] // rules:
// conditions: // - header: { name: ":method", exact_match: "GET" }
// - header: // - header: { name: ":path", regex_match: "/products(/.*)?" }
// key: "version" // - or_rules:
// values: [simple: "v1", simple: "v2"] // rules:
// - destination_port: 80
// - destination_port: 443
// principals: // principals:
// - // - any: true
// //
message RBAC { message RBAC {
// Should we do white-list or black-list style access control. // Should we do white-list or black-list style access control?
enum Action { enum Action {
// The policies grant access to principals. The rest is denied. This is white-list style // The policies grant access to principals. The rest is denied. This is white-list style
// access control. This is the default type. // access control. This is the default type.
@ -53,105 +59,98 @@ message RBAC {
DENY = 1; 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; Action action = 1;
// Maps from policy name to policy. // Maps from policy name to policy. A match occurs when at least one policy matches the request.
map<string, Policy> policies = 2; map<string, Policy> policies = 2;
} }
// Policy specifies a role and the principals that are assigned/denied the role. // 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.
message Policy { message Policy {
// Required. The set of permissions that define a role. // 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]; repeated Permission permissions = 1 [(validate.rules).repeated .min_items = 1];
// Required. List of principals that are assigned/denied the role based on action. // 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]; repeated Principal principals = 2 [(validate.rules).repeated .min_items = 1];
} }
// Specifies how to match an entry in a map. // Permission defines an action (or actions) that a principal can take.
message MapEntryMatch { message Permission {
// The key to select an entry from the map.
string key = 1;
// A list of matched values. // Used in the `and_rules` and `or_rules` fields in the `rule` oneof. Depending on the context,
repeated envoy.type.StringMatch values = 2; // each are applied with the associated behavior.
} message Set {
repeated Permission rules = 1 [(validate.rules).repeated .min_items = 1];
}
// Specifies how to match IP addresses. oneof rule {
message IpMatch { option (validate.required) = true;
// IP addresses in CIDR notation.
repeated envoy.api.v2.core.CidrRange cidrs = 1;
}
// Specifies how to match ports. // A set of rules that all must match in order to define the action.
message PortMatch { Set and_rules = 1;
// Port numbers.
repeated uint32 ports = 1;
}
// Permission defines a permission to access the service. // A set of rules where at least one must match in order to define the action.
message Permission { Set or_rules = 2;
// Optional. A list of HTTP paths or gRPC methods.
// gRPC methods must be presented as fully-qualified name in the form of // When any is set, it matches any action.
// packageName.serviceName/methodName. bool any = 3 [(validate.rules).bool.const = true];
// If this field is unset, it applies to any path.
repeated envoy.type.StringMatch paths = 1;
// Required. A list of HTTP methods (e.g., "GET", "POST").
// If this field is unset, it applies to any method.
repeated string methods = 2;
// Definition of a custom condition.
message Condition {
oneof condition_spec {
// Header match. This matches to the "request.http.headers" field in
// ":ref: `AttributeContext <envoy_api_msg_service.auth.v2alpha.AttributeContext>`.
// The map key is the header name. The header specifies how the service is accessed.
MapEntryMatch header = 1;
// Destination IP addresses.
IpMatch destination_ips = 2;
// Destination ports.
PortMatch destination_ports = 3;
}
}
// Optional. Custom conditions. // A header (or psuedo-header such as :path or :method) on the incoming HTTP request.
repeated Condition conditions = 3; envoy.api.v2.route.HeaderMatcher header = 4;
// A CIDR block that describes the destination IP.
envoy.api.v2.core.CidrRange destination_ip = 5;
// A port number that describes the destination port connecting to.
uint32 destination_port = 6 [(validate.rules).uint32.lte = 65535];
}
} }
// Principal defines an identity or a group of identities. // Principal defines an identity or a group of identities for a downstream subject.
message Principal { message Principal {
// Authentication attributes for principal. These could be filled out inside RBAC filter.
// Or if an authentication filter is used, they can be provided by the authentication filter. // 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 {
repeated Principal ids = 1 [(validate.rules).repeated .min_items = 1];
}
// Authentication attributes for a downstream.
message Authenticated { message Authenticated {
// Optional. The name of the principal. This matches to the "source.principal" field in // The name of the principal. If set, the URI SAN is used from the certificate, otherwise the
// ":ref: `AttributeContext <envoy_api_msg_service.auth.v2alpha.AttributeContext>`. // subject field is used. If unset, it applies to any user that is authenticated.
// If unset, it applies to any user.
string name = 1; string name = 1;
} }
// Optional. Authenticated attributes that identify the principal. oneof identifier {
Authenticated authenticated = 1; option (validate.required) = true;
// Definition of a custom attribute to identify the principal. // A set of identifiers that all must match in order to define the downstream.
message Attribute { Set and_ids = 1;
oneof attribute_spec {
// Source service name. This matches to the "source.service" field in
// ":ref: `AttributeContext <envoy_api_msg_service.auth.v2alpha.AttributeContext>`.
string service = 1;
// Source IP addresses. // A set of identifiers at least one must match in order to define the downstream.
IpMatch source_ips = 2; Set or_ids = 2;
// Header match. This matches to the "request.http.headers" field in // When any is set, it matches any downstream.
// ":ref: `AttributeContext <envoy_api_msg_service.auth.v2alpha.AttributeContext>`. bool any = 3 [(validate.rules).bool.const = true];
// The map "key" is the header name. The header identifies the client.
MapEntryMatch header = 3; // Authenticated attributes that identify the downstream.
} Authenticated authenticated = 4;
}
// Optional. Custom attributes that identify the principal. // A CIDR block that describes the downstream IP.
repeated Attribute attributes = 2; envoy.api.v2.core.CidrRange source_ip = 5;
// A header (or psuedo-header such as :path or :method) on the incoming HTTP request.
envoy.api.v2.route.HeaderMatcher header = 6;
}
} }

Loading…
Cancel
Save