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"; // [#protodoc-title: Role Based Access Control (RBAC)] // Role Based Access Control (RBAC) provides service-level and method-level access control for a // service. RBAC policies are additive. The policies are examined in order. A request is allowed // once a 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/superuser" } // "product-viewer": // permissions: // - 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 safe-list or block-list style access control? enum Action { // The policies grant access to principals. The rest is denied. This is safe-list style // access control. This is the default type. ALLOW = 0; // The policies deny access to principals. The rest is allowed. This is block-list style // access control. 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. A match occurs when at least one policy matches the request. map policies = 2; } // 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. 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. 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]; } // Permission defines an action (or actions) that a principal can take. message Permission { // 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]; } oneof rule { option (validate.required) = true; // A set of rules that all must match in order to define the action. Set and_rules = 1; // 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]; // 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]; // Metadata that describes additional information about the action. envoy.type.matcher.MetadataMatcher metadata = 7; } } // Principal defines an identity or a group of identities for a downstream subject. message Principal { // 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 { // 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; } oneof identifier { option (validate.required) = true; // A set of identifiers that all must match in order to define the downstream. Set and_ids = 1; // A set of identifiers at least one must match in order to define the downstream. Set or_ids = 2; // 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; // 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; // Metadata that describes additional information about the principal. envoy.type.matcher.MetadataMatcher metadata = 7; } }