Wasm Plugin

WasmPlugins provides a mechanism to extend the functionality provided by the Istio proxy through WebAssembly filters.

Order of execution (as part of Envoy’s filter chain) is determined by phase and priority settings, allowing the configuration of complex interactions between user-supplied WasmPlugins and Istio’s internal filters.

Examples:

AuthN Filter deployed to ingress-gateway that implements an OpenID flow and populates the Authorization header with a JWT to be consumed by Istio AuthN.

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: openid-connect
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: file:///opt/filters/openid.wasm
  sha256: 1ef0c9a92b0420cf25f7fe5d481b231464bc88f486ca3b9c83ed5cc21d2f6210
  phase: AUTHN
  pluginConfig:
    openid_server: authn
    openid_realm: ingress

This is the same as the last example, but using an OCI image.

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: openid-connect
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://private-registry:5000/openid-connect/openid:latest
  imagePullPolicy: IfNotPresent
  imagePullSecret: private-registry-pull-secret
  phase: AUTHN
  pluginConfig:
    openid_server: authn
    openid_realm: ingress

This is the same as the last example, but using VmConfig to configure environment variables in the VM.

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: openid-connect
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://private-registry:5000/openid-connect/openid:latest
  imagePullPolicy: IfNotPresent
  imagePullSecret: private-registry-pull-secret
  phase: AUTHN
  pluginConfig:
    openid_server: authn
    openid_realm: ingress
  vmConfig:
    env:
    - name: POD_NAME
      valueFrom: HOST
    - name: TRUST_DOMAIN
      value: "cluster.local"

This is also the same as the last example, but the Wasm module is pulled via https and updated for each time when this plugin resource is changed.

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: openid-connect
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: https://private-bucket/filters/openid.wasm
  imagePullPolicy: Always
  phase: AUTHN
  pluginConfig:
    openid_server: authn
    openid_realm: ingress
  vmConfig:
    env:
    - name: POD_NAME
      valueFrom: HOST
    - name: TRUST_DOMAIN
      value: "cluster.local"

And a more complex example that deploys three WasmPlugins and orders them using phase and priority. The (hypothetical) setup is that the openid-connect filter performs an OpenID Connect flow to authenticate the user, writing a signed JWT into the Authorization header of the request, which can be verified by the Istio authn plugin. Then, the acl-check plugin kicks in, passing the JWT to a policy server, which in turn responds with a signed token that contains information about which files and functions of the system are available to the user that was previously authenticated. The acl-check filter writes this token to a header. Finally, the check-header filter verifies the token in that header and makes sure that the token’s contents (the permitted ‘function’) matches its plugin configuration.

The resulting filter chain looks like this: -> openid-connect -> istio.authn -> acl-check -> check-header -> router

apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: openid-connect
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://private-registry:5000/openid-connect/openid:latest
  imagePullPolicy: IfNotPresent
  imagePullSecret: private-registry-pull-secret
  phase: AUTHN
  pluginConfig:
    openid_server: authn
    openid_realm: ingress
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: acl-check
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://private-registry:5000/acl-check/acl:latest
  imagePullPolicy: Always
  imagePullSecret: private-registry-pull-secret
  phase: AUTHZ
  priority: 1000
  pluginConfig:
    acl_server: some_server
    set_header: authz_complete
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
  name: check-header
  namespace: istio-ingress
spec:
  selector:
    matchLabels:
      istio: ingressgateway
  url: oci://private-registry:5000/check-header:latest
  imagePullPolicy: IfNotPresent
  imagePullSecret: private-registry-pull-secret
  phase: AUTHZ
  priority: 10
  pluginConfig:
    read_header: authz_complete
    verification_key: a89gAzxvls0JKAKIJSBnnvvvkIO
    function: read_data

WasmPlugin

WasmPlugins provides a mechanism to extend the functionality provided by the Istio proxy through WebAssembly filters.

FieldTypeDescriptionRequired
selectorWorkloadSelector

Criteria used to select the specific set of pods/VMs on which this plugin configuration should be applied. If omitted, this configuration will be applied to all workload instances in the same namespace. If the WasmPlugin is present in the config root namespace, it will be applied to all applicable workloads in any namespace.

At most, only one of the selector or targetRef can be set for a given policy.

No
targetRefPolicyTargetReference

Optional. The targetRef specifies the gateway the policy should be applied to. The targeted resource specified will determine which workloads the WasmPlugin applies to. The targeted resource must be a Gateway in the group gateway.networking.k8s.io. The gateway must be in the same namespace as the policy.

If the targetRef is not set, the policy is applied as defined by the selector. At most, only one of the selector or targetRef can be set for a given policy. Waypoint proxies will not respect selectors even if they match.

No
urlstring

URL of a Wasm module or OCI container. If no scheme is present, defaults to oci://, referencing an OCI image. Other valid schemes are file:// for referencing .wasm module files present locally within the proxy container, and http[s]:// for .wasm module files hosted remotely.

Yes
sha256string

SHA256 checksum that will be used to verify Wasm module or OCI container. If the url field already references a SHA256 (using the @sha256: notation), it must match the value of this field. If an OCI image is referenced by tag and this field is set, its checksum will be verified against the contents of this field after pulling.

No
imagePullPolicyPullPolicy

