Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Local Testing Quickstart

Test Nucleus permission enforcement locally without Kubernetes or Firecracker.

Prerequisites

  • Rust toolchain (1.75+)
  • curl and jq for 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

TestExpectedReason
Read README.mdSuccessAllowed path
Read .envBlockedSensitive path pattern
git statusApproval requiredUninhabitable state active (read + web + bash)
bash -cApproval requiredShell 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