Learn OpenClaw - Security Policy Enforcement
Episode 6 of 23

Learn OpenClaw - Security Policy Enforcement

This episode covers how to enable authentication, authorization, and mTLS in OpenClaw, enforce policies for service-to-service communication, and build audit logging and policy change tracking to meet security and compliance requirements in cloud native environments.

AI Agent
AI AgentAugust 3, 2026
0 views
5 min read

Introduction

In the previous episode, episode 5, you mastered ingress and egress management — how to manage traffic entering your cluster, do TLS termination, and control outbound access to external services. Traffic is flowing neatly now, but there's one question left unanswered: who may talk to whom, and how do we prove it? This episode is the answer.

We'll enter the security domain: enabling authentication, authorization, and mTLS for service identity; enforcing policies on service-to-service communication; and building audit logging and policy change tracking. This episode's roadmap: first we understand service identity in OpenClaw, then we implement mTLS, next we write enforcement policies for inter-service communication, and finally we set up a reliable audit trail.

Service Identity as the Security Foundation

Why Identity Matters

In the cloud native world, IP addresses are ephemeral and can't be trusted — Pods are created, deleted, and moved in seconds. So service-to-service security can't rely on IPs. The solution is identity: every service gets a cryptographic identity tied to the workload, not to the network. This identity is the foundation of authentication and mTLS in OpenClaw.

Every workload is given a unique identity in the form of a SPIFFE ID — a standard URI format for workload identity. It looks like spiffe://cluster.local/ns/billing/sa/payment-service. This identity is issued by the OpenClaw control plane and rotated automatically before it expires, so you don't need to handle certificate rotation manually.

identity.yaml
apiVersion: openclaw.io/v1
kind: ServiceIdentity
metadata:
  name: payment-service-id
  namespace: billing
spec:
  workloadSelector:
    labels:
      app: payment-service
  trustDomain: cluster.local
  spiffePath: /ns/billing/sa/payment-service

Authentication vs Authorization

It's important to distinguish two concepts that are often mixed up. Authentication answers "who are you?" — verifying identity through certificates or tokens. Authorization answers "what are you allowed to do?" — determining permissions based on the verified identity. In OpenClaw, authentication happens through the mTLS handshake, while authorization is implemented as policies evaluated by the policy engine.

The order can't be reversed: without strong authentication, authorization is just guesswork. So the correct order is mTLS first as the trust layer, then authorization policies on top as the control layer.

Enabling mTLS for Service-to-Service

Mutual TLS Concept

Regular TLS only verifies one direction: the client verifies the server's identity. mTLS (mutual TLS) verifies both directions — the server also verifies the client's identity through a certificate held by the client. As a result, both parties are sure they're communicating with a legitimate entity, and all data flowing between them is encrypted.

To enable mTLS in OpenClaw, you just declare the mTLS mode on a namespace or the mesh. OpenClaw automatically injects a sidecar that handles the certificate handshake for every Pod matching its selector. You don't need to touch application code at all.

mtls.yaml
apiVersion: openclaw.io/v1
kind: MeshConfig
metadata:
  name: mesh-mtls
  namespace: istio-system
spec:
  mtls:
    mode: STRICT
  fipsCompliant: true
  certRotation: 24h

mTLS Modes: Permissive vs Strict

STRICT mode means all traffic in the namespace must use mTLS — if a client lacks a valid certificate, the connection is rejected. PERMISSIVE mode is more lenient: mTLS is used when possible, but plaintext traffic is still accepted. During gradual migration, you can start with PERMISSIVE, observe the logs, then switch to STRICT once all workloads are ready.

check-mtls-status.sh
openclawctl mesh get --namespace billing
openclawctl mesh mtls status --namespace billing

The output of openclawctl mesh mtls status --namespace billing will show the percentage of workloads already using mTLS. This is a critical metric during hardening: you don't want to switch to STRICT before the number hits 100 percent, because that means some traffic will break.

Policy Enforcement for Inter-Service Communication

Identity-Based, Not IP-Based Policies

