api: Add log action to RBAC filter api#11705
api: Add log action to RBAC filter api#11705mattklein123 merged 48 commits intoenvoyproxy:masterfrom
Conversation
|
Relates to #11594 |
There was a problem hiding this comment.
Why is this a string and not a bool?
There was a problem hiding this comment.
This could be used to indicate a reason for logging and presence of the key indicates whether to log. E.g. RBAC filter would put "rbac" here.
There was a problem hiding this comment.
I think I would prefer we have a dynamic metadata key for the RBAC filter and make it a bool. This is the intended use of dynamic metadata, which avoids having to coordinate on key namespace across arbitrary number of filters.
There was a problem hiding this comment.
What about the scenarios where multiple filters can give a decision to logging filter to log/not. For example, we have a wasm sampling filter that also decides whether a request should be logged or not. It would be good to have a key that is generic enough and not filter specific so that the consuming filter can make a decision just based on the value of this key rather than needing to have knowledge of all filters from whom, it can get a decision of, to log or not.
There was a problem hiding this comment.
Please specify in the docs how this interacts with Envoy's default file and gRPC access loggers. You might want to add a field that indicates what metadata controls logging to them potentially. I think you should also pick naming of the key space that indicates how this is supposed to be used when taking into account the variety of loggers; basically what I'm after is a solution that makes sense for Envoy independent of Istio.
There was a problem hiding this comment.
Sounds good. To clarify, we'll use the same key for use in all access loggers. It will be called something like "access_log_policy", which conveys its use for determining whether to output access logs. All loggers have the option of checking this key when invoked. For envoy access loggers specifically, we'd provide an access log filter that can be specified in the logger config that checks this key.
There was a problem hiding this comment.
OK, sounds good. Will this be a boolean or some string? What are the contents of this string if it's a policy?
There was a problem hiding this comment.
For flexibility purposes @gargnupur and @kyessenov preferred a string. Currently I just have it set to "yes" or "no", but potential use case for a string would be instead of "yes" to put the deciding filter name, for debugging or some other reason. I could go either way on this, whatever the general consensus is.
There was a problem hiding this comment.
We're going with a boolean value now.
There was a problem hiding this comment.
Does this still effectively allow?
There was a problem hiding this comment.
It allows all requests. I'll make it more clear.
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
Should this key be qualified by RBAC filter?
There was a problem hiding this comment.
This is probably the only comment I have still outstanding.
There was a problem hiding this comment.
+1. The "envoy" part in "envoy.log" does not provide much value.
There was a problem hiding this comment.
I think I would prefer we have a dynamic metadata key for the RBAC filter and make it a bool. This is the intended use of dynamic metadata, which avoids having to coordinate on key namespace across arbitrary number of filters.
There was a problem hiding this comment.
I say that all requests are allowed explicitly here. I think it's clear enough right @yangminzhu ?
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
LOG action does not impact allow or deny decision. Let's remove "All requests are allowed" to avoid confusion.
There was a problem hiding this comment.
To avoid confusion, I think its best for the user to know that all requests are allowed if the action is LOG rather than wonder what will happen with their request
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
+1. The "envoy" part in "envoy.log" does not provide much value.
f254b36 to
aa28d67
Compare
a5ccc9c to
7f21b1e
Compare
| * empty map should be used if there are no headers available. | ||
| * @param info the per-request or per-connection stream info with additional information | ||
| * about the action/principal. | ||
| * about the action/principal. Can be modified by an Action. |
There was a problem hiding this comment.
Can we be more specific that it could be modified only by an LOG action.
| return true; | ||
| } | ||
| default: | ||
| return true; |
There was a problem hiding this comment.
I think you can replace return true with NOT_REACHED_GCOVR_EXCL_LINE;, and remove the return true below.
| config_->engine(callbacks_->route(), Filters::Common::RBAC::EnforcementMode::Enforced); | ||
| if (engine != nullptr) { | ||
| if (engine->allowed(*callbacks_->connection(), headers, callbacks_->streamInfo(), nullptr)) { | ||
| // Check authorization decision and do Action operations |
There was a problem hiding this comment.
This comment seems a bit redundant.
| checkEngine(engine, expected, empty_info, connection, headers); | ||
| } | ||
|
|
||
| void checkEngineLog( |
There was a problem hiding this comment.
Can we remove this function and combine the check into the checkEngine()? You can still pass the LogResult to it. This gives us more coverage with less code.
There was a problem hiding this comment.
That would probably mean having every test check log metadata even when its an Allow or Deny test
There was a problem hiding this comment.
isn't that better? we make sure the Allow/Deny doesn't write to the metadata accidentally.
There was a problem hiding this comment.
Yeah I guess that's true.
| checkEngineLog(engine, RBAC::LogResult::Undecided, info, conn, headers); | ||
| } | ||
|
|
||
| TEST(RoleBasedAccessControlEngineImpl, LogAllowAll) { |
There was a problem hiding this comment.
This would be duplicated and can be removed if you combine checkEngineLog() to checkEngine(), see the comment above.
| EXPECT_EQ(Http::FilterHeadersStatus::Continue, log_filter_.decodeHeaders(headers, false)); | ||
| auto filter_meta = req_info_.dynamicMetadata().filter_metadata().at( | ||
| Filters::Common::RBAC::DynamicMetadataKeysSingleton::get().CommonNamespace); | ||
| EXPECT_EQ(false, filter_meta.fields() |
There was a problem hiding this comment.
You can just use EXPECT_FALSE.
| EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(trailers_)); | ||
|
|
||
| // Check Log | ||
| setMetadata(); |
There was a problem hiding this comment.
Call the setMetadata() in the beginning, also remove the extra call of EXPECT_EQ(Http::FilterHeadersStatus::Continue, ...) which is already called above.
There was a problem hiding this comment.
This checks the log action in the same test as the regular action. After refactoring some stuff from before, it might make sense to do all log tests this way. Do you think its better to combine log tests with Allow tests or should we keep them separate?
There was a problem hiding this comment.
let's combine them together so that we also cover the case that non-LOG action will not write to the metadata accidentally.
There was a problem hiding this comment.
I meant testing that LOG action will log whenever ALLOW action allows. So I'm using two separate configs in these tests. This allows me to easily add checks for log action for other cases like Path and RequestedServerName. Do you think that's too confusing?
There was a problem hiding this comment.
I think this is unnecessary and complicates the tests with two configs. Like I said before, just initialize the config to the action you want to test, and then check the behavior:
- for ALLOW action, it should allow the request and deny by default, the metadata should not change
- for DENY action, it should deny if explicitly matched and allow if not, the metadata should not change
- for LOG action, it should always allow, and the metadata should change if matched
There was a problem hiding this comment.
Sure sounds good.
| }; | ||
| EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.decodeHeaders(headers, false)); | ||
|
|
||
| headers = Http::TestRequestHeaderMapImpl{ |
There was a problem hiding this comment.
what's the purpose of this and the next line?
There was a problem hiding this comment.
I added an extra test to Path, I thought it could maybe use a verify false test? I'll remove it. It's probably not necessary.
There was a problem hiding this comment.
isn't it duplicate with the above one?
There was a problem hiding this comment.
":path" is set to "prefix/suffix/next" for the first one and "/suffix#seg?param=value" for the second one.
| EXPECT_EQ(Http::FilterHeadersStatus::StopIteration, filter_.decodeHeaders(headers, false)); | ||
|
|
||
| // Check Log | ||
| setMetadata(); |
There was a problem hiding this comment.
same here, move the setMetadata() to the above, and remove the extra EXPECT_EQ() in the next line.
| RoleBasedAccessControlFilterConfigSharedPtr config_; | ||
|
|
||
| RoleBasedAccessControlFilter filter_; | ||
| RoleBasedAccessControlFilterConfigSharedPtr log_config_; |
There was a problem hiding this comment.
no, let's use only one filter_ and config_ otherwise it gets really complicated of which one is being tested in a test case.
You can have a custom setUp(envoy::config::rbac::v3::RBAC::Action action) that creates a new config/filter and assign to the config_/filter_ in the beginning of each test case, it also combine the SetUp().
Similar to what you are doing in the network/rbac/filter_test.cc
There was a problem hiding this comment.
This makes more verbose to check log and non-log actions in the same test, which I do a couple times, but for clarity I can change it.
There was a problem hiding this comment.
why more verbose? they are testing different things, for a non-LOG action, we also need to make sure it doesn't write to the metadata.
There was a problem hiding this comment.
I'm testing both configs in some tests, see below comment.
Signed-off-by: davidraskin <draskin@google.com>
Signed-off-by: davidraskin <draskin@google.com>
Signed-off-by: davidraskin <draskin@google.com>
|
@mattklein123 @yangminzhu does this look good now? Thanks. |
yangminzhu
left a comment
There was a problem hiding this comment.
Thanks! Looks good to me and only 1 small comment.
| NOT_REACHED_GCOVR_EXCL_LINE; | ||
| } | ||
|
|
||
| return true; |
There was a problem hiding this comment.
could this be removed since all cases are handled in the switch?
Signed-off-by: davidraskin <draskin@google.com>
|
@mattklein123 Could you please take a look? Thanks! |
|
@mattklein123 Does this PR look okay now or is there more that needs to be done? Thanks. |
This is in my review queue. Asking me repeatedly to review it is doing the opposite of what you are hoping for. Thank you for your understanding! |
|
Apologies, and sorry for being obnoxious. This was just a blocking PR on my end and I just wanted to make sure you hadn't missed it for whatever reason. I fully understand that there's other PRs that are higher priority and need to be reviewed first. Thanks! |
mattklein123
left a comment
There was a problem hiding this comment.
LGTM with small merge issue. Thank you!
/wait
| * lua: added Lua APIs to access :ref:`SSL connection info <config_http_filters_lua_ssl_socket_info>` object. | ||
| * postgres network filter: :ref:`metadata <config_network_filters_postgres_proxy_dynamic_metadata>` is produced based on SQL query. | ||
| * ratelimit: added :ref:`enable_x_ratelimit_headers <envoy_v3_api_msg_extensions.filters.http.ratelimit.v3.RateLimit>` option to enable `X-RateLimit-*` headers as defined in `draft RFC <https://tools.ietf.org/id/draft-polli-ratelimit-headers-03.html>`_. | ||
| * ratelimit: added :ref:`enable_x_ratelimit_headers <envoy_v3_api_msg_extensions.filters.http.ratelimit.v3.RateLimit>` option to enable `X-RateLimit-*` headers as defined in `draft RFC <https://tools.ietf.org/id/draft-polli-ratelimit-headers-02.html>`_. |
There was a problem hiding this comment.
You didn't actually fix the issue. This line needs to get reverted.
/wait
There was a problem hiding this comment.
Oops, should be good now.
Signed-off-by: davidraskin <draskin@google.com>
|
Thank you! |
Commit Message: Add "LOG" action to RBAC filter api
Additional Description: The log action will be used to set the dynamic metadata key "envoy.log", which can be used to decide whether to log a request.
Risk Level: Low
Testing: Existing tests pass
Docs Changes: Updated RBAC configuration reference with new dynamic metadata, and updated RBAC api reference.
Release Notes: n/a
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]