Skip to main content
Version: 1.0.0

Use the hardened execution profile

The hardened profile is opt-in. Copy the published contracts/hardened/profile.json contract to touba.hardened-profile.json, reference it in your project profile, then prepare and run the project.

{
"run_profiles": {
"hardened": {
"require_supply_chain_lock": true,
"supply_chain_lock": "touba.lock.json",
"hardened_profile": "touba.hardened-profile.json"
}
}
}

Declare budgets in .tb source, after imports and before declarations; the compiler produces the required AIR limits.

module examples.bounded

limits run
max_run_ms as 30000
max_steps as 100
max_tool_calls as 20
max_agent_invocations as 5
max_provider_calls as 10

Each tool binding must include "sandbox": { "required": true }. Also supply a durable checkpoint path. The runtime uses opaque_refs for provider data and refuses execution if the lock, sandbox, budgets, redaction or checkpoint storage requirements are unmet.

This is defense in depth, not a guarantee against exfiltration by an authorized handler, general prompt-injection detection, or identical sandbox protection across operating systems.

With a prepared run plan and validated lock:

touba run --run-plan .touba/build/hardened/touba.run-plan.json \
--human-checkpoint-out .touba/pending-approval.json --output json

HardenedBudgetRequired identifies a missing compiled source limit; HardenedDurableCheckpointRequired identifies missing checkpoint configuration. JSON output and its admission trace retain these codes without business payloads. A pure program validates the budget/lock/checkpoint path; it does not qualify handler OS isolation.

Locate the installed contract​

For an installed Touba distribution, this macOS/Linux command prints the bundled contract path without changing the installation:

Locate the profile
node --input-type=module <<'JS'
import {execFileSync} from 'node:child_process';
import {accessSync} from 'node:fs';
import {dirname, resolve} from 'node:path';
const info = JSON.parse(execFileSync('touba', ['version', '--json'], {encoding: 'utf8'}));
if (!info.distribution.sdk_archive) throw new Error('An installed Touba distribution is required');
const profile = resolve(dirname(info.distribution.sdk_archive), '../lib/contracts/hardened/profile.json');
accessSync(profile);
console.log(profile);
JS

Copy this file into your project and preserve its checks. In a source checkout, the path is implementation/contracts/hardened/profile.json.

Sandbox qualification​

When sandbox.required: true, macOS uses sandbox-exec; Linux x64 combines bubblewrap, seccomp and the native touba-sandbox launcher with Landlock ABI 3 or newer. Out-of-scope data, writes, descendants and network connections are denied by default. Native Linux checks cover Ubuntu 24.04, Node and Python, including termination of descendants on timeout.

On Linux, bubblewrap must be installed and user namespaces available. An Ubuntu host protected by AppArmor may require an administrator profile limited to that binary, without disabling global protections. Each write_paths entry must already exist: use a dedicated output directory to create files. Write access does not grant read access. Exact Unix socket scopes require Landlock ABI 9; an unenforceable policy is refused before launch. The probe runs a command under confinement to check prerequisites.

The Windows backend is still undergoing V1 qualification, including asynchronous Python handlers without network authorization. It is not announced as available in a finalized distribution. An unavailable sandbox or unsupported policy prevents execution, with no direct-execution fallback. Without a required sandbox, handlers remain trusted host code. HandlerSandboxUnsupportedPolicy identifies a policy unsupported by the selected backend.

The technical baseline permits the interpreter's native libraries and metadata, not every JavaScript module or the user's directory. For an installed, verified JavaScript SDK, prepare inventories its individual files in sandbox.code_paths. Third-party dependencies require explicit paths; no whole directory is opened. Explicit binding fragments keep their own inventory.

The code_paths selection supplements this technical inventory; [] removes additional files, not the verified SDK files. Data paths remain separate permissions.

Enable the sandbox through host decisions:

Terminal
touba prepare --mode plan --host-decisions-json '{"bindings":{"tool:orders.review/ReadOrder":{"sandbox":{"required":true}}}}'

Use your tool reference, install its SDK, review the inventory, then use --mode write and --mode check. Relative handler file arguments are resolved before the isolated process starts. Data access still requires a grant and explicit read_paths or write_paths. Code paths never grant write access. For startup failures, development-only --handler-diagnostics <file.jsonl> records the error class and known source position, without private messages.