-
Notifications
You must be signed in to change notification settings - Fork 5.5k
authz: RBAC filter config PBs + flexibility changes #3477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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"], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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]; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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,30 +16,36 @@ 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. | ||
|
|
@@ -68,90 +74,70 @@ message Policy { | |
| 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 a permission to access the service. | ||
| message Permission { | ||
|
|
||
| // A list of matched values. | ||
| repeated envoy.type.StringMatch values = 2; | ||
| } | ||
| message Set { | ||
| repeated Permission rules = 1 [(validate.rules).repeated .min_items = 1]; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Per offline convo can we add some more docs/explanation of what the AND/OR behavior is of this repeated lists? I think that would be helpful.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, these are just wrappers since you can't have a repeated field in a oneof. Adding a comment to specify that the application is dependent on whether it's in
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I commented in the wrong place. :(
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (But more comments here fine too) |
||
| } | ||
|
|
||
| // 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; | ||
|
|
||
| // Optional. Custom conditions. | ||
| repeated Condition conditions = 3; | ||
| // When any is set, it matches any action. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On this field (and the same one on principal) can we add a bit more docs explaining the usage (effectively that it's explicit and a policy needs to have at least one permission and principal). |
||
| bool any = 3 [(validate.rules).bool.const = true]; | ||
|
|
||
| // 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. | ||
| message Principal { | ||
|
|
||
| message Set { | ||
| repeated Principal ids = 1 [(validate.rules).repeated .min_items = 1]; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. space between "repeated" and ".min_items"? |
||
| } | ||
|
|
||
| // 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. | ||
| 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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the "subject field"? Is "unset" of this field equivalent to "any" field set to "true"?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the same behavior as in ext authz / AttributeContext, it uses the URI SAN if present, otherwise, it uses the subject field off the certificate. if a principal has authenticated set with its name unset it means that the request must be authenticated, but does not care who the subject is. |
||
| 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 principal. | ||
| 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 principal. | ||
| 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 principal. | ||
| bool any = 3 [(validate.rules).bool.const = true]; | ||
|
|
||
| // Authenticated attributes that identify the principal. | ||
| Authenticated authenticated = 4; | ||
|
|
||
| // Optional. Custom attributes that identify the principal. | ||
| repeated Attribute attributes = 2; | ||
| // A CIDR block that describes the source 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; | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that there is space between "repeated" and ".min_items"? Should it be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clang-format rules doesn't distinguish between the option name and the
repeateddecorator for a field. Unfortunately this has to remain but it's fortunately compatible with protoc