istio
istio copied to clipboard
Support for Kubernetes secret to pass a key within `PluginConfig` for `WasmPlugin`
Describe the feature request
Support for Kubernetes secret to pass PluginConfig for WasmPlugin, i.e there is a need to pass client secret as k8s secret for OIDC workflow to work under the custom WasmPlugin, to avoid plain text using PluginConfig and after on extend secret to be pushed by the cloud provider.
Describe alternatives you've considered
Technically using Envoyfilter the whole configuration can be provided as k8s secret however the goal is to split the configuration into multiple configmaps and secrets or should be extensions.wasm.v3.EnvironmentVariables used?
Affected product area (please put an X in all that apply)
[ ] Ambient [ ] Docs [ ] Installation [ ] Networking [ ] Performance and Scalability [X] Extensions and Telemetry [ ] Security [ ] Test and Release [ ] User Experience [ ] Developer Infrastructure
Affected features (please put an X in all that apply) [X] WASM
Additional context
Related discussion https://github.com/istio/istio/pull/45411
Thinking about it a little bit more, this requirement here is like Kubernetes downward API. Kubernetes has supported setting a env from secret/configmap https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-environment-variables.
// EnvVar represents an environment variable present in a Container.
type EnvVar struct {
// Name of the environment variable. Must be a C_IDENTIFIER.
Name string `json:"name" protobuf:"bytes,1,opt,name=name"`
// Optional: no more than one of the following may be specified.
// Variable references $(VAR_NAME) are expanded
// using the previously defined environment variables in the container and
// any service environment variables. If a variable cannot be resolved,
// the reference in the input string will be unchanged. Double $$ are reduced
// to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e.
// "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)".
// Escaped references will never be expanded, regardless of whether the variable
// exists or not.
// Defaults to "".
// +optional
Value string `json:"value,omitempty" protobuf:"bytes,2,opt,name=value"`
// Source for the environment variable's value. Cannot be used if value is not empty.
// +optional
ValueFrom *EnvVarSource `json:"valueFrom,omitempty" protobuf:"bytes,3,opt,name=valueFrom"`
}
// EnvVarSource represents a source for the value of an EnvVar.
type EnvVarSource struct {
// Selects a field of the pod: supports metadata.name, metadata.namespace, `metadata.labels['<KEY>']`, `metadata.annotations['<KEY>']`,
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
// +optional
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
// Selects a resource of the container: only resources limits and requests
// (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.
// +optional
ResourceFieldRef *ResourceFieldSelector `json:"resourceFieldRef,omitempty" protobuf:"bytes,2,opt,name=resourceFieldRef"`
// Selects a key of a ConfigMap.
// +optional
ConfigMapKeyRef *ConfigMapKeySelector `json:"configMapKeyRef,omitempty" protobuf:"bytes,3,opt,name=configMapKeyRef"`
// Selects a key of a secret in the pod's namespace
// +optional
SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty" protobuf:"bytes,4,opt,name=secretKeyRef"`
}
as we can see in k8s, the secret is not authorized at all, the only limitation is: it must reside in same namespace as the pod.
I think we can use similar schema for wasm, and for security, we can enforce more authz policy.
secret is not authorized at all, the only limitation is:
it actually is - in service account you can limit what secrets can be mounted or used like this
Maybe i missed that. In istiod we can do the authz based on rbac as well, I think we already do rbac for sds.
Here is the first iteration to leverage environment variable to pass a secret... not sure if it is an approach that should be endorsed in a scale...
the wasm plugin:
apiVersion: [extensions.istio.io/v1alpha1](http://extensions.istio.io/v1alpha1)
kind: WasmPlugin
metadata:
name: wasm-example
namespace: default
spec:
selector:
matchLabels:
app: ingress
url: oci://[REPOSITORY]/wasm:v1
pluginConfig:
openid_server: authn
openid_realm: ingress
vmConfig:
env:
- name: SECRET
valueFrom: SECRET
The SECRET environment variable has to be mapped to envoy sidecar (which is WASM VM) so that will require to use a custom template using inject.istio.io/templates (https://istio.io/latest/docs/setup/additional-setup/sidecar-injection/#custom-templates-experimental) for the given deployment,.
apiVersion: [install.istio.io/v1alpha1](http://install.istio.io/v1alpha1)
kind: IstioOperator
metadata:
name: istio
spec:
values:
sidecarInjectorWebhook:
templates:
custom: |
spec:
containers:
- name: istio-proxy
env:
- name: SECRET
valueFrom:
secretKeyRef:
name: secret
key: password
🚧 This issue or pull request has been closed due to not having had activity from an Istio team member since 2024-02-17. If you feel this issue or pull request deserves attention, please reopen the issue. Please see this wiki page for more information. Thank you for your contributions.
Created by the issue and PR lifecycle manager.
Would indeed be nice to have a way to configure a wasm plugin with secrets in a proper way without leaking it to all manifests and logs.