envoyproxy / envoyproxy/envoy

wasm: Add support for Dynamic Metadata

Open
#15,148 17 comments 9 reactions 0 assignees View on GitHub
area/wasm enhancement help wanted
Dominant language
C++
Stars
28.9k
Forks
5.6k
Avg merge
1d 20h
Merged PRs (30d)
437

Description

*Description*:
Currently in WASM is not possible to set [Dynamic Metadata](https://www.envoyproxy.io/docs/envoy/latest/configuration/advanced/well_known_dynamic_metadata).
_This metadata emitted by a filter can be consumed by other filters and useful features can be built by stacking such filters For example, a logging filter can consume dynamic metadata from an RBAC filter_

One of the use cases is the integration with RBAC for example how [MYSQL does](https://www.envoyproxy.io/docs/envoy/latest/configuration/listeners/network_filters/mysql_proxy_filter#dynamic-metadata)
We (vmware platform team) have a WASM network filter and we'd need to integrate it with RBAC.

Do others find this valuable? Is there something that we should know before we start contributing this?
( cc @venilnoronha, I spoke with him about that)

ref: Rust SDK Issue: https://github.com/proxy-wasm/proxy-wasm-rust-sdk/issues/81

More details:
---
I did a test by changing the envoy [proxy wasm context.cc](https://github.com/envoyproxy/envoy/blob/1d1b708c7bf6efa02c41d9ce22cbf1e4a1aeec2c/source/extensions/common/wasm/context.cc#L1123) **ONLY for test** ( thanks to @yuval-k for pointed there)

```cpp
WasmResult Context::setProperty(absl::string_view path, absl::string_view value) {
auto* stream_info = getRequestStreamInfo();
if (!stream_info) {
return WasmResult::NotFound;
}
// ENVOY_LOG(debug, "***** setProperty wasm path:{} value:{}", path, value);
ProtobufWkt::Struct metadata_val;
auto& fields_a = *metadata_val.mutable_fields();
std::string v1;
absl::StrAppend(&v1, value);
fields_a[v1].set_bool_value(true);
std::string key3;
absl::StrAppend(&key3, path);
stream_info->setDynamicMetadata(key3, metadata_val);
```
Rust code:
```rust
self.set_property(vec!["my.filters.network.network"],
Some("myitem".as_ref()));
```

And actually the filter works:

```
[2021-02-20 16:45:17.749][7215663][debug][rbac] [source/extensions/filters/network/rbac/rbac_filter.cc:45] checking connection: requestedServerName: , sourceIP: 127.0.0.1:54608, directRemoteIP: 127.0.0.1:54608,remoteIP: 127.0.0.1:54608, localAddress: 127.0.0.1:5673, ssl: none,
dynamicMetadata: filter_metadata {
key: "my.filters.network.network"
value {
fields {
key: "myitem"
value {
bool_value: true
}
}
}
}
```
The RBAC seems to work:
```
[2021-02-19 20:02:20.480][6826232][debug][rbac] [source/extensions/filters/network/rbac/rbac_filter.cc:125]
enforced denied, matched policy myitem-policy
```

envoy conf:
```yaml
filter_chains:
- filters:
- name: envoy.filters.network.wasm
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm
config:
configuration: {"@type":"type.googleapis.com/google.protobuf.StringValue",
"value":""}
name: "my.filters.network.network"
root_id: "my.filters.network.network"
vm_config:
vm_id: "my.filters.network.network"
runtime: envoy.wasm.runtime.v8
code: {"local":{"filename":"wasm32-unknown-unknown/release/my_network_filter.wasm"}}
allow_precompiled: true
- name: envoy.filters.network.rbac
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC
stat_prefix: rbac
rules:
action: DENY
policies:
"myqueue-policy":
permissions:
- metadata:
filter: my.filters.network.network
path:
- key: myitem
value:
bool_match: true
```

Note:
My RBAC filter does not work always, I am looking why.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.