Scarab ScarabRuntime
agentd daemon online | v0.1.0 // now available
Linux-Native AI Agent Runtime

SCARAB RUNTIME

Hardened execution layer for autonomous AI agents.
Isolation via seccomp-BPF, AppArmor, cgroups, and nftables — zero-trust from the kernel up.

Rust
Memory-Safe Core
MIT
Open Source
ash — agent shell ● LIVE
agentd starting...
seccomp-BPF filter loaded
AppArmor profiles compiled
cgroup v2 hierarchy mounted
credential store unlocked
HTTP gateway bound :8080
daemon ready. awaiting connections.
$ ash spawn etc/agents/example-agent.yaml
spawned agent:example-01
trust_level: sandboxed
workspace: /var/scarab/ws/a1b2c3
phase: plan → act → observe
$
example-agent.yaml manifest
apiVersion: scarab/v1
kind: AgentManifest
spec:
trust_level: sandboxed
capabilities:
- fs.read:/workspace/**
- tool.invoke:web-search
- net.connect:api.openai.com
// 01 kernel-level

Hardened

Syscall filtering via seccomp-BPF. AppArmor confinement profiles auto-generated from agent manifests.

// 02 per-agent

Isolated

OverlayFS workspaces with snapshot/rollback. Cgroups v2 hard limits on memory, CPU, and PID exhaustion.

// 03 immutable

Verifiable

SHA-256 hash-chained NDJSON audit logs. Append-only. Tamper-resistant. Every tool call recorded.

4 layers
Kernel Enforcement
seccomp · apparmor · cgroups · nftables
25+ commands
ash CLI
spawn · kill · secrets
AES-256 GCM
Credential Store
Argon2id KDF
MIT license
Open Source
scarab-project
Zero-Trust by Design

Isolation
Architecture

// Kernel Enforcement Stack applied in order, L1 → L4
L1 syscall filter
kernel-enforced

Seccomp-BPF

A BPF program compiled and loaded into the kernel at agent spawn time. Enforces a strict syscall allowlist derived from the agent's trust level. Any unlisted syscall terminates the process immediately with SIGSYS — no fallback, no escalation.

untrusted: ~30 syscalls · sandboxed: ~80 · trusted: ~150 · privileged: unrestricted
L2 MAC profiles
LSM-enforced

AppArmor

Mandatory Access Control profiles auto-generated from the agent's capability manifest at spawn. Restricts filesystem path access, Linux capability bits, and socket operations. Enforced via kernel LSM hooks — no userspace path can bypass confinement.

profiles derived from capabilities[] in manifest.yaml — zero manual policy authoring
L3 resource limits
per-agent

Cgroups v2

Hard resource ceilings enforced by the kernel controller hierarchy. Memory (hard + swap), CPU quota (burst and sustained windows), PID count, and I/O throttle rates. Prevents resource exhaustion, fork bombs, and noisy-neighbour attacks between concurrent agents.

memory.max · cpu.max · pids.max · io.max · io.weight
L4 network isolation
namespace-scoped

Nftables

Per-agent network namespaces backed by nftables rules. Four escalating network policies specified in the manifest: none (air-gapped), local-only, allowlist (explicit domain list), and full. Default policy is none — agents have no network access unless explicitly granted.

policy: none | local-only | allowlist | full
// Information Flow Control runtime-enforced

Prompt injection into external data cannot be stopped at the LLM level — once tainted content enters the context window, all subsequent reasoning is potentially compromised. Scarab tracks which agents have read external data and blocks them from calling output tools at dispatch time. No LLM reasoning is trusted for any security-relevant action.

Tool Classification

Tool Categories

Every tool registered in agentd carries a static category and per-tool tainting and sensitive flags. These drive taint propagation and the exfiltration gate at dispatch — independently of anything the LLM produces.

Input
web.fetch · fs.read
taints agent on success
LocalOutput
fs.write · fs.delete
writes locally only
Output
net.send · email.send
blocked if tainted
Internal
lm.complete · blackboard
no taint effect
Taint Tracking

Exfiltration Gate

Each tool carries independent tainting and sensitive flags. A tool call taints the agent if it reads external data; it marks the agent sensitive if it handles data that must not leave. The exfiltration gate fires only when both flags are set — blocking Output-category tools on agents that have seen sensitive data and are potentially compromised by injection.

Exfiltration gate — at dispatch
tainted + unsensitive + Output → ✓ allowed
untainted + sensitive + Output → ✓ allowed
tainted + sensitive + Output → ✗ denied
Injection Defence

InjectionPolicy

Content returned by Input-category tools is wrapped in <external_content> delimiters before entering the LLM context, signalling to the model that the enclosed text is untrusted. An optional second classifier model call can validate the prompt before it reaches the primary LLM.

None No protection. Use only for fully trusted data sources.
DelimiterOnly Default. Wraps Input results in <external_content> tags.
DualValidate Delimiter + secondary classifier LLM pass before primary.
Blackboard Namespaces
Data / Control Planes
data.* — input category

Reading any data.* key permanently taints the reading agent. At dispatch, agentd blocks agents that hold the agent.spawn capability from reading these keys — orchestrators coordinate without ever seeing raw external data.

control.* — internal category

Reading control.* keys does not taint. Writes to control.* are validated at dispatch against a JSON Schema declared in the writing agent's manifest (spec.control_schema), limiting the injection surface to the declared schema shape.

// Filesystem Isolation

OverlayFS Workspaces

Each agent receives a private OverlayFS workspace at spawn — an isolated view of the filesystem backed by copy-on-write semantics. The lower layer is read-only; all writes are captured in an agent-specific upper layer.

spawn
Fresh overlay mounted at /var/scarab/ws/<id>
snapshot
Upper layer checkpointed — rollback point created
rollback
Upper layer replaced atomically from checkpoint
teardown
Upper layer discarded or archived on completion
base: debian minimal · no shared mutable state between agents
// Capability-Based Access Control

Capability Tokens

Every tool invocation is gated by an unforgeable capability token in domain.action:scope format. Tokens are issued at spawn from the agent manifest and validated by agentd on every dispatch. Agents cannot escalate or mint new tokens.

manifest.yaml capability spec
capabilities:
- fs.read:/workspace/**
- fs.write:/tmp/build/**
- tool.invoke:web-search
- net.connect:api.openai.com
Trust Levels
untrusted
sandboxed
trusted
privileged
default: sandboxed · syscall set and apparmor profile scale with level
Sealed Credentials

Secret Store

Agents never hold raw secrets. Credentials are injected as opaque handles ({{secret:name}}) and substituted inside the agentd dispatch layer — then scrubbed before results re-enter LLM context.

encryption AES-256-GCM
key deriv. Argon2id KDF
storage SQLite (sealed)
agent refs {{secret:name}}
scrubbing pre-LLM context
Audit Trail

Immutable Log

Every tool call, phase transition, and credential access is written to an append-only NDJSON log. Each entry is chained via SHA-256 to the previous — making retroactive tampering detectable.

SHA-256
chain hash
NDJSON
format
append
write mode
immutable
guarantee
Anomaly Detection

Watchdog

A continuous watchdog monitors the audit trail in real time. Anomalous patterns trigger escalation up the agent hierarchy — or immediate termination.

Tool call volume spikes
Capability scope creep
Kernel denial events
Secret handle probing
Canary token leakage
agentd-api · port 8080

REST API

agentd-api exposes the full agent lifecycle over HTTP. Bearer token auth, SSE live event stream, and JSON everywhere. Runs on port 8080 by default.

Authorization: Bearer $SCARAB_TOKEN
POST /api/v1/agents
curl -X POST \
  https://scarab.local:8080/api/v1/agents \
  -H "Authorization: Bearer $SCARAB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"manifest":"etc/agents/example-agent.yaml","trust_level":"sandboxed"}'
Response application/json
{
  "agent_id":    "agent:example-01",
  "status":       "spawning",
  "workspace":    "/var/scarab/ws/a1b2c3",
  "trust_level":  "sandboxed",
  "created_at":   "2025-01-15T09:00:00Z"
}
Rust SDK

Agent SDK

Build autonomous agents that run inside Scarab's execution environment. The libagent SDK handles IPC, capability enforcement, and the plan→act→observe loop.

main.rs — libagent rust
use libagent::{Agent, ToolResult};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Initialize from SCARAB_* environment vars
    let mut agent = Agent::from_env()?;

    loop {
        // Plan: determine next action
        let action = agent.plan().await?;
        if action.is_terminal() { break; }

        // Act: invoke sandboxed tool via agentd
        let result: ToolResult =
            agent.invoke(&action).await?;

        // Observe: update context with result
        agent.observe(result).await?;
    }

    agent.complete().await
}
API Reference
from_env()
Zero-config init. Reads SCARAB_AGENT_ID, SCARAB_IPC_SOCK, SCARAB_WORKSPACE from environment.
plan()
Sends accumulated context to LLM. Returns typed Action with tool name, args, and terminal flag.
invoke()
Dispatches tool call through agentd. Enforced against capability manifest. Returns ToolResult.
observe()
Appends ToolResult to observation buffer. Prepares updated context for next plan cycle.
complete()
Signals clean termination to agentd daemon. Workspace preserved until explicit teardown.
Cargo.toml toml
[dependencies]
libagent = { path = "../libagent" }
tokio    = { version = "1", features = ["full"] }
anyhow   = "1"

Ready to isolate your agents?

Scarab is MIT-licensed and runs on any Linux 5.x+ system. Pull the repo and spawn your first agent in minutes.

● kernel: linux 5.x+ | ● lang: rust | ● license: MIT