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(
name = "rbac",
srcs = ["rbac.proto"],
visibility = ["//visibility:public"],
deps = [
"//envoy/api/v2/core:address",
"//envoy/api/v2/route",
"//envoy/type:string_match",
],
)
@ -16,6 +18,7 @@ api_go_proto_library(
proto = ":rbac",
deps = [
"//envoy/api/v2/core:address_go_proto",
"//envoy/api/v2/route:route_go_proto",
"//envoy/type:string_match_go_proto",
],
)

@ -2,7 +2,7 @@ syntax = "proto3";
import "validate/validate.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;
option go_package = "v2alpha";
@ -16,33 +16,39 @@ option go_package = "v2alpha";
// 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 (empty permission entry
// means full access) to the service.
//
// * 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
// "v2".
//
// .. code-block:: yaml
//
// action: ALLOW
// policies:
// "service-admin":
// permissions:
// -
// - any: true
// principals:
// authenticated:
// name: "cluster.local/ns/default/sa/admin"
// - authenticated: { name: "cluster.local/ns/default/sa/admin" }
// - authenticated: { name: "cluster.local/ns/default/sa/superuser" }
// "product-viewer":
// permissions:
// - paths: [prefix: "/products", suffix: "/reviews"]
// methods: ["GET"]
// conditions:
// - header:
// key: "version"
// values: [simple: "v1", simple: "v2"]
// - and_rules:
// rules:
// - header: { name: ":method", exact_match: "GET" }
// - header: { name: ":path", regex_match: "/products(/.*)?" }
// - or_rules:
// rules:
// - destination_port: 80
// - destination_port: 443
// principals:
// -
// - any: true
//
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 {
// The policies grant access to principals. The rest is denied. This is white-list style
// access control. This is the default type.
@ -53,105 +59,98 @@ message RBAC {
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.
// 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.
// 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 {
// 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];
// 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];
}
// Specifies how to match an entry in a map.
message MapEntryMatch {
// The key to select an entry from the map.
string key = 1;
// Permission defines an action (or actions) that a principal can take.
message Permission {
// A list of matched values.
repeated envoy.type.StringMatch values = 2;
}
// 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 {
repeated Permission rules = 1 [(validate.rules).repeated .min_items = 1];
}
// Specifies how to match IP addresses.
message IpMatch {
// IP addresses in CIDR notation.
repeated envoy.api.v2.core.CidrRange cidrs = 1;
}
oneof rule {
option (validate.required) = true;
// Specifies how to match ports.
message PortMatch {
// Port numbers.
repeated uint32 ports = 1;
}
// A set of rules that all must match in order to define the action.
Set and_rules = 1;
// Permission defines a permission to access the service.
message Permission {
// Optional. A list of HTTP paths or gRPC methods.
// gRPC methods must be presented as fully-qualified name in the form of
// packageName.serviceName/methodName.
// 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;
}
}
// 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];
// Optional. Custom conditions.
repeated Condition conditions = 3;
// A header (or psuedo-header such as :path or :method) on the incoming HTTP request.
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 {
// 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 {
// Optional. The name of the principal. This matches to the "source.principal" field in
// ":ref: `AttributeContext <envoy_api_msg_service.auth.v2alpha.AttributeContext>`.
// If unset, it applies to any user.
// The name of the principal. If set, the URI SAN is used from the certificate, otherwise the
// subject field is used. If unset, it applies to any user that is authenticated.
string name = 1;
}
// Optional. Authenticated attributes that identify the principal.
Authenticated authenticated = 1;
oneof identifier {
option (validate.required) = true;
// Definition of a custom attribute to identify the principal.
message Attribute {
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;
// A set of identifiers that all must match in order to define the downstream.
Set and_ids = 1;
// Source IP addresses.
IpMatch source_ips = 2;
// A set of identifiers at least one must match in order to define the downstream.
Set or_ids = 2;
// 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 identifies the client.
MapEntryMatch header = 3;
}
}
// 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;
// Optional. Custom attributes that identify the principal.
repeated Attribute attributes = 2;
// A CIDR block that describes the downstream IP.
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