Skip to content

A Proxy-Wasm module allowing communication to Authorino and Limitador.

License

Notifications You must be signed in to change notification settings

Kuadrant/wasm-shim

Repository files navigation

Wasm-shim

Rust FOSSA Status

A Proxy-Wasm module written in Rust, acting as a shim between Envoy and both Rate-limiting and External Auth services.

Sample configuration

Following is a sample configuration used by the shim.

services:
  auth-service:
    type: auth
    endpoint: auth-cluster
    failureMode: deny
    timeout: 10ms
  ratelimit-service:
    type: ratelimit
    endpoint: ratelimit-cluster
    failureMode: allow
actionSets:
  - name: rlp-ns-A/rlp-name-A
    routeRuleConditions:
      hostnames: [ "*.toystore.com" ]
      predicates:
      - request.url_path.startsWith("/get")
      - request.host == "test.toystore.com"
      - request.method == "GET"
    actions:
    - service: auth-service
      scope: auth-scope-a
    - service: ratelimit-service
      scope: ratelimit-scope-a
      predicates:
      - auth.identity.anonymous == true
      data:
      - expression:
          key: my_header
          value: request.headers["my-custom-header"]

Features

CEL Predicates and Expression

routeRuleConditions's predicates are expressed in Common Expression Language (CEL). Predicates evaluating to a bool value, while Expression, used for passing data to a service, evaluate to some Value.

These expression can operate on the data made available to them through the Well Known Attributes, see below

Well Known Attributes

Attribute Description
Envoy Attributes Contextual properties provided by Envoy during request and connection processing
source.remote_address This attribute evaluates to the trusted client address (IP address without port) as it is being defined by Envoy Doc
auth.* Data made available by the authentication service to the ActionSet's pipeline

Building

Prerequisites:

  • Install wasm32-unknown-unknown build target
rustup target add wasm32-unknown-unknown

Build the WASM module

make build

Build the WASM module in release mode

make build BUILD=release

Build the WASM module with features

make build FEATURES=debug-host-behaviour

Testing

cargo test

Running local development environment (kind)

docker is required.

Run local development environment

make local-setup

This deploys a local kubernetes cluster using kind, with the local build of wasm-shim mapped to the envoy container. An echo API as well as limitador, authorino, and some test policies are configured.

To expose the envoy endpoint run the following:

kubectl port-forward --namespace kuadrant-system deployment/envoy 8000:8000

There is then a single auth action set defined for e2e testing:

  • auth-a which defines auth is required for requests to /get for the AuthConfig with effective-route-1
curl -H "Host: test.a.auth.com" http://127.0.0.1:8000/get -i
# HTTP/1.1 401 Unauthorized
curl -H "Host: test.a.auth.com" -H "Authorization: APIKEY IAMALICE" http://127.0.0.1:8000/get -i
# HTTP/1.1 200 OK

And some rate limit action sets defined for e2e testing:

  • rlp-a: Only one data item. Data selector should not generate return any value. Thus, descriptor should be empty and rate limiting service should not be called.
curl -H "Host: test.a.rlp.com" http://127.0.0.1:8000/get -i
  • rlp-b: Conditions do not match. Hence, rate limiting service should not be called.
curl -H "Host: test.b.rlp.com" http://127.0.0.1:8000/get -i
  • rlp-c: Descriptor entries from multiple data items should be generated. Hence, rate limiting service should be called.
curl -H "Host: test.c.rlp.com" -H "x-forwarded-for: 50.0.0.1" -H "my-custom-header-01: my-custom-header-value-01" -H "x-dyn-user-id: bob" http://127.0.0.1:8000/get -i

Check limitador logs for received descriptor entries.

kubectl logs -f deployment/limitador-sample -n kuadrant-system

The expected descriptor entries:

Entry { key: "limit_to_be_activated", value: "1" }
Entry { key: "source.address", value: "50.0.0.1:0" }
Entry { key: "request.headers.my-custom-header-01", value: "my-custom-header-value-01" }
Entry { key: "user_id", value: "bob" }
  • multi-a which defines two actions for authenticated ratelimiting.
curl -H "Host: test.a.multi.com" http://127.0.0.1:8000/get -i
# HTTP/1.1 401 Unauthorized

Alice has 5 requests per 10 seconds:

while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H "Authorization: APIKEY IAMALICE" -H "Host: test.a.multi.com" http://127.0.0.1:8000/get | grep -E --color "\b(429)\b|$"; sleep 1; done

Bob has 2 requests per 10 seconds:

while :; do curl --write-out '%{http_code}\n' --silent --output /dev/null -H "Authorization: APIKEY IAMBOB" -H "Host: test.a.multi.com" http://127.0.0.1:8000/get | grep -E --color "\b(429)\b|$"; sleep 1; done

To rebuild and deploy to the cluster:

make build local-rollout

Stop and clean up resources:

make local-cleanup

License

Apache 2.0 License

FOSSA Status