Local Testing Quickstart
Test Nucleus permission enforcement locally without Kubernetes or Firecracker.
Prerequisites
- Rust toolchain (1.75+)
curlandjqfor testing
1. Build the Tool Proxy
cargo build -p nucleus-tool-proxy --release
2. Start the Tool Proxy
./target/release/nucleus-tool-proxy \
--spec examples/openclaw-demo/pod.yaml \
--listen 127.0.0.1:8080 \
--auth-secret demo-secret \
--approval-secret approval-secret \
--audit-log /tmp/nucleus-demo-audit.log
The demo profile includes the uninhabitable state (read + web + bash), so all bash commands require approval.
3. Test Permission Enforcement
Create a helper function for signed requests:
nucleus_call() {
local ENDPOINT=$1
local BODY=$2
local TIMESTAMP=$(date +%s)
local ACTOR="test"
local MESSAGE="${TIMESTAMP}.${ACTOR}.${BODY}"
local SIGNATURE=$(echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "demo-secret" | awk '{print $2}')
curl -s -X POST "http://127.0.0.1:8080/v1/${ENDPOINT}" \
-H "Content-Type: application/json" \
-H "X-Nucleus-Timestamp: ${TIMESTAMP}" \
-H "X-Nucleus-Actor: ${ACTOR}" \
-H "X-Nucleus-Signature: ${SIGNATURE}" \
-d "${BODY}"
}
Test Cases
Read allowed file (should succeed):
nucleus_call "read" '{"path":"README.md"}' | jq -r '.contents[:100]'
# Output: # Nucleus...
Read sensitive file (should be blocked):
nucleus_call "read" '{"path":".env"}' | jq '.error'
# Output: "nucleus error: access denied: path '.env' blocked by policy"
Run git status (requires approval due to uninhabitable state):
nucleus_call "run" '{"command":"git status"}' | jq '.'
# Output: {"error":"nucleus error: approval required...","kind":"approval_required"}
Run bash -c (blocked by command policy + uninhabitable state):
nucleus_call "run" '{"command":"bash -c \"echo hi\""}' | jq '.kind'
# Output: "approval_required"
4. Verify Audit Log
cat /tmp/nucleus-demo-audit.log | jq '{event, subject, result}'
Each entry includes:
- Hash-chained integrity (
prev_hash,hash) - HMAC signature (
signature) - Actor tracking
Expected Results
| Test | Expected | Reason |
|---|---|---|
| Read README.md | Success | Allowed path |
| Read .env | Blocked | Sensitive path pattern |
| git status | Approval required | Uninhabitable state active (read + web + bash) |
| bash -c | Approval required | Shell interpreter blocked + uninhabitable state |
Why Uninhabitable state Triggers
The demo profile has:
read_files: Always(private data access)web_fetch: LowRisk(untrusted content)run_bash: LowRisk(exfiltration vector)
All three legs of the “uninhabitable state” are present, so Nucleus automatically requires approval for exfiltration operations (run_bash, git_push, create_pr).
This protects against prompt injection attacks that could steal secrets via web content.
Test with Network-Isolated Profile
For testing without uninhabitable state protection, use the codegen profile which has no web access:
# codegen-pod.yaml
apiVersion: nucleus/v1
kind: Pod
metadata:
name: codegen-test
spec:
work_dir: .
timeout_seconds: 3600
policy:
type: profile
name: codegen
./target/release/nucleus-tool-proxy \
--spec codegen-pod.yaml \
--listen 127.0.0.1:8080 \
--auth-secret demo-secret \
--approval-secret approval-secret \
--audit-log /tmp/codegen-audit.log
With codegen, bash commands will succeed without approval (no uninhabitable state because web_fetch: Never).
Next Steps
- Kubernetes Quickstart - Production deployment
- Permission Profiles - All available profiles
- OpenClaw Integration - Full OpenClaw adapter setup