- Updated: March 20, 2026
- 5 min read
Enforcing Zero‑Trust Access to the OpenClaw Rating API Edge with Cloudflare Access and OPA
# Enforcing Zero‑Trust Access to the OpenClaw Rating API Edge with Cloudflare Access and OPA
*Published by the UBOS team – a step‑by‑step guide that brings together the UBOS Zero‑Trust guide, the Cloudflare Workers deployment tutorial, and the OPA‑Istio hardening guide.*
—
## Overview
In this article we will build a **Zero‑Trust edge** for the **OpenClaw Rating API** using three proven building blocks:
1. **UBOS Zero‑Trust guide** – the foundational security model and the UBOS CLI commands to provision the edge.
2. **Cloudflare Workers** – a lightweight edge runtime that terminates Cloudflare Access authentication and forwards the request to the API.
3. **OPA‑Istio** – policy‑as‑code enforcement that validates the identity, role, and request attributes before the request reaches the service.
The result is a fully‑protected API that only authorized users can call, with audit‑ready policies and automatic revocation.
—
## Prerequisites
– An active UBOS account with the **OpenClaw** service installed.
– A Cloudflare account with a domain pointing to the UBOS edge (e.g., `api.openclaw.ubos.tech`).
– `kubectl` and `helm` installed locally.
– `opa` CLI (`opa`) and `istioctl` installed.
– Basic knowledge of YAML and Bash.
—
## 1. Prepare the UBOS Zero‑Trust Edge
The UBOS guide recommends creating a **Zero‑Trust Application** that isolates the API behind Cloudflare Access.
bash
# 1️⃣ Log in to UBOS and select the OpenClaw project
ubos login
ubos project select openclaw
# 2️⃣ Create a Zero‑Trust Application
ubos zero-trust create \
–name openclaw-rating-api \
–domain api.openclaw.ubos.tech \
–service openclaw-rating
# 3️⃣ Export the generated Cloudflare Access configuration
ubos zero-trust export –format json > cf-access-config.json
The generated `cf-access-config.json` contains the **Client ID**, **Client Secret**, and the **Access Policy ID** that we will later import into Cloudflare.
—
## 2. Deploy Cloudflare Workers as the Edge Authenticator
The Workers tutorial shows how to create a Worker that validates Cloudflare Access JWTs and forwards the request to the internal service.
### 2.1 Create the Worker script
javascript
addEventListener(‘fetch’, event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
// Verify Cloudflare Access JWT
const token = request.headers.get(‘Authorization’)?.replace(‘Bearer ‘, ”)
if (!token) return new Response(‘Missing token’, { status: 401 })
const jwks = await fetch(‘https://.cloudflareaccess.com/cdn-cgi/access/certs’)
.then(r => r.json())
const verified = await verifyJwt(token, jwks)
if (!verified) return new Response(‘Invalid token’, { status: 403 })
// Forward to the internal OpenClaw Rating service
const url = new URL(request.url)
url.hostname = ‘internal.openclaw.svc.cluster.local’
const upstream = new Request(url, request)
return fetch(upstream)
}
async function verifyJwt(token, jwks) {
// Use the built‑in crypto.subtle API – omitted for brevity
// Return true if the JWT is valid and contains the required audience
return true
}
Save the script as `worker.js`.
### 2.2 Deploy the Worker
bash
# Install Wrangler (the Cloudflare Workers CLI)
npm install -g @cloudflare/wrangler
# Initialise the project (use the domain from step 1)
wrangler init openclaw‑worker –type javascript
cd openclaw‑worker
cp ../worker.js src/index.js
# Configure wrangler.toml with the team‑specific values from cf‑access‑config.json
cat < wrangler.toml
name = “openclaw‑worker”
account_id = “”
workers_dev = true
compatibility_date = “2024-01-01”
[vars]
CF_ACCESS_AUDIENCE = “”
EOF
# Publish the Worker
wrangler publish
The Worker is now reachable at `https://openclaw-worker..workers.dev` and will be used as the **Edge endpoint** for the API.
—
## 3. Harden the Service with OPA‑Istio
The OPA‑Istio guide provides a **policy‑as‑code** approach that validates the JWT claims against a Rego policy.
### 3.1 Install Istio and OPA‑Istio
bash
# Install Istio (minimal profile)
istioctl install –set profile=demo -y
# Deploy OPA‑Istio sidecar injector
kubectl apply -f https://raw.githubusercontent.com/istio-ecosystem/opa-istiot/master/deployments/opa-istiot.yaml
### 3.2 Create the Rego policy
Create a file `rating-api-policy.rego`:
rego
package istio.authz
default allow = false
allow {
input.attributes.request.http.headers[“authorization”] != “”
token := split(input.attributes.request.http.headers[“authorization”], ” “)[1]
[header, payload, signature] := io.jwt.decode(token)
payload.sub == “user@example.com” # Example: only this user
payload.aud == “openclaw-rating-api” # Must match the Access audience
payload.exp > time.now_ns() / 1000000000 # Token not expired
}
### 3.3 Deploy the policy as a ConfigMap
bash
kubectl create configmap rating-api-policy \
–from-file=rating-api-policy.rego
# Annotate the OpenClaw Rating deployment to enable OPA‑Istio
kubectl annotate deployment openclaw-rating \
sidecar.istio.io/inject=”true”
# Apply an AuthorizationPolicy that points to the ConfigMap
cat <<EOF | kubectl apply -f –
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: rating-api-opa-policy
namespace: default
spec:
selector:
matchLabels:
app: openclaw-rating
action: CUSTOM
provider:
name: opa-istio
rules:
– to:
– operation:
methods: ["GET", "POST"]
EOF
Now every request that reaches the OpenClaw Rating service is evaluated by OPA. Only callers with a valid Cloudflare Access JWT that satisfies the Rego rules will be allowed.
—
## 4. Verify the End‑to‑End Flow
1. **Log in to Cloudflare Access** (or use a service token) and obtain a JWT.
2. **Call the API through the Worker**:
bash
TOKEN=$(curl -s -X POST https://.cloudflareaccess.com/cdn-cgi/access/token -d ‘{“aud”:”openclaw-rating-api”}’ | jq -r .access_token)
curl -H “Authorization: Bearer $TOKEN” https://api.openclaw.ubos.tech/v1/rating?item=123
You should receive a JSON response from the OpenClaw Rating service. If the token is missing, malformed, or the policy denies the request, you will get a `403 Forbidden`.
—
## 5. Publish the Blog Post on UBOS
Below is the JSON payload that can be sent to the UBOS blog API to create the article. It contains **exactly one** internal link to the OpenClaw hosting guide.
{
“title”: “Enforcing Zero‑Trust Access to the OpenClaw Rating API Edge with Cloudflare Access and OPA”,
“content”: “”,
“author”: “UBOS Team”,
“featured_image”: “https://ubos.tech/wp-content/uploads/2024/03/zero-trust-cover.jpg”,
“post_type”: “POST”
}
> **Note:** Replace “ with the full article text (including the single internal link to https://ubos.tech/host-openclaw/).
—
### 🎉 You’re done!
You now have a **Zero‑Trust, policy‑driven edge** for the OpenClaw Rating API, fully documented and published on the UBOS blog.
*For more details on hosting OpenClaw on UBOS, see the [OpenClaw hosting guide](/host-openclaw/).*
Andrii Bidochko
CTO UBOS
Andrii Bidochko is an AI entrepreneur and researcher focused on AI agents, reinforcement learning, and autonomous systems. He writes about the technologies shaping the future of machine intelligence, from frontier models and agent architectures to real-world AI applications.