The pull behaviour to be applied when fetching Wasm module by either OCI image or http/https. Only relevant when referencing Wasm module without any digest, including the digest in OCI image URL or sha256 field in vm_config. Defaults to IfNotPresent, except when an OCI image is referenced in the url and the latest tag is used, in which case Always is the default, mirroring Kubernetes behaviour.

No
imagePullSecretstring

Credentials to use for OCI image pulling. Name of a Kubernetes Secret in the same namespace as the WasmPlugin that contains a Docker pull secret which is to be used to authenticate against the registry when pulling the image.

No
pluginConfigStruct

The configuration that will be passed on to the plugin.

No
pluginNamestring

The plugin name to be used in the Envoy configuration (used to be called rootID). Some .wasm modules might require this value to select the Wasm plugin to execute.

No
phasePluginPhase

Determines where in the filter chain this WasmPlugin is to be injected.

No
priorityInt32Value

Determines ordering of WasmPlugins in the same phase. When multiple WasmPlugins are applied to the same workload in the same phase, they will be applied by priority, in descending order. If priority is not set, or two WasmPlugins exist with the same value, the ordering will be deterministically derived from name and namespace of the WasmPlugins. Defaults to 0.

No
failStrategyFailStrategy

Specifies the failure behavior for the plugin due to fatal errors.

No
vmConfigVmConfig

Configuration for a Wasm VM. More details can be found here.

No
matchTrafficSelector[]

Specifies the criteria to determine which traffic is passed to WasmPlugin. If a traffic satisfies any of TrafficSelectors, the traffic passes the WasmPlugin.

No
typePluginType

Specifies the type of Wasm Extension to be used.

No

VmConfig

Configuration for a Wasm VM. more details can be found here.

FieldTypeDescriptionRequired
envEnvVar[]

Specifies environment variables to be injected to this VM. Note that if a key does not exist, it will be ignored.

No

EnvVar

FieldTypeDescriptionRequired
namestring

Name of the environment variable. Must be a C_IDENTIFIER.

Yes
valueFromEnvValueSource

Source for the environment variable’s value.

No
valuestring

Value for the environment variable. Only applicable if valueFrom is HOST. Defaults to “”.

No

WasmPlugin.TrafficSelector

TrafficSelector provides a mechanism to select a specific traffic flow for which this Wasm Plugin will be enabled. When all the sub conditions in the TrafficSelector are satisfied, the traffic will be selected.

FieldTypeDescriptionRequired
modeWorkloadMode

Criteria for selecting traffic by their direction. Note that CLIENT and SERVER are analogous to OUTBOUND and INBOUND, respectively. For the gateway, the field should be CLIENT or CLIENT_AND_SERVER. If not specified, the default value is CLIENT_AND_SERVER.

No
portsPortSelector[]

Criteria for selecting traffic by their destination port. More specifically, for the outbound traffic, the destination port would be the port of the target service. On the other hand, for the inbound traffic, the destination port is the port bound by the server process in the same Pod.

If one of the given ports is matched, this condition is evaluated to true. If not specified, this condition is evaluated to true for any port.

No

PluginType

PluginType indicates the type of Wasm extension to be used. There are two types of extensions: HTTP and NETWORK.

The HTTP extension works at Layer 7 (for example, as an HTTP filter in Envoy). The detailed HTTP interface can be found here:

The NETWORK extension works at Layer 4 (for example, as a network filter in Envoy). The detailed NETWORK interface can be found here:

The NETWORK extension can be applied to HTTP traffic as well.

NameDescription
UNSPECIFIED_PLUGIN_TYPE

Defaults to HTTP.

HTTP

Use HTTP Wasm Extension.

NETWORK

Use Network Wasm Extension.

PluginPhase

The phase in the filter chain where the plugin will be injected.

NameDescription
UNSPECIFIED_PHASE

Control plane decides where to insert the plugin. This will generally be at the end of the filter chain, right before the Router. Do not specify PluginPhase if the plugin is independent of others.

AUTHN

Insert plugin before Istio authentication filters.

AUTHZ

Insert plugin before Istio authorization filters and after Istio authentication filters.

STATS

Insert plugin before Istio stats filters and after Istio authorization filters.

PullPolicy

The pull behaviour to be applied when fetching a Wam module, mirroring K8s behaviour.

NameDescription
UNSPECIFIED_POLICY

Defaults to IfNotPresent, except for OCI images with tag latest, for which the default will be Always.

IfNotPresent

If an existing version of the image has been pulled before, that will be used. If no version of the image is present locally, we will pull the latest version.

Always

We will always pull the latest version of an image when changing this plugin. Note that the change includes metadata field as well.

EnvValueSource

NameDescription
INLINE

Explicitly given key-value pairs to be injected to this VM

HOST

Istio-proxy’s environment variables exposed to this VM.

FailStrategy

NameDescription
FAIL_CLOSE

A fatal error in the binary fetching or during the plugin execution causes all subsequent requests to fail with 5xx.

FAIL_OPEN

Enables the fail open behavior for the Wasm plugin fatal errors to bypass the plugin execution. A fatal error can be a failure to fetch the remote binary, an exception, or abort() on the VM. This flag is not recommended for the authentication or the authorization plugins.

Was this information useful?
Do you have any suggestions for improvement?

Thanks for your feedback!