Skip to main content
Version: 1.9

Raw policies

From v1.9.0 onwards, Kubewarden supports the ability to write and execute policies outside a Kubernetes cluster, as a generic policy evaluation engine. The Policy Server exposes the /validate_raw endpoint that can be used to validate arbitrary JSON documents against a Kubewarden policy.

For this guide, we will use the following raw policies:

note

Please ensure that the policy author has marked the policy as policyType: raw in the metadata. You can inspect the metadata by using kwctl

kwctl inpect ghcr.io/kubewarden/tests/raw-mutation-policy:v0.1.0

Running the policy server outside Kubernetes

The Policy Server can be run outside Kubernetes as a standalone container.

First, create a policies.yml file with the following content:

raw-validation:
url: ghcr.io/kubewarden/tests/raw-validation-policy:v0.1.0
settings:
validUsers:
- alice
- bob
validActions:
- read
- write
validResources:
- orders
- products

raw-mutation:
url: ghcr.io/kubewarden/tests/raw-mutation-policy:v0.1.0
allowedToMutate: true
settings:
forbiddenResources:
- privateResource
- secretResource
defaultResource: publicResource

To start the policy server:

# Create a docker volume to store the policies
docker volume create --driver local \
--opt type=tmpfs \
--opt device=tmpfs \
--opt o=ui=65533 \
policy-store

# Start the policy server
docker run --rm -it \
-p 3000:3000 \
-v $(pwd)/policies.yml:/policies.yml \
-v policy-store:/registry \
ghcr.io/kubewarden/policy-server:1.9.0 \
--ignore-kubernetes-connection-failure=true

NOTE: the flag --ignore-kubernetes-connection-failure=true is required to start the policy server without Kubernetes. However, it is possible to start the Policy Server with/inside Kubernetes and use the raw validation endpoint. Raw policies can access context-aware capabilities like standard policies.

Running a Policy Server inside Kubernetes without the Kubewarden controller

It's not possible to use a Policy Server instance managed by the Kubewarden controller to host raw policies. The controller will not allow the user to change the Policy Server ConfigMap to add a raw policy, since it will try to reconcile it reverting the changes. Because of that, a dedicated Policy Server has to be started.

Create a policy-server.yaml file with the following content:

---
apiVersion: apps/v1
kind: Deployment
metadata:
name: policy-server-deployment
spec:
replicas: 1
selector:
matchLabels:
app: policy-server
template:
metadata:
labels:
app: policy-server
spec:
containers:
- name: policy-server
image: ghcr.io/kubewarden/policy-server:v1.9.0
ports:
- containerPort: 3000
volumeMounts:
- name: policy-store
mountPath: /registry
- name: policies-config
mountPath: /policies.yml
subPath: policies.yml
volumes:
- name: policy-store
emptyDir: {}
- name: policies-config
configMap:
name: policies-configmap
---
apiVersion: v1
kind: Service
metadata:
name: policy-server-service
spec:
selector:
app: policy-server
ports:
- protocol: TCP
port: 3000
targetPort: 3000
---
apiVersion: v1
kind: ConfigMap
metadata:
name: policies-configmap
data:
policies.yml: |
raw-validation:
url: ghcr.io/kubewarden/tests/raw-validation-policy:v0.1.0
settings:
validUsers:
- alice
- bob
validActions:
- read
- write
validResources:
- orders
- products
raw-mutation:
url: ghcr.io/kubewarden/tests/raw-mutation-policy:v0.1.0
allowedToMutate: true
settings:
forbiddenResources:
- privateResource
- secretResource
defaultResource: publicResource

Apply the configuration:

kubectl apply -f policy-server.yaml
info

The Policy Server instance deployed will have access to Kubernetes resources that could be leveraged by context aware policies. The access level to the Kubernetes resources is determined by the Service Account used to run the Policy Server workload.

In the previous example, no Service Account is defined inside of the Deployment specification; hence the default Service Account is going to be used.

Using the validate_raw endpoint

Validation

The raw validation endpoint is exposed at /validate_raw and accepts POST requests. Since we have deployed a service, we can set a port-forward to access it with kubectl port-forward service/policy-server-service 3000:3000 -n default.

Let's try to validate a JSON document against the raw-validation policy:

curl -X POST \
http://localhost:3000/validate_raw/raw-validation \
-H 'Content-Type: application/json' \
-d '{
"request": {
"user": "alice",
"action": "read",
"resource": "customers"
}
}'

The request will be not accepted, since alice has not been granted access to the customers resource:

{
"response": {
"uid": "",
"allowed": false,
"auditAnnotations": null,
"warnings": null
}
}

Let's try again with a valid resource:

curl -X POST \
http://localhost:3000/validate_raw/raw-validation \
-H 'Content-Type: application/json' \
-d '{
"request": {
"user": "alice",
"action": "read",
"resource": "orders"
}
}'

This time, the request will be accepted:

{
"response": {
"uid": "",
"allowed": true,
"auditAnnotations": null,
"warnings": null
}
}
note

If the uid field is provided in the request payload, it will be returned as part of the response.

Mutation

Now, let's try to mutate a JSON document against the raw-mutation policy:

curl -X POST \
http://localhost:3000/validate_raw/raw-mutation \
-H 'Content-Type: application/json' \
-d '{
"request": {
"user": "alice",
"action": "read",
"resource": "privateResource"
}
}'

The request will be mutated and the response will contain a JSONPatch:

{
"response": {
"uid": "",
"allowed": true,
"patchType": "JSONPatch",
"patch": "W3sib3AiOiJyZXBsYWNlIiwicGF0aCI6Ii9yZXNvdXJjZSIsInZhbHVlIjoicHVibGljUmVzb3VyY2UifV0=",
"auditAnnotations": null,
"warnings": null
}
}

Writing raw policies

Similarly to policies that validate Kubernetes resources, raw policies are written in WebAssembly using Kubewarden SDKs. If you are interested in writing raw policies, please refer to language-specific documentation for more information: