Generally Available

Secure Agent SDK v1.1

Runtime controls and evidence tooling for enterprise AI agents.

Deny-by-default permissions, TEE-isolated execution, immutable audit records, content safety filters, and one-call control mapping for governed deployments.

✓ WASM Sandbox Runtime (Phase 1.1) ✓ Python SDK ⧗ SOC 2 program in progress EU AI Act evidence support ✓ TypeScript ✓ Node.js ≥ 18
🔒
Deny-by-Default Permissions
Capability-based access control. Agents can only do what you explicitly grant — network, file, API, cross-agent.
🧱
TEE Sandbox
Agents run in Trusted Execution Environments with hardware attestation. Cryptographic proof your code ran untampered.
📋
Immutable Audit Trail
Every action logged with timestamp, agent ID, input/output, and permission state. Blockchain-anchored for tamper-evidence.
🛡️
Content Safety
Multi-layer content moderation — regex patterns + AI scoring. Blocks harmful, illegal, or injection-attack content before it runs.
Kill Switch
Instant agent termination from dashboard or API. Per-agent or global emergency stop with reason logging.
📊
Evidence Packages
Export PDF/JSON evidence packages mapping your agent controls to EU AI Act, SOC 2, and NIST AI RMF. Audit-prepared for your compliance team's review.

Installation

Install via npm. Zero runtime dependencies.

# npm
npm install @thetazero/agent-sdk

# yarn
yarn add @thetazero/agent-sdk

# pnpm
pnpm add @thetazero/agent-sdk

Get your API key from the dashboard under Settings → API Keys. All keys currently have full access — fine-grained scopes are coming Q2 2026.

Quick Start

Three lines to run a sandboxed, governed agent.

const { SecureAgent } = require('@thetazero/agent-sdk');

const agent = new SecureAgent({
  apiKey:      'tzk_your_api_key',
  permissions: SecureAgent.permissions.CODER,
  limits:      { maxMemoryMb: 512, maxExecutionTimeSec: 300 },
  sandbox:     'STANDARD',
});

await agent.configure();

const result = await agent.run({
  task: 'Analyze the user churn data and identify top 3 risk factors',
  data: { users: churnDataset },
});

console.log(result.output);
// ↳ executionId, status, output, durationMs, auditTrailUrl

WASM Sandbox Runtime Phase 1.1

The Phase 1.1 sandbox runtime executes your agent code inside an isolated Node.js worker_thread with a clean vm.createContext() global scope. No require, no process, no filesystem — only the approved thetazero.* host API and safe JS built-ins. CPU time is enforced by a parent-side kill timer; memory is capped via worker resourceLimits. Every host function call is recorded in a structured audit trail.

🔌
Isolated Worker Thread
Agent code runs in a separate OS thread. No shared memory with the host process. Killed instantly when the CPU time limit fires.
🛡️
Clean Global Scope
vm.createContext() exposes only approved globals: JSON, Math, Date, standard constructors, and the thetazero bridge. require, process, and Buffer are denied.
📋
Full Audit Trail
Every thetazero.* call is logged with function name, argument summary, timestamp, allow/deny decision, and duration. Returned in every execution response.
Resource Limits
Configurable memory_limit_mb (default 128 MB), cpu_time_limit_ms (default 30 s), and max_api_calls_per_run (default 50).
// Execution response includes full resource telemetry
{
  "execution_id": 4821,
  "status":       "completed",
  "output":       { "summary": "..." },
  "resource_usage": {
    "cpu_ms":     1842,
    "memory_mb":  128,
    "api_calls":  3,
    "host_calls": 5
  },
  "host_call_audit": [
    { "fn": "http_request", "allowed": true,  "duration_ms": 412 },
    { "fn": "write_result", "allowed": true,  "duration_ms": 0   }
  ],
  "violation_count": 0,
  "was_terminated": false
}

Host API — thetazero.*

Agent code running inside the sandbox communicates with the outside world exclusively through the thetazero host bridge. All calls are async and return Promises.

Available in sandbox code

Use thetazero.* (or alias it to const tz = thetazero) inside your agent's entry_code. These functions are NOT available in the Python SDK — they run inside the sandbox at execution time.

