> ## Documentation Index
> Fetch the complete documentation index at: https://docs.declaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Agents SDK

> Run agents built with the OpenAI Agents SDK inside a declaw sandbox — the agent's bash, file, and PTY tools all execute under declaw's full security posture without changing any agent logic.

The `declaw.openai` module plugs declaw into the OpenAI Agents SDK as a
sandbox backend. Agent authors keep their existing Agents-SDK code; the
only change is handing a `DeclawSandboxClient` to the runner. Every
tool the agent invokes — `bash`, `read_file`, `write_file`,
`apply_patch`, `pty_exec_start`, etc. — runs inside the VM, with the
full declaw [security surface](/security/overview) applied at the VM's
network boundary.

## Install

```bash theme={null}
pip install "declaw[openai-agents]"
```

## Imports

Everything you need is available from a single namespace:

```python theme={null}
from declaw.openai import (
    # Adapter surface
    DeclawSandboxClient,
    DeclawSandboxClientOptions,
    DeclawSandboxSession,
    DeclawSandboxSessionState,
    DeclawSandboxTimeouts,
    DeclawSandboxType,
    # Security knobs (re-exported from declaw.security)
    SecurityPolicy,
    PIIConfig,
    InjectionDefenseConfig,
    TransformationRule,
    ToxicityConfig,
    CodeSecurityConfig,
    InvisibleTextConfig,
    EnvSecurityConfig,
    AuditConfig,
    # Network + lifecycle
    NetworkPolicy,
    SandboxNetworkOpts,
    SandboxLifecycle,
    ALL_TRAFFIC,
    # Agent-side guardrails helpers
    PIIHandler,
    GuardrailsClient,
)
```

## `DeclawSandboxClient`

The sandbox-provider class. `backend_id = "declaw"`.

* `await client.create(*, options: DeclawSandboxClientOptions) -> SandboxSession`
* `await client.delete(session) -> SandboxSession`
* `await client.resume(state: DeclawSandboxSessionState) -> SandboxSession`
* `client.deserialize_session_state(payload) -> DeclawSandboxSessionState`

## `DeclawSandboxClientOptions`

Pydantic frozen model. Every field declaw's `Sandbox.create` accepts is
exposed here, plus the individual security sub-configs as convenience
shortcuts.

| Field                   | Type                             | Default               | What it controls                                                                                                                                                                  |
| ----------------------- | -------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `template`              | `str`                            | `"base"`              | Which preloaded sandbox template to spawn from. See [templates](/features/templates).                                                                                             |
| `api_key`               | `str \| None`                    | from `DECLAW_API_KEY` | Override the API key for this client.                                                                                                                                             |
| `domain`                | `str \| None`                    | from `DECLAW_DOMAIN`  | API host (e.g. `api.declaw.ai`).                                                                                                                                                  |
| `timeout`               | `int \| None`                    | `300`                 | Sandbox lifetime in seconds.                                                                                                                                                      |
| `envs`                  | `dict[str,str]`                  | `None`                | Environment variables for the sandbox process.                                                                                                                                    |
| `metadata`              | `dict[str,str]`                  | `None`                | Custom labels for audit / routing.                                                                                                                                                |
| `allow_internet_access` | `bool`                           | `True`                | Shorthand for "no egress lockdown"; overridden by `network`.                                                                                                                      |
| `security`              | `SecurityPolicy`                 | `None`                | Full security policy — see below.                                                                                                                                                 |
| `pii`                   | `PIIConfig`                      | `None`                | Shortcut; overrides `security.pii` if set.                                                                                                                                        |
| `injection_defense`     | `InjectionDefenseConfig`         | `None`                | Shortcut for `security.injection_defense`.                                                                                                                                        |
| `transformations`       | `list[TransformationRule]`       | `None`                | Regex substitution rules.                                                                                                                                                         |
| `toxicity`              | `ToxicityConfig`                 | `None`                | Harmful-content detection.                                                                                                                                                        |
| `code_security`         | `CodeSecurityConfig`             | `None`                | Code-injection scanning in HTTP traffic.                                                                                                                                          |
| `invisible_text`        | `InvisibleTextConfig`            | `None`                | Zero-width / hidden-character stripping.                                                                                                                                          |
| `env_security`          | `EnvSecurityConfig`              | `None`                | Env-var masking for audit logs.                                                                                                                                                   |
| `audit`                 | `AuditConfig`                    | `None`                | Per-sandbox audit toggle.                                                                                                                                                         |
| `network`               | `SandboxNetworkOpts`             | `None`                | `allow_out` / `deny_out` / `mask_request_host`.                                                                                                                                   |
| `lifecycle`             | `SandboxLifecycle`               | `None`                | `on_timeout` (`kill` / `pause`), `auto_resume`.                                                                                                                                   |
| `volumes`               | `list[VolumeAttachment \| dict]` | `None`                | Pre-uploaded [volumes](./volumes) (create with `declaw.Volumes.create`) to hydrate into the agent's sandbox at boot. Each entry is `{"volume_id": "...", "mount_path": "/data"}`. |
| `timeouts`              | `DeclawSandboxTimeouts`          | `None`                | Adapter-internal op timeouts.                                                                                                                                                     |

