Zero-Trust security sandbox for OpenClaw agents. Every agent output is treated as hostile; validation and sandboxing are deterministic and local-first.
npm installnpm run buildnpm run test- Use
createSecurityGuardrail()to getauthority,schema,sandbox,trust.
import { createSecurityGuardrail } from "openclaw-security-guardrail";
import { z } from "zod";
const guardrail = createSecurityGuardrail();
await guardrail.trust.load();
const context = { agentId: "a1", tenantId: "t1", userTier: "pro", skill: "scan" };
guardrail.authority.enforceTier(context);
const safe = guardrail.authority.sanitize({ result: "ok", overrideScore: 99 }).sanitized;
const schema = z.object({ result: z.string(), tenantId: z.string() });
guardrail.schema.validate({ result: "ok", tenantId: "t1" }, schema);
await guardrail.sandbox.execute(async (signal) => {
if (signal.aborted) throw new DOMException("Aborted", "AbortError");
return "done";
});- Skill whitelist per tier is configured in
src/config/security.config.ts. - Resource limits (timeout 30s, 512MB RAM, 50% CPU best-effort, max payload 2MB).
- Forbidden overrides:
overrideScore,userTier,eligibility,newBudgetare stripped. - Schema enforcement: strict JSON validation with payload size limit and sensitive-field detection.
- Always include
tenantIdin agent context and outputs;AuthorityGuard.enforceTenantrejects cross-tenant data. - Cross-tenant leak test lives in
tests/adversarial/cross-tenant.test.ts. - Single-tenant use: set a fixed
tenantId(e.g.,"default") but keep the check enabled to catch accidental mix-ups.
userTierdrives the skill whitelist insecurity.config.ts; agent calls are blocked if the skill is not allowed for that tier.- Guardrail strips any
userTierthe agent tries to return; only the platform sets it. - Single-user mode: set
userTier: "single"(or any label) and configure the corresponding whitelist; keep enforcement on to prevent privilege creep.
- Always pass
AgentContextwithtenantId,userTier,skill. - Wrap every agent call with
guardLlmCallor manually chain:authority.enforceTier(context)authority.sanitize(output)schema.validate(output, schema)sandbox.execute(fn, limits)for skill executiontrust.recordResult(agentId, success)
- Add per-model pricing or trust weights in config as needed.
src/security:AuthorityGuard,SchemaGuard,SandboxWrapper,TrustEnginesrc/domain:SecurityPolicy,AgentContextsrc/config:security.config.tstests/adversarial: override, cross-tenant, resource exhaustion, schema rejectiontests/unit: trust engine persistence
- Local-first: uses JSON files for trust store, no external infra required.
- Deterministic: no AI heuristics; all checks are rule-based.