FunctionDescriptionConfig required
thetazero.log(msg, level?) Emit a structured log entry. Level: 'info' (default), 'warn', 'error', 'debug'. Synchronous — no parent round-trip.
thetazero.http_request(url, method?, headers?, body?) Make an outbound HTTPS request. Returns { status, headers, body }. HTTPS only. Counted against max_api_calls_per_run. allow_network: true
thetazero.read_context(key) Read a value from the agent's scoped context store. Returns null if not set. Counted against max_api_calls_per_run.
thetazero.write_result(output) Write the agent's final execution result. Must be JSON-serializable. Can be called multiple times — last call wins. Prefer returning a value from the entry code directly.
thetazero.agentName Read-only. Name of the running agent.
thetazero.agentVersion Read-only. Version string of the running agent.
thetazero.executionId Read-only. Numeric ID of this execution record.
// entry_code example — full host API usage
const tz = thetazero;

// Structured logging
await tz.log("Starting execution", "info");
await tz.log(`Agent: ${tz.agentName} v${tz.agentVersion}`);

// Outbound HTTPS (requires allow_network: true)
const resp = await tz.http_request(
  "https://api.example.com/data",
  "GET",
  { "Authorization": "Bearer token" }
);
await tz.log(`Status: ${resp.status}`);

// Context store
const prevCount = await tz.read_context("run_count") ?? 0;

// Final result — write_result() or return value both work
await tz.write_result({
  processed:  resp.body.items.length,
  run_number: prevCount + 1,
});

REST API — /api/v1/sdk/agents

All endpoints require an API key with the agents scope. Set the Authorization: Bearer tzk_… header on every request.

MethodEndpointDescription
POST/api/v1/sdk/agentsRegister / upsert an agent by name
GET/api/v1/sdk/agentsList agents for this API key
GET/api/v1/sdk/agents/:idGet one agent by ID
PATCH/api/v1/sdk/agents/:idUpdate code, config, or status
DELETE/api/v1/sdk/agents/:idDelete agent and all executions
POST/api/v1/sdk/agents/:id/executeExecute agent in sandbox (synchronous)
GET/api/v1/sdk/agents/:id/executionsList execution history
GET/api/v1/sdk/agents/:id/executions/:eidFull execution details incl. logs & audit
# Register a new agent (or upsert by name)
curl -X POST https://thetazero.app/api/v1/sdk/agents \
  -H "Authorization: Bearer tzk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-summarizer",
    "version": "1.0.0",
    "entry_code": "await thetazero.write_result({ ok: true });",
    "config": {
      "memory_limit_mb": 128,
      "cpu_time_limit_ms": 15000,
      "max_api_calls_per_run": 10,
      "allow_network": false
    },
    "status": "ready"
  }'

# Response
{
  "success": true,
  "agent": {
    "id": 42,
    "name": "my-summarizer",
    "version": "1.0.0",
    "status": "ready",
    "config": { "memory_limit_mb": 128, "cpu_time_limit_ms": 15000, "allow_network": false }
  }
}

Python SDK

Zero-dependency Python wrapper for the ThetaZero REST API. Requires Python ≥ 3.8. Install from the sdk-package directory or pip (coming soon).

# Install (pip coming soon — use directly from source for now)
pip install thetazero-sdk

# Or from source
pip install ./sdk-package/thetazero
from thetazero import SecureAgent

agent = SecureAgent(
    api_key="tzk_your_api_key",   # or set THETAZERO_API_KEY env var
    name="hello-world",
    description="Simplest possible SDK agent",
)

# Deploy with raw JavaScript entry code
agent.deploy(
    entry_code="""
await thetazero.log("Hello from the sandbox!");
await thetazero.write_result({ message: "Hello, " + (input.name || "world") + "!" });
"""
)

# Run it
result = agent.run(input={"name": "Alice"})
result.raise_for_status()   # raises RuntimeError if status != completed

print(result.output)           # {'message': 'Hello, Alice!'}
print(result.resource_usage)  # {'cpu_ms': 18, 'api_calls': 0, 'host_calls': 2}

# List executions
for ex in agent.executions():
    print(ex["status"], ex["resource_usage"])

SecureAgent methods

