Skip to content

Commit 3123487

Browse files
authored
Merge pull request #45111 from JStickler/OSSMDOC-550
OSSMDOC-550: Document new WasmPlugin API.
2 parents 80c70aa + ea44667 commit 3123487

10 files changed

+443
-141
lines changed

modules/ossm-configuring-the-threescale-wasm-auth-module.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,5 @@ $ oc apply -f threescale-wasm-auth-bookinfo.yaml
5959

6060
[role="_additional-resources"]
6161
.Additional resources
62-
* xref:../../service_mesh/v2x/ossm-extensions.adoc#ossm-extensions-deploy_ossm-extensions[Deploying extensions]
62+
* xref:../../service_mesh/v2x/ossm-extensions.adoc#ossm-smextensions-deploy_ossm-extensions[Deploying `ServiceMeshExtension` resources]
6363
* link:https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources[Custom Resources]

modules/ossm-extensions-overview.adoc

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
////
2+
This module included in the following assemblies:
3+
*service_mesh_/v2x/ossm-extensions.adoc
4+
////
5+
:_content-type: CONCEPT
6+
[id="ossm-extensions-overview_{context}"]
7+
= WebAssembly modules overview
8+
9+
WebAssembly modules can be run on many platforms, including proxies, and have broad language support, fast execution, and a sandboxed-by-default security model.
10+
11+
{SMProductName} extensions are link:https://www.envoyproxy.io/docs/envoy/v1.20.0/intro/arch_overview/http/http_filters#arch-overview-http-filters[Envoy HTTP Filters], giving them a wide range of capabilities:
12+
13+
* Manipulating the body and headers of requests and responses.
14+
* Out-of-band HTTP requests to services not in the request path, such as authentication or policy checking.
15+
* Side-channel data storage and queues for filters to communicate with each other.
16+
17+
[NOTE]
18+
====
19+
When creating new WebAssembly extensions, use the WasmPlugin API. The ServiceMeshExtension API is deprecated as of {SMProductName} version 2.2 and will be removed in a future release.
20+
====
21+
22+
There are two parts to writing a {SMProductName} extension:
23+
24+
. You must write your extension using an SDK that exposes the link:https://github.com/proxy-wasm/spec[proxy-wasm API] and compile it to a WebAssembly module.
25+
. You must then package the module into a container.
26+
27+
.Supported languages
28+
29+
You can use any language that compiles to WebAssembly bytecode to write a {SMProductName} extension, but the following languages have existing SDKs that expose the proxy-wasm API so that it can be consumed directly.
30+
31+
.Supported languages
32+
|===
33+
| Language | Maintainer | Repository
34+
35+
| AssemblyScript
36+
| solo.io
37+
| link:https://github.com/solo-io/proxy-runtime[solo-io/proxy-runtime]
38+
39+
| C++
40+
| proxy-wasm team (Istio Community)
41+
| link:https://github.com/proxy-wasm/proxy-wasm-cpp-sdk[proxy-wasm/proxy-wasm-cpp-sdk]
42+
43+
| Go
44+
| tetrate.io
45+
| link:https://github.com/tetratelabs/proxy-wasm-go-sdk[tetratelabs/proxy-wasm-go-sdk]
46+
47+
| Rust
48+
| proxy-wasm team (Istio Community)
49+
| link:https://github.com/proxy-wasm/proxy-wasm-rust-sdk[proxy-wasm/proxy-wasm-rust-sdk]
50+
|===
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
////
2+
This module included in the following assemblies:
3+
*service_mesh_/v2x/ossm-extensions.adoc
4+
////
5+
:_content-type: REFERENCE
6+
[id="ossm-wasm-ref-smextension_{context}"]
7+
= ServiceMeshExtension reference
8+
9+
The ServiceMeshExtension API provides a mechanism to extend the functionality provided by the Istio proxy through WebAssembly filters. There are two parts to writing a WebAssembly extension:
10+
11+
. Write your extension using an SDK that exposes the proxy-wasm API and compile it to a WebAssembly module.
12+
. Package it into a container.
13+
14+
[NOTE]
15+
====
16+
When creating new WebAssembly extensions, use WasmPlugin. ServiceMeshExtension is deprecated as of {SMProductName} version 2.2 and will be removed in a future release.
17+
====
18+
19+
.ServiceMeshExtension Field Reference
20+
[options="header"]
21+
[cols="a, a"]
22+
|===
23+
| Field | Description
24+
25+
|metadata.namespace
26+
|The `metadata.namespace` field of a `ServiceMeshExtension` source has a special semantic: if it equals the Control Plane Namespace, the extension will be applied to all workloads in the Service Mesh that match its `workloadSelector` value. When deployed to any other Mesh Namespace, it will only be applied to workloads in that same Namespace.
27+
28+
|spec.workloadSelector
29+
|The `spec.workloadSelector` field has the same semantic as the `spec.selector` field of the link:https://istio.io/v1.6/docs/reference/config/networking/gateway/#Gateway[Istio Gateway resource]. It will match a workload based on its Pod labels. If no `workloadSelector` value is specified, the extension will be applied to all workloads in the namespace.
30+
31+
|spec.config
32+
|This is a structured field that will be handed over to the extension, with the semantics dependent on the extension you are deploying.
33+
34+
|spec.image
35+
|A container image URI pointing to the image that holds the extension.
36+
37+
|spec.phase
38+
|The phase determines where in the filter chain the extension is injected, in relation to existing Istio functionality like Authentication, Authorization and metrics generation. Valid values are: PreAuthN, PostAuthN, PreAuthZ, PostAuthZ, PreStats, PostStats. This field defaults to the value set in the `manifest.yaml` file of the extension, but can be overwritten by the user.
39+
40+
|spec.priority
41+
|If multiple extensions with the same `spec.phase` value are applied to the same workload instance, the `spec.priority` value determines the ordering of execution. Extensions with higher priority will be executed first. This allows for inter-dependent extensions. This field defaults to the value set in the `manifest.yaml` file of the extension, but can be overwritten by the user.
42+
|===
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
////
2+
This module included in the following assemblies:
3+
*service_mesh_/v2x/ossm-extensions.adoc
4+
////
5+
:_content-type: REFERENCE
6+
[id="ossm-wasm-ref-wasmplugin_{context}"]
7+
= WasmPlugin API reference
8+
9+
The WasmPlugins API provides a mechanism to extend the functionality provided by the Istio proxy through WebAssembly filters.
10+
11+
You can deploy multiple WasmPlugins. The `phase` and `priority` settings determine the order of execution (as part of Envoy's filter chain), allowing the configuration of complex interactions between user-supplied WasmPlugins and Istio’s internal filters.
12+
13+
In the following example, an authentication filter implements an OpenID flow and populates the Authorization header with a JSON Web Token (JWT). Istio authentication consumes this token and deployes it to the ingress gateway. The WasmPlugin file lives in the proxy sidecar filesystem. Note the field `url`.
14+
15+
[source,yaml]
16+
----
17+
apiVersion: extensions.istio.io/v1alpha1
18+
kind: WasmPlugin
19+
metadata:
20+
name: openid-connect
21+
namespace: istio-ingress
22+
spec:
23+
selector:
24+
matchLabels:
25+
istio: ingressgateway
26+
url: file:///opt/filters/openid.wasm
27+
sha256: 1ef0c9a92b0420cf25f7fe5d481b231464bc88f486ca3b9c83ed5cc21d2f6210
28+
phase: AUTHN
29+
pluginConfig:
30+
openid_server: authn
31+
openid_realm: ingress
32+
----
33+
34+
Below is the same example, but this time an Open Container Initiative (OCI) image is used instead of a file in the filesystem. Note the fields `url`, `imagePullPolicy`, and `imagePullSecret`.
35+
36+
[source,yaml]
37+
----
38+
apiVersion: extensions.istio.io/v1alpha1
39+
kind: WasmPlugin
40+
metadata:
41+
name: openid-connect
42+
namespace: istio-system
43+
spec:
44+
selector:
45+
matchLabels:
46+
istio: ingressgateway
47+
url: oci://private-registry:5000/openid-connect/openid:latest
48+
imagePullPolicy: IfNotPresent
49+
imagePullSecret: private-registry-pull-secret
50+
phase: AUTHN
51+
pluginConfig:
52+
openid_server: authn
53+
openid_realm: ingress
54+
----
55+
56+
.WasmPlugin Field Reference
57+
[options="header"]
58+
[cols="a, a, a, a"]
59+
|===
60+
| Field | Type | Description | Required
61+
62+
|spec.selector
63+
|WorkloadSelector
64+
|Criteria used to select the specific set of pods/VMs on which this plug-in configuration should be applied. If omitted, this configuration will be applied to all workload instances in the same namespace. If the `WasmPlugin` field is present in the config root namespace, it will be applied to all applicable workloads in any namespace.
65+
|No
66+
67+
|spec.url
68+
|string
69+
|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.
70+
|No
71+
72+
|spec.sha256
73+
|string
74+
|SHA256 checksum that will be used to verify the 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.
75+
|No
76+
77+
|spec.imagePullPolicy
78+
|PullPolicy
79+
|The pull behavior to be applied when fetching an OCI image. Only relevant when images are referenced by tag instead of SHA. Defaults to the value `IfNotPresent`, except when an OCI image is referenced in the `url` field and the `latest` tag is used, in which case the value `Always` is the default, mirroring K8s behavior. Setting is ignored if the `url` field is referencing a Wasm module directly using `file://` or `http[s]://`.
80+
|No
81+
82+
|spec.imagePullSecret
83+
|string
84+
|Credentials to use for OCI image pulling. The name of a secret in the same namespace as the `WasmPlugin` object that contains a pull secret for authenticating against the registry when pulling the image.
85+
|No
86+
87+
|spec.phase
88+
|PluginPhase
89+
|Determines where in the filter chain this `WasmPlugin` object is injected.
90+
|No
91+
92+
|spec.priority
93+
|`int64`
94+
|Determines the ordering of `WasmPlugins` objects that have the same `phase` value. When multiple `WasmPlugins` objects are applied to the same workload in the same phase, they will be applied by priority and in descending order. If the `priority` field is not set, or two `WasmPlugins` objects with the same value, the ordering will be determined from the name and namespace of the `WasmPlugins` objects. Defaults to the value `0`.
95+
|No
96+
97+
|spec.pluginName
98+
|string
99+
|The plug-in name used in the Envoy configuration. Some Wasm modules might require this value to select the Wasm plug-in to execute.
100+
|No
101+
102+
|spec.pluginConfig
103+
|Struct
104+
|The configuration that will be passed on to the plug-in.
105+
|No
106+
107+
|spec.pluginConfig.verificationKey
108+
|string
109+
|The public key used to verify signatures of signed OCI images or Wasm modules. Must be supplied in PEM format.
110+
|No
111+
|===
112+
113+
The `WorkloadSelector` object specifies the criteria used to determine if a filter can be applied to a proxy. The matching criteria includes the metadata associated with a proxy, workload instance information such as labels attached to the pod/VM, or any other information that the proxy provides to Istio during the initial handshake. If multiple conditions are specified, all conditions need to match in order for the workload instance to be selected. Currently, only label based selection mechanism is supported.
114+
115+
.WorkloadSelector
116+
[options="header"]
117+
[cols="a, a, a, a"]
118+
|===
119+
| Field | Type | Description | Required
120+
|matchLabels
121+
|map<string, string>
122+
|One or more labels that indicate a specific set of pods/VMs on which a policy should be applied. The scope of label search is restricted to the configuration namespace in which the resource is present.
123+
|Yes
124+
|===
125+
126+
The `PullPolicy` object specifies the pull behavior to be applied when fetching an OCI image.
127+
128+
.PullPolicy
129+
[options="header"]
130+
[cols="a, a"]
131+
|===
132+
| Value | Description
133+
|<empty>
134+
|Defaults to the value `IfNotPresent`, except for OCI images with tag latest, for which the default will be the value `Always`.
135+
136+
|IfNotPresent
137+
|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.
138+
139+
|Always
140+
|We will always pull the latest version of an image when applying this plugin.
141+
|===
142+
143+
`Struct` represents a structured data value, consisting of fields which map to dynamically typed values. In some languages, Struct might be supported by a native representation. For example, in scripting languages like JavaScript a struct is represented as an object.
144+
145+
.Struct
146+
[options="header"]
147+
[cols="a, a, a"]
148+
|===
149+
| Field | Type | Description
150+
|fields
151+
|map<string, Value>
152+
|Map of dynamically typed values.
153+
|===
154+
155+
`PluginPhase` specifies the phase in the filter chain where the plugin will be injected.
156+
157+
.PluginPhase
158+
[options="header"]
159+
[cols="a, a"]
160+
|===
161+
| Field | Description
162+
|<empty>
163+
|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.
164+
165+
|AUTHN
166+
|Insert plugin before Istio authentication filters.
167+
168+
|AUTHZ
169+
|Insert plugin before Istio authorization filters and after Istio authentication filters.
170+
171+
|STATS
172+
|Insert plugin before Istio stats filters and after Istio authorization filters.
173+
|===
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
////
2+
This module included in the following assemblies:
3+
*service_mesh_/v2x/ossm-extensions.adoc
4+
////
5+
:_content-type: PROCEDURE
6+
[id="ossm-smextensions-deploy_{context}"]
7+
= Deploying `ServiceMeshExtension` resources
8+
9+
You can enable {SMProductName} extensions using the `ServiceMeshExtension` resource. In this example, `istio-system` is the name of the control plane project.
10+
11+
[NOTE]
12+
====
13+
When creating new WebAssembly extensions, use WasmPlugin. ServiceMeshExtension is deprecated as of {SMProductName} version 2.2 and will be removed in a future release.
14+
====
15+
16+
For a complete example that was built using the Rust SDK, take a look at the link:https://github.com/maistra/header-append-filter[header-append-filter]. It is a simple filter that appends one or more headers to the HTTP responses, with their names and values taken out from the `config` field of the extension. See a sample configuration in the snippet below.
17+
18+
.Procedure
19+
20+
. Create the following example resource:
21+
+
22+
.Example ServiceMeshExtension resource extension.yaml
23+
[source,yaml]
24+
----
25+
apiVersion: maistra.io/v1
26+
kind: ServiceMeshExtension
27+
metadata:
28+
name: header-append
29+
namespace: istio-system
30+
spec:
31+
workloadSelector:
32+
labels:
33+
app: httpbin
34+
config:
35+
first-header: some-value
36+
another-header: another-value
37+
image: quay.io/maistra-dev/header-append-filter:2.1
38+
phase: PostAuthZ
39+
priority: 100
40+
----
41+
42+
. Apply your `extension.yaml` file with the following command:
43+
+
44+
[source,terminal]
45+
----
46+
$ oc apply -f <extension>.yaml
47+
----
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
////
2+
This module included in the following assemblies:
3+
*service_mesh_/v2x/ossm-extensions.adoc
4+
////
5+
:_content-type: REFERENCE
6+
[id="ossm-extensions-smextension-format_{context}"]
7+
= `ServiceMeshExtension` container format
8+
9+
You must have a `.wasm` file containing the bytecode of your WebAssembly module, and a `manifest.yaml` file in the root of the container filesystem to make your container image a valid extension image.
10+
11+
[NOTE]
12+
====
13+
When creating new WebAssembly extensions, use WasmPlugin. ServiceMeshExtension is deprecated as of {SMProductName} version 2.2 and will be removed in a future release.
14+
====
15+
16+
.manifest.yaml
17+
[source,yaml]
18+
----
19+
schemaVersion: 1
20+
21+
name: <your-extension>
22+
description: <description>
23+
version: 1.0.0
24+
phase: PreAuthZ
25+
priority: 100
26+
module: extension.wasm
27+
----
28+
29+
.Field Reference for manifest.yml
30+
[options="header"]
31+
[cols="a, a, a"]
32+
|===
33+
| Field | Description |Required
34+
35+
|schemaVersion
36+
|Used for versioning of the manifest schema. Currently the only possible value is `1`.
37+
|This is a required field.
38+
39+
|name
40+
|The name of your extension.
41+
|This field is just metadata and currently unused.
42+
43+
|description
44+
|The description of your extension.
45+
|This field is just metadata and currently unused.
46+
47+
|version
48+
|The version of your extension.
49+
|This field is just metadata and currently unused.
50+
51+
|phase
52+
|The default execution phase of your extension.
53+
|This is a required field.
54+
55+
|priority
56+
|The default priority of your extension.
57+
|This is a required field.
58+
59+
|module
60+
|The relative path from the container filesystem's root to your WebAssembly module.
61+
|This is a required field.
62+
|===

0 commit comments

Comments
 (0)