**Composition rule.** If you pass a full `SecurityPolicy` via `security=`,
we use it. Any per-field shortcut (e.g. `pii=PIIConfig(...)`) that's
also set *overrides* the matching sub-field on the composite policy.
If neither is set, the sandbox runs with platform defaults.

## `DeclawSandboxSession`

Returned from `client.create()` and `client.resume()`. Implements
the `BaseSandboxSession` ABC — `_exec_internal`, `read`, `write`,
`running`, `persist_workspace`, `hydrate_workspace` — plus a handful
of declaw-specific conveniences:

```python theme={null}
# Wrapped by agents.sandbox.SandboxSession; unwrap to reach these:
declaw_session: DeclawSandboxSession = session._inner  # or session.inner
await declaw_session.list_snapshots()
await declaw_session.metrics(start=..., end=...)
await declaw_session.pause()
await declaw_session.resume()
declaw_session.underlying_sandbox      # the raw declaw AsyncSandbox
```

## `DeclawSandboxSessionState`

Serializable state for `client.resume()`. Carries:

* `sandbox_id: str` — to reattach to a live sandbox.
* `snapshot_id: str | None` — if set, `resume()` restores from a
  memory+disk snapshot (`Sandbox.restore`), otherwise it reattaches
  to a still-running sandbox (`Sandbox.connect`).
* `template: str`, `created_at: datetime`.

## Quick start

```python theme={null}
import asyncio
from agents import Runner
from agents.run import RunConfig
from agents.sandbox import SandboxAgent, SandboxRunConfig
from declaw.openai import (
    DeclawSandboxClient, DeclawSandboxClientOptions,
    SecurityPolicy, PIIConfig, InjectionDefenseConfig, SandboxNetworkOpts,
)

async def main():
    options = DeclawSandboxClientOptions(
        template="python",
        security=SecurityPolicy(
            pii=PIIConfig(enabled=True, action="redact"),
            injection_defense=InjectionDefenseConfig(enabled=True, sensitivity="medium"),
        ),
        network=SandboxNetworkOpts(allow_out=["api.openai.com", "pypi.org"]),
    )

    client = DeclawSandboxClient()
    session = await client.create(options=options)
    try:
        agent = SandboxAgent(name="demo", model="gpt-5.4", instructions="...")
        result = await Runner.run(
            agent,
            "Write 'hello' to /workspace/x.txt and print its byte count.",
            run_config=RunConfig(sandbox=SandboxRunConfig(session=session)),
        )
        print(result.final_output)
    finally:
        await client.delete(session)

asyncio.run(main())
```

## Security — exactly what the core SDK provides

The adapter does **not** introduce a parallel security path. Whatever
you set in `SecurityPolicy` here is the same policy enforced by the
sandbox's edge proxy for any sandbox — the same six guardrail
scanners, the same audit log entries, the same outcome. When the
agent's bash tool runs `curl https://api.example.com/?email=alice@acme.com`,
the request is intercepted and scanned before it reaches the upstream.

See [Security → Overview](/security/overview) for the full
scanner list and policy reference.

## Session resume

`persist_workspace` creates a declaw snapshot of memory + disk; the
returned session state carries `snapshot_id` which `client.resume()`
uses to restore the exact VM state later — in a different process,
on a different machine, or across a cluster restart. Snapshots are
persisted to the platform's blob store (GCS in our managed cloud).

## See also

* [Cookbook: OpenAI Agents quick-start](/cookbook/openai-agents-quickstart)
* [Cookbook: PII redaction end-to-end](/cookbook/openai-agents-security)
* [Security → Overview](/security/overview)
* [Features → Templates](/features/templates)