MethodDescription
deploy(entry_code?, **kwargs)Register / upsert the agent on ThetaZero. Returns the agent record.
run(input?)Execute in the sandbox synchronously. Returns ExecutionResult.
executions(page?, limit?, status?)List execution history. Returns list of dicts.
get_execution(execution_id)Full execution detail including logs and audit trail.
get_agent()Retrieve the current agent definition.
list_agents()List all agents for this API key.
update(**kwargs)Patch agent fields (entry_code, config, status, etc.).
delete()Permanently delete the agent and all executions.

AgentConfig fields

FieldTypeDefaultDescription
memory_limit_mbint128Worker thread memory cap (MB)
cpu_time_limit_msint30 000Wall-clock execution timeout (ms)
max_api_calls_per_runint50Max http_request / read_context calls
allow_networkboolFalseEnable outbound HTTPS
allow_filesystemboolFalseEnable filesystem access (reserved)
sandbox_templatestr"STANDARD"STRICT / STANDARD / DEV
allowed_domainslist[str][]Domain allow-list for network calls (empty = all HTTPS)

Sandboxing

Every agent runs in an isolated execution environment. Choose from three policy templates — STRICT for enterprise, STANDARD for general use, DEV for local development.

STRICT
Strictest controls — maps to SOC 2 & EU AI Act control frameworks
Memory: 256 MB
Time: 120 sec
API calls: 50 / run
Network: blocked
Content safety: on
STANDARD
General use — default
Memory: 512 MB
Time: 300 sec
API calls: 100 / run
Network: allowed
Content safety: on
DEV
Local dev only — not for production
Memory: 2048 MB
Time: 600 sec
API calls: 500 / run
Network: allowed
Content safety: off
// Override specific limits within a template
const agent = new SecureAgent({
  sandbox: 'STRICT',
  limits: {
    maxMemoryMb:         512,   // override STRICT default of 256
    maxExecutionTimeSec: 180,   // override STRICT default of 120
  },
});

// Verify TEE attestation after execution
const proof = await agent.verifyExecution(result.executionId);
console.log(proof.tee_mode);          // 'theta_tee' | 'docker_fallback'
console.log(proof.attestation_id);    // cryptographic attestation ID
console.log(proof.chain_valid);       // true if audit chain intact

Permission System

Deny-by-default capability model. Agents have zero permissions unless explicitly granted. Use presets or compose custom scope arrays.

Fine-grained scopes coming Q2 2026

The scopes listed below are the planned permission model. Today, all live API keys have full access to your account. Role-based, per-scope enforcement will be available in Q2 2026.

ScopeDescription
compute:readRead compute job status and metrics
compute:writeSubmit compute jobs to EdgeCloud nodes
inference:callMake LLM inference API calls
data:readRead structured data inputs
data:writeWrite structured data outputs
network:outboundMake outbound HTTP requests
storage:readRead from persistent storage
storage:writeWrite to persistent storage
agents:readRead outputs from other agents (cross-agent)
agents:writeWrite to other agents or spawn subagents
// Use a built-in preset
permissions: SecureAgent.permissions.CODER
// → ['compute:read','compute:write','inference:call','data:read','network:outbound']

// Or compose custom scopes
permissions: ['inference:call', 'data:read']

// Available presets
SecureAgent.permissions.READONLY    // safest
SecureAgent.permissions.WRITER      // inference + data:read only
SecureAgent.permissions.RESEARCHER  // network + inference, no cross-agent write
SecureAgent.permissions.CODER       // network + compute + inference
SecureAgent.permissions.ANALYST     // broadest data access
SecureAgent.permissions.FULL        // all scopes — trusted agents only

Audit Trail

Every agent action is logged with a timestamp, agent ID, action type, input/output summary, and permission state. Rows are immutable (UPDATE/DELETE blocked at DB level). Batches are anchored to the blockchain every 5 minutes for tamper-evidence.

// Query the full audit log
const audit = await agent.getAuditLog({
  from:           '2026-01-01',
  to:             '2026-01-31',
  actionTypes:    ['api_call', 'permission_denied'],
  violationsOnly: false,
  limit:          200,
});
// → { events: [...], total: 47, anchored: true }

// Verify a specific record's blockchain integrity
const proof = await agent.verifyAuditRecord(12345);
// → { chain_valid: true, anchor_tx_hash: '0xabc...', verified_at: '...' }

// Export for compliance review
const csv = await agent.exportAuditLog('csv', {
  from: '2026-01-01',
  to:   '2026-03-31',
});
Immutability guarantee

