-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Title: Improve RBAC to attribute-based engine and CEL)-based API
Background:
The current RBAC engine implements the access control with an role-based API.
Problems:
-
The RBAC role-based API separates the Permission and Principal into 2 different messages. The separation makes sense in control plane as it allows us to reuse the permission and principal, which is the key benefits of role-based access control. But this doesn't make too much sense in data plane, especially in the policy enforcement point (PEP) in Envoy. It makes the code unnecessary complicated, redundant and duplication of both the API and engine implementation. For example, we have 2 almost the same
createfunctions in matchers.cc -
The current RBAC engine is hard to extend for dynamic attributes passed in dynamic metadata. The current RBAC engine uses the MetadataMatcher to match against the value in metadata which is hard-coded in Envoy, only type and operation supported in the metadata matcher could be used in the RBAC policy. For example, the current matcher doesn't support matching on the type
Mapat all, in order to support this we have to modify theMetadataMatcherand wait for its release and deployment. -
The current RBAC engine is tightly coupled with Envoy which makes it very hard to reuse and integrate the engine for other use cases, for example evaluating or analyzing the policy before dispatching to Envoy.
Proposal:
-
Change the RBAC engine to be attributes based
Instead of today's hard-coded engine and matcher, we will define a list of available attributes from the context, pass it together with the CEL expression to the CEL evaluator to get the result (trueorfalse) and do the action accordingly. -
Change the RBAC API to be CEL-based
Instead of today's role-based API, an example API would look like the following, note we could choose either to pass the CEL string or the compiled CELAst to the Envoy.
message Policy {
repeated Rule rules = 1;
}
message Rule {
one_of cel {
CELAst ast = 1;
string expr = 2;
}
enum Action {
ALLOW = 0;
DENY = 1;
}
Action action = 3;
}Benefits:
- The new engine doesn't have separate
permissionandprincipal, it executes the unified policy it gets, the logic of the filter will be much simplified compared to today's custom engine and matchers - The CEL has rich comparison support for matching and protobuf message which means a lot of useful features will be supported in the access control without additional code change. This can also simplify the implementation in Enovy as we don't need to implement them again.
- The CEL engine could be easily reused to support policy evaluation and analysis before sending it to Envoy
- The integration of CEL opens the possibility for using it in places in Enovy other than RBAC. It has built-in support for protobuf message, so some matchers and matching API could be simplified a lot by using CEL expression directly
- The CEL engine is used in Google in production in various products, mostly for access control related policy evaluation and is better tested compared to the RBAC engine, which essentially invents it own AST in its API and evaluation in the RBAC engine.
As a conceptual example, a policy like
headers[":path"].startsWith("/info") &&
headers[":method"] in ["GET", "HEAD"] &&
("x-id" in metadata ? metadata["x-id"] == "123456" : false) &&
metadata["private-protocol-decoder"]["version"].exists_one(x, x in ["V1", "V2"])
could be supported without any code changes with the proposal (attributes-based engine and CEL-based policy), but would require some significant code change in Envoy with today's RBAC engine and API.
Relevant Links:
Common Expression Language.
CEL language spec
CEL C++ implementation
@mattklein123 @rodaine @lizan @liminw @diemtvu @rshriram @venilnoronha
I'm still working on a more detailed design doc, feedback and comments are highly appreciated. More specifically, I would like to know:
- does the direction of the proposal looks good to you?
- do you have any specific concerns that you think should be addressed in the design doc?
Thank you!