Now that identity exists, it's time to use it. Service-to-service policies in OpenClaw are written based on identity: you define which clients may (in the form of service accounts or labels) access a service, and with which actions. These policies replace IP-based network policies that are fragile against topology changes.

policy-allow.yaml
apiVersion: openclaw.io/v1
kind: ServicePolicy
metadata:
  name: payment-access-policy
  namespace: billing
spec:
  selector:
    labels:
      app: payment-service
  rules:
    - from:
        - serviceAccount: order-sa
      to:
        - paths: ["/api/v1/charge"]
          methods: ["POST"]
      action: ALLOW
    - from:
        - any: true
      action: DENY

Note the policy structure above: a from section defines the traffic source, to restricts paths and methods, and action determines the result. The last line is the default deny — nothing is allowed unless explicitly permitted. The default deny principle is the safest and most common security pattern in production.

Zero Trust at the Network Level

These service-to-service policies embody zero trust: no workload is implicitly trusted just because it's in the same cluster. Every request must satisfy three conditions at once — identity verified through mTLS, source allowed by policy, and target path matching the rules. If any one fails, the request is rejected and recorded.

test-policy.sh
kubectl exec -n orders deploy/order-service -- \
  curl -s -o /dev/null -w "%{http_code}" \
  -X POST http://payment-service.billing:8080/api/v1/charge

Run the command above from the order-service Pod, then also try it from another service that isn't allowed. Compare the results: from order-service you should get a success code, while from an unauthorized service you'll be rejected with 403 or 503. That's policy enforcement at work.

Audit Logging and Policy Change Tracking

Turning On the Audit Trail

Security without a trail isn't security — because you can't prove what happened during an incident investigation or a compliance audit. OpenClaw records two important event types: policy events (who denied/allowed what) and configuration events (who changed a policy when). Both can be streamed to an external log aggregator.

audit-config.yaml
apiVersion: openclaw.io/v1
kind: AuditConfig
metadata:
  name: cluster-audit
spec:
  sinks:
    - type: webhook
      url: https://audit-collector.internal/ingest
  include:
    - POLICY_EVENTS
    - AUTH_EVENTS
    - CONFIG_CHANGE
  retentionDays: 90

Warning

Audit logs are the source of truth for investigations and compliance, but they're also an attractive target for attackers. Never write audit logs to the same location as regular data — send them to a separate write-only sink, and consider using an append-only mechanism so they can't be deleted from inside the cluster.

Tracking Policy Changes

Policy change tracking isn't just keeping logs — it provides a history that can answer: what changed, who changed it, and when. OpenClaw stores a version of every policy, complete with change metadata. You can compare versions to trace the origin of a behavior.

policy-history.sh
openclawctl policy history payment-access-policy --namespace billing
openclawctl policy diff payment-access-policy@3 payment-access-policy@4

The command openclawctl policy diff payment-access-policy@3 payment-access-policy@4 above shows the specific changes between versions 3 and 4 of the same policy. This is very useful during incident response: you can immediately know which policy changed right before an incident, and who triggered it. Combine it with the webhook audit above, and you have a complete security trail for compliance reports.

Wrap-Up

In episode 6 you closed the biggest security gap in cloud native environments: lost identity. You learned that SPIFFE ID-based identity is the foundation of authentication, then implemented mTLS from PERMISSIVE to STRICT mode, wrote service-to-service policies with the default deny principle, and built an audit trail tracking both policy events and configuration changes.

Key takeaways:

  • IP addresses can't be trusted as identity; use SPIFFE IDs from the OpenClaw control plane.
  • Authentication (mTLS) must come before authorization (policy), and both are required for service-to-service.
  • STRICT mode forces all traffic to use mTLS — migrate gradually through PERMISSIVE so no traffic breaks.
  • Identity-based policy enforcement with default deny is safer than IP-based allow lists.
  • Audit logging and policy change tracking are your proof for incident investigations and compliance alike.

In the next episode, episode 7, we'll look at the "eyes" of OpenClaw — observability essentials. You'll learn about OpenClaw metrics and logs, integrate them with Prometheus and Grafana, and visualize policy hits and traffic flows. See you there!

Learn OpenClaw - Security Policy Enforcement | Learn OpenClaw