Audit rows have a Postgres trigger that raises an exception on any UPDATE or DELETE. Not configurable. This supports SOC 2 evidence collection requirements.

Content Safety Filters

Inputs and outputs pass through a two-layer safety pipeline: fast regex pattern matching, then AI scoring for borderline cases.

LayerWhat it checksAction on fail
Pattern matchToxicity, injection, harmful content patternsBlock immediately
AI scoringToxicity score < 0.4, injection score < 0.35Block + log violation
Resource boundsPrompt length, cost delta vs parent, evolution rateBlock + alert

Content safety is always on for STRICT and STANDARD sandbox templates. Can be disabled only in DEV mode.

Rate Limits & Quotas

Per-execution and per-swarm rate limits prevent runaway agents from consuming unbounded resources.

Limit typeDefaultOverride
API calls / minute (per execution)60limits.maxApiCallsPerRun
Swarm executions / hour10Contact support
Memory per execution512 MBlimits.maxMemoryMb
Max execution time300 seclimits.maxExecutionTimeSec

Quota violations are logged to the audit trail as rate_limit_hit or sandbox_limit_hit events with is_violation: true.

Kill Switch

Instant agent termination from the SDK or dashboard. Supports per-agent and global kill with full reason logging.

Agent Running
All systems normal
// Stop a specific agent (from SDK)
await agent.stop('Suspicious output detected — halting for review');

// Stop from any script (without SecureAgent instance)
const res = await fetch(`/api/sdk/agents/${agentId}/kill`, {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: JSON.stringify({ reason: 'Policy violation' }),
});

