rbac: add support for upstream ip policy.#17645
rbac: add support for upstream ip policy.#17645mattklein123 merged 78 commits intoenvoyproxy:mainfrom
Conversation
7243aea to
72631b1
Compare
|
PTAL @alyssawilk @htuch @yangminzhu. |
yangminzhu
left a comment
There was a problem hiding this comment.
Also I think this should at least be covered in unit tests (preferably also in integration tests), could you add some tests?
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
I wonder should we add a generic filter state matcher (similar to the dynamic metadata matcher) so that it can support other use cases in the future without the need to change the rbac API everytime?
cc @htuch for API review
api/envoy/config/rbac/v3/rbac.proto
Outdated
Thanks for looking :). Wanted to have a first pass to make sure that the changes are ok in general before I add tests. |
4ef7357 to
357904d
Compare
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
Can you explain in the documentation here what the resolution semantics are? What happens if there is a change in resolution during processing? What is the v4/v6 story? etc.
|
Tagging @alyssawilk (dynamic forward DNS) @lizan (RBAC) for implementation review. |
|
@htuch thanks for reviewing the PR. |
alyssawilk
left a comment
There was a problem hiding this comment.
Looks solid at a high level - let's add unit tests and an integration test to make sure it all hangs together!
There was a problem hiding this comment.
I'd actually like @mattklein123 's thoughts on this.
I'd mildly prefer to have rbac just look up the ip:host mapping to copying it all into stream info for every request, but that'd be a hard dep on the dynamic proxy code which may be worse in the long run.
There was a problem hiding this comment.
If it were up to me I would probably leave this as is, but config guard tracking this in filter state to avoid the perf hit for people that don't care.
There was a problem hiding this comment.
is the right thing to do here to add the address, or replace the address?
I'd think if we did recreateStream (internal redirect) we'd want to remove old addresses rather than append to them, to make sure we only had the addresses we wanted to use
There was a problem hiding this comment.
Do you think we should add a clear API so that the caller can then call clear and add? Or is it better to replace the set with a single address? The idea here is to have a set of resolved addresses for the upstream and if any of them match.
There was a problem hiding this comment.
yeah I think in the long run we're going to want to support multiple addresses, but also handle recreateStream, so either overwrite an existing set, or clear it and add new data.
(if that doesn't make sense please ping me on slack)
|
@alyssawilk thanks for reviewing. I have resolved most of the suggestions and comments. There is still some questions which I do not have clear answers for. Would appreciate your input. |
api/envoy/config/rbac/v3/rbac.proto
Outdated
There was a problem hiding this comment.
I'm a bit hesitate to add a field to support an extension while dfp might be an exception here. Though shouldn't this be an example that we should have an upstream HTTP filter for RBAC? while I know the current upstream filter doesn't support this yet.
There was a problem hiding this comment.
Agree that this could be solved with a upstream filter. As discussed in the issue, this is a DFP specific targeted changed to solve a particular use case. We probably need to revisit this when upstream filters are more powerful.
There was a problem hiding this comment.
Yeah sounds reasonable for now. Shall we name the field more explicitly, or do we expect other filter might set that filter state as well?
There was a problem hiding this comment.
@lizan I think the construct could be used in a general context when we have upstream filters in their full form. When we generalize the RBAC policy to act on ANY of the upstream ip addresses, I think the address set could be the source of truth for it. WDYT?
There was a problem hiding this comment.
Yeah I'm not crazy about this hard coding either which is effectively going to live forever. I have a vague idea that I'm going to throw out there that we might want to explore.
What if we had some type of generic matcher extension mechanism. Basically this becomes a typed_extension_config. One of the things the extension matcher gets access to when it matches is filter state. The config for the typed extension can be whatever it wants including a string name, hard coded, etc. (If you upstream the extension it needs to be more generic but if you just have an internal extension you can hard code it all.)
|
mind checking out the coverage fail? Looks like it's legit and this is missing some unit testing. |
Will add unit + integration tests. |
|
/retest |
|
Retrying Azure Pipelines: |
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for all the improved testing! Here's some follow up thoughts
There was a problem hiding this comment.
javadoc comments for envoy/ functions if you leave them here
Alternately looking at another example filterSate object we just use the impl everywhere and don't have an abstract base class. I think that'd be fine here too, especially if we add a key() function so all the files using the class have to include the Impl anyway
envoy/stream_info/filter_state.h
Outdated
There was a problem hiding this comment.
Looks like in at least one other use case, the Filterstate::Object had
static const std::string& key();
which is nice because then only components who care about that object pull that key. WDYT?
There was a problem hiding this comment.
would ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::rbac) work over the MISC logger macro?
There was a problem hiding this comment.
yeah I think in the long run we're going to want to support multiple addresses, but also handle recreateStream, so either overwrite an existing set, or clear it and add new data.
(if that doesn't make sense please ping me on slack)
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
|
@htuch @mattklein123 I have added port as additional matching parameter in the matcher. Also, removed the upstream ip |
api/envoy/extensions/rbac/matchers/upstream_ip_port/v3/upstream_ip_port_matcher.proto
Show resolved
Hide resolved
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
|
@mattklein123 @htuch @alyssawilk @ggreenway I think this PR should be ready now. I am not sure why the dependency CI checks are failing. |
|
/retest |
|
Retrying Azure Pipelines: |
mattklein123
left a comment
There was a problem hiding this comment.
Thanks LGTM with small remaining comments.
/wait
api/envoy/extensions/rbac/matchers/upstream_ip_port/v3/upstream_ip_port_matcher.proto
Show resolved
Hide resolved
|
|
||
| "envoy.rbac.matchers.upstream_ip": "//source/extensions/filters/common/rbac/matchers:upstream_ip_lib", | ||
| "envoy.rbac.matchers.upstream_ip_port": "//source/extensions/filters/common/rbac/matchers:upstream_ip_port_lib", | ||
| "envoy.rbac.matchers.upstream_port": "//source/extensions/filters/common/rbac/matchers:upstream_port_lib", |
There was a problem hiding this comment.
I think this needs to get removed? Or is this staying to match on ports only? Would it be better to just have a single matcher and allow address to be optional and if so any address will match? So basically either port, address, or both need to be set?
There was a problem hiding this comment.
Thanks @mattklein123 .
I can see how having both could be confusing but I have kept the ip-port matcher to qualify IP with Port for matching IP & Port (if provided). Wanted to keep Port matcher separate so that a) be independent (no dependency on IP) b) Have IP as first class citizen of the IP-Port matcher a Port as an added qualifier.
Please let me know if that makes sense.
There was a problem hiding this comment.
I don't really follow. You have port optional in one of them. Why can't address be optional? Logically then shouldn't you have an address only matcher? I would remove the dedicated port matcher and just make a single matcher that requires either to be set or both.
There was a problem hiding this comment.
I was hoping that we can avoid configurations where neither IP or Port are provided.
Will change to combine the matchers 👍
There was a problem hiding this comment.
Just reject that case in code and I think that will turn out great, thank you.
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
|
/retest |
|
Retrying Azure Pipelines: |
mattklein123
left a comment
There was a problem hiding this comment.
Almost there, thanks!
/wait
source/extensions/filters/common/rbac/matchers/upstream_ip_port.cc
Outdated
Show resolved
Hide resolved
- Added configuration check. Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
| UpstreamIpPortMatcher::UpstreamIpPortMatcher( | ||
| const envoy::extensions::rbac::matchers::upstream_ip_port::v3::UpstreamIpPortMatcher& proto) { | ||
| if (!proto.has_upstream_ip() && !proto.has_upstream_port_range()) { | ||
| throw EnvoyException("Invalid UpstreamIpPortMatcher configuration - missing `upstream_ip` and " |
There was a problem hiding this comment.
| throw EnvoyException("Invalid UpstreamIpPortMatcher configuration - missing `upstream_ip` and " | |
| throw EnvoyException("Invalid UpstreamIpPortMatcher configuration - missing `upstream_ip` and/or " |
There was a problem hiding this comment.
Also, update the docs to make it more clear that one or both are required (I already mentioned this), thanks.
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
| // Note that although both fields are optional, an exception will be thrown during configuration | ||
| // load time if none of the fields are provided. |
There was a problem hiding this comment.
(Users don't care about exceptions)
| // Note that although both fields are optional, an exception will be thrown during configuration | |
| // load time if none of the fields are provided. | |
| // Note that although both fields are optional, at least one of IP or port must be supplied. If only one is supplied the other is a wildcard match. |
Signed-off-by: Jojy George Varghese <jojy_varghese@apple.com>
alyssawilk
left a comment
There was a problem hiding this comment.
Thanks for your patience slogging through this - looks great.
Based on the dicsussion in the issue #17410, this PR adds
implementation for ability to add rbac policy to filter upstream ip addresses for dynamically
resolved domains (by dynamic proxy filter).
risk: Medium
testing: Manual testing
api: added upstream_ip to
RBAC::Policy::PermissionSigned-off-by: Jojy G Varghese jojy_varghese@apple.com
Commit Message:
Additional Description:
Risk Level:
Testing:
Docs Changes:
Release Notes:
Platform Specific Features:
[Optional Runtime guard:]
[Optional Fixes #Issue]
[Optional Deprecated:]
[Optional API Considerations:]