// Global kill switch (stops ALL agents)
await fetch('/api/sdk/kill-switch/global', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}` },
  body: JSON.stringify({ halted: true, reason: 'Emergency maintenance' }),
});

Controls Mapping & Evidence

One call to map controls and generate evidence for your compliance team's review. ThetaZero evaluates your agent configuration against framework requirements and produces a coverage report. Output is audit-prepared evidence — not a certification or compliance score.

Framework
Score
Coverage
EU AI Act
Controls mapped
94%
MAPPED
SOC 2
Controls documented
87%
DOCUMENTED
NIST AI RMF
Controls mapped
71%
Gap identified

// Apply compliance frameworks at configure() time
const agent = new SecureAgent({
  compliance: ['eu_ai_act', 'soc2', 'nist_ai_rmf'],
});
await agent.configure(); // evaluates immediately

// Get current compliance status
const status = await agent.getComplianceStatus();

// Generate evidence package for compliance team review
const evidence = await agent.getEvidencePackage('eu_ai_act', 'markdown');
// → controls-mapped evidence document — audit-prepared, not a certification

// Export full compliance coverage report (JSON)
const report = await agent.exportComplianceReport('json');

API Reference

new SecureAgent(opts)

Constructor options.

apiKeyRequired. API key starting with tzk_
agentId?Cloud agent ID. Auto-resolved on first configure() if omitted.
permissions?Scope array. Defaults to READONLY. Use SecureAgent.permissions.* presets.
limits?Override resource limits: maxMemoryMb, maxExecutionTimeSec, maxApiCallsPerRun.
sandbox?'STRICT' | 'STANDARD' | 'DEV'. Default: 'STANDARD'.
compliance?Framework codes: 'eu_ai_act', 'soc2', 'nist_ai_rmf'.
agent.configure() → Promise<this>
Configure sandbox policy, apply permission scopes, and evaluate compliance framework coverage. Safe to call multiple times. Auto-resolves agentId if not provided.
agent.run(input) → Promise<ExecutionResult>
Execute the agent. Input: { task: string, data?: object, model?: string }. Returns executionId, status, output, durationMs, costTfuel, auditTrailUrl.
agent.stop(reason?) → Promise
Instantly kill the agent. Reason is logged to the audit trail. No delay — termination is synchronous at the platform level.
agent.getAuditLog(opts?) → Promise<AuditQueryResult>
Query the immutable audit trail. Filter by date range, action types, violations. Sorted by recorded_at ASC.
agent.verifyAuditRecord(recordId) → Promise<VerificationResult>
Verify a single audit record's blockchain integrity. Returns hash, chain validity, and anchor transaction.
agent.exportAuditLog(format, opts?) → Promise
Export in 'json', 'csv', or 'summary' format. CSV returns file content suitable for Content-Disposition download.
agent.getComplianceStatus() → Promise<ComplianceStatus>
Returns cached compliance evaluation results per framework. Includes per-control coverage status and gap remediation steps.
agent.evaluateCompliance() → Promise
Force re-run all compliance evaluations and refresh the cache. Use after changing sandbox policy or permissions.
agent.getEvidencePackage(framework, format?) → Promise
Generate a controls-mapped evidence package for 'eu_ai_act', 'soc2', or 'nist_ai_rmf'. Returns markdown or JSON documenting control coverage and supporting evidence. Audit-prepared for your compliance team's review — not a certification.
agent.storeCredential(credential) → Promise
Encrypt and store a credential (API key, OAuth token, secret). Values stored with AES-256-GCM. Never returned in plaintext after creation.
agent.rotateCredential(credentialId, newValue) → Promise
Atomic rotation — revoke old credential and create new one in a single transaction. Old credential immediately invalidated.

Permission Requests v1.1

Agents declare elevated permissions upfront. The account owner reviews and approves or denies before execution proceeds. Deny-by-default — nothing is granted unless explicitly requested and approved.

agent.requestPermission(opts) → Promise<PermissionRequestRecord>
Request elevated permissions. Blocks until approved, denied, or timed out (default 3 min). The account owner sees a push notification in their dashboard with approve/deny buttons. Throws SDKError with code PERMISSION_DENIED, PERMISSION_EXPIRED, or PERMISSION_TIMEOUT on rejection.
// Agent requests network + external API access before execution
await agent.requestPermission({
  permissions: {
    allow_network:        true,
    allow_external_apis:  true,
    max_api_calls_per_run: 500,
  },
  justification: 'Needs to call OpenWeatherMap for forecast data',
  timeoutMs: 120_000, // 2 min
});

// If we get here, the owner approved — safe to proceed
const result = await agent.run({ task: 'Fetch weather forecast for NYC' });
Dashboard Integration

Pending requests appear in Security → Permission Requests in the ThetaZero dashboard. A red badge shows the count of unreviewed requests. Owners receive real-time notifications. Each request shows the permissions sought, the agent type, and the justification provided.

REST API
MethodEndpointDescription
POST/api/sdk/permission-requestsCreate a permission request
GET/api/sdk/permission-requests?status=pendingList requests by status
POST/api/sdk/permission-requests/:id/approveApprove a pending request
POST/api/sdk/permission-requests/:id/denyDeny a pending request

Live Audit Stream v1.1

Subscribe to a real-time stream of agent actions via Server-Sent Events (SSE). Every action — API calls, file access, inference calls, permission checks — appears in the stream as it happens.

agent.streamAuditLog(opts, onEvent) → AuditStreamHandle
Opens an SSE connection and calls onEvent(type, data) for each audit event. Returns a handle with a close() method to disconnect. Works in Node.js ≥18. For browsers, use new EventSource('/api/sdk/audit/stream') directly.
// Node.js — watch a live execution
const stream = agent.streamAuditLog(
  { executionId: 1234 },
  (type, data) => {
    if (type === 'audit') {
      console.log(`[${data.action_category}] ${data.description}`);
      if (data.is_violation) console.error('⚠ VIOLATION:', data.description);
    }
  }
);

// Run the agent (stream will receive events in real time)
await agent.run({ task: 'Analyze Q1 metrics and generate report' });

// Disconnect when done
stream.close();
GET /api/sdk/audit/stream
SSE endpoint. Query params: executionId, agentId, since (ISO timestamp). Events: connected on open, audit per action, timeout at 10-min limit, keepalive every 15s.
// Browser — watch all events for your account
const source = new EventSource(
  '/api/sdk/audit/stream?executionId=1234',
  { headers: { Authorization: 'Bearer tzk_...' } }
);
source.addEventListener('audit', (e) => {
  const action = JSON.parse(e.data);
  console.log(action.action_type, action.description);
});
source.addEventListener('timeout', () => source.close());

Ready to deploy enterprise-safe agents?

Start in 2 minutes

Get an API key, install the SDK, and ship your first governed agent today.

Get API Key → Full Docs