> ## Documentation Index
> Fetch the complete documentation index at: https://blaxel-mendral-deps-weekly-safe-github-actions-20260803.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Drive overview

> Agent Drive is a distributed filesystem mountable to multiple sandboxes or agents simultaneously, with concurrent read-write access and built-in replication.

<Note>
  This feature is currently in private preview. During the preview, the Agent Drive feature is only available in the `us-was-1` region. Both your drive and your sandbox must be created in this region. Drive size is not configurable at the moment. A quotas system for drive storage is coming soon. [Request access](https://blaxel.fillout.com/t/pbTXmanx3Sus).
</Note>

Agent Drive is a distributed filesystem that can be mounted to multiple sandboxes or agents at any time, including while they are already running. Drives support concurrent read-write access (RWX) from multiple sandboxes simultaneously, with built-in replication for durability.

Unlike [volumes](/Volumes/Overview), which are block storage devices attached at sandbox creation to a single sandbox, drives behave like a shared cloud filesystem, but mounted directly into a sandbox's file tree. An optimized FUSE client built specifically for this filesystem is added directly to the sandbox or agent to give a POSIX-compliant interface.

* A drive can be attached to an already-running sandbox at any mount path, without needing to recreate the sandbox.
* Multiple sandboxes can mount the same drive simultaneously with full read-write access.
* A specific subdirectory of a drive can be mounted using `drivePath` (instead of mounting the entire drive).
* Drives scale automatically with no fixed capacity limits. Pre-provisioning or run-time resizing is not required.

## Use cases

Some examples of use cases are:

* Passing data or files from one sandbox to another directly, without needing intermediary storage or services
* Storing tool call outputs and context histories for use in other agents
* Sharing common datasets across agents
* Creating a shared filesystem cache of package dependencies to speed up future agent/sandbox deployments

## Create a drive

<Accordion title="Learn more about authentication on Blaxel">
  The Blaxel SDK requires two environment variables to authenticate:

  | Variable       | Description                |
  | -------------- | -------------------------- |
  | `BL_WORKSPACE` | Your Blaxel workspace name |
  | `BL_API_KEY`   | Your Blaxel API key        |

  You can create an API key from the [Blaxel console](https://app.blaxel.ai/profile/security). Your workspace name is visible in the URL when you log in to the console (e.g. `app.blaxel.ai/{workspace}`).

  Set them as environment variables or add them to a `.env` file at the root of your project:

  ```bash theme={null}
  export BL_WORKSPACE=my-workspace
  export BL_API_KEY=my-api-key
  ```

  When developing locally, you can also **log in to your workspace with Blaxel CLI** (as shown above). This allows you to run Blaxel SDK functions that will automatically connect to your workspace without additional setup. When you deploy on Blaxel, authentication is handled automatically — no environment variables needed.
</Accordion>

Create a standalone drive by specifying a unique `name` and `region`. You can also optionally specify the display name and labels for the drive.

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { DriveInstance } from "@blaxel/core";

  const drive = await DriveInstance.create({
    name: "my-drive",
    region: "us-was-1",
    displayName: "My Project Drive", // optional; defaults to `name`
    labels: { env: "dev", project: "my-project" }, // optional; labels
  });
  ```

  ```python Python theme={null}
  from blaxel.core.drive import DriveInstance
  drive = await DriveInstance.create(
      {
          "name": "my-drive",
          "region": "us-was-1",
          "display_name": "My Project Drive", # optional; defaults to `name`
          "labels": {"env": "dev", "project": "my-project"},  # optional; labels
      }
  )
  ```

  ```bash CLI theme={null}
  bl drive create --name my-drive --region us-was-1
  ```
</CodeGroup>

You can also use `createIfNotExists()` to retrieve an existing drive or create a new one if it doesn't exist:

<CodeGroup>
  ```tsx TypeScript theme={null}
  const drive = await DriveInstance.createIfNotExists({
    name: "my-drive",
    region: "us-was-1",
    displayName: "My Project Drive", // optional; defaults to `name`
    labels: { env: "dev", project: "my-project" }, // optional; labels
  });
  ```

  ```python Python theme={null}
  from blaxel.core.drive import DriveInstance
  drive = await DriveInstance.create_if_not_exists(
      {
          "name": "my-drive",
          "region": "us-was-1",
          "display_name": "My Project Drive", # optional; defaults to `name`
          "labels": {"env": "dev", "project": "my-project"},  # optional; labels
      }
  )
  ```
</CodeGroup>

## Mount a drive to a sandbox

Mount a drive to a running sandbox by specifying the `driveName`, the `mountPath` (where the drive will appear in the sandbox's filesystem), and optionally the `drivePath` (a subdirectory within the drive to mount).

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { SandboxInstance } from "@blaxel/core";

  const sandbox = await SandboxInstance.get("my-sandbox");

  await sandbox.drives.mount({
    driveName: "my-drive",
    mountPath: "/mnt/data",
    drivePath: "/",   // optional; defaults to root of the drive
  });
  ```

  ```python Python theme={null}
  from blaxel.core import SandboxInstance

  sandbox = await SandboxInstance.get("my-sandbox")

  await sandbox.drives.mount(
      drive_name="my-drive",
      mount_path="/mnt/data",
      drive_path="/", # optional; defaults to root of the drive
  )
  ```

  ```bash CLI theme={null}
  bl drive mount --sandbox my-sandbox --drive my-drive --mount-path /mnt/data
  ```
</CodeGroup>

Once mounted, any file written to `/mnt/data` inside the sandbox will be stored on the drive and persist even after the sandbox is deleted.

### Mount a subdirectory

You can mount a specific subdirectory of a drive rather than its root. This is useful when a single drive contains multiple project directories:

<CodeGroup>
  ```tsx TypeScript theme={null}
  await sandbox.drives.mount({
    driveName: "my-drive",
    mountPath: "/app/project",
    drivePath: "/projects/alpha",
  });
  ```

  ```python Python theme={null}
  await sandbox.drives.mount(
      drive_name="my-drive",
      mount_path="/app/project",
      drive_path="/projects/alpha",
  )
  ```

  ```bash CLI theme={null}
  bl drive mount --sandbox my-sandbox --drive my-drive --mount-path /app/project --drive-path /projects/alpha
  ```
</CodeGroup>

<Note>
  `drivePath` / `drive_path` controls the subtree visible to the sandbox. When combined with [drive permissions](/Agent-drive/Permissions), you can restrict a workload to a specific subfolder of a drive using the `path` field in a permission rule.
</Note>

### Mount a drive as read-only

You can mount a drive in read-only mode:

<CodeGroup>
  ```tsx TypeScript theme={null}
  await sandbox.drives.mount({
    driveName: "my-drive",
    mountPath: "/mnt/shared",
    readOnly: true,
  });
  ```

  ```python Python theme={null}
  await sandbox.drives.mount(
      drive_name="my-drive",
      mount_path="/mnt/shared",
      read_only=True,
  )
  ```

  ```bash CLI theme={null}
  bl drive mount --sandbox my-sandbox --drive my-drive --mount-path /mnt/shared --read-only
  ```
</CodeGroup>

The same drive can be mounted read-write in one sandbox and read-only in others. However, any write attempt to a drive mounted as read-only will fail with a permission error.

<Note>
  When [drive permissions](/Agent-drive/Permissions) are configured with `mode: "read"`, read-only access is enforced both at the FUSE mount level and at the storage server level. The workload's identity token is validated against the permission rules, preventing unauthorized remounting in read-write mode.
</Note>

## Access a drive over S3

Every drive also exposes an S3-compatible HTTP endpoint, so you can read and write its contents directly from any S3 client, such as the AWS CLI, boto3, or the AWS SDK for JavaScript, without mounting the drive into a sandbox first.

Requests must use SigV4 signing and path-style addressing (the bucket in the path, not the hostname). Credentials are a [service account](/Security/Service-accounts)'s [API key](/Security/Access-tokens): `AWS_ACCESS_KEY_ID` is the API key's record ID and `AWS_SECRET_ACCESS_KEY` is its raw secret value — **not** the service account's OAuth client ID/secret pair. Personal API keys and OAuth tokens are not supported for S3 access.

<Warning>
  Drive permission rules (labels, `path`, `mode`) are **not currently enforced** for S3 access. A valid service-account API key grants full read-write access to every drive in the workspace over S3, regardless of any [drive permissions](/Agent-drive/Permissions) configured on them. Only issue S3 credentials to service accounts you're comfortable giving full access to all drives in the workspace; enforcing permission rules over S3 is planned but not yet available.
</Warning>

<Note>
  API keys created before S3 support was added may not work for SigV4 signing and will return `InvalidAccessKeyId`. If you hit this error, create a new API key for the service account (or rotate the existing one) and use the new credentials.
</Note>

### Find a drive's S3 endpoint and bucket

The endpoint is returned in the drive's state as `s3Url`, in the form `{endpoint}/{bucket}`:

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { DriveInstance } from "@blaxel/core";

  const drive = await DriveInstance.get("my-drive");
  console.log(drive.state?.s3Url);
  ```

  ```python Python theme={null}
  from blaxel.core.drive import DriveInstance

  drive = await DriveInstance.get("my-drive")
  state = drive.drive.state
  print(state.s_3_url if state and state.s_3_url else None)  # low-level field name; a higher-level property is planned
  ```
</CodeGroup>

The bucket is the last path segment of `s3Url`; the rest of the URL is the endpoint to pass to your S3 client.

<Note>
  The Blaxel CLI does not currently expose the S3 endpoint via `bl drive get`. Use the TypeScript or Python SDK to retrieve it until CLI support is added.
</Note>

### Use the AWS CLI

Export the service account's API key as AWS-style credentials, then use standard `aws s3` commands with `--endpoint-url` and `--region` set to the drive's endpoint and region:

```bash theme={null}
export AWS_ACCESS_KEY_ID="<api-key-id>"       # the API key's record ID, not the service account's OAuth client ID
export AWS_SECRET_ACCESS_KEY="<api-key-secret>"  # the API key's raw secret value, not the OAuth client secret
```

```bash theme={null}
aws s3 ls "s3://<bucket>/" \
  --endpoint-url "<endpoint>" \
  --region "<drive-region>"
```

```bash theme={null}
aws s3 cp ./local.bin "s3://<bucket>/path/local.bin" \
  --endpoint-url "<endpoint>" --region "<drive-region>"
aws s3 cp "s3://<bucket>/path/local.bin" ./local.bin \
  --endpoint-url "<endpoint>" --region "<drive-region>"
```

<Tip>
  The region passed to the S3 client must match the drive's `region`, and the endpoint must be called with path-style addressing (the default for most S3 clients when a custom endpoint is set).
</Tip>

## List mounted drives

List all drives currently mounted to a sandbox:

<CodeGroup>
  ```tsx TypeScript theme={null}
  const mounts = await sandbox.drives.list();
  console.log(mounts);
  ```

  ```python Python theme={null}
  mounts = await sandbox.drives.list()
  print(mounts)
  ```

  ```bash CLI theme={null}
  bl drive mounts --sandbox my-sandbox
  ```
</CodeGroup>

## List all drives

To retrieve all drives in your workspace, use the built-in SDK pagination helper functions.

<Note>
  Pagination is recommended for list operations because retrieving all available resources in a single request is slow and resource-intensive, and therefore does not scale well.
</Note>

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { DriveInstance } from "@blaxel/core";

  const drives = await DriveInstance.list({ limit: 50 });
  for await (const drive of drives) {
    console.log(drive.name);
  }
  ```

  ```python Python theme={null}
  import asyncio
  from blaxel.core.drive import DriveInstance

  async def main():
      drives = await DriveInstance.list(limit=50)
      async for drive in drives.auto_paging_iter():
          print(drive.name)

  asyncio.run(main())
  ```

  ```bash CLI theme={null}
  bl drive list
  ```
</CodeGroup>

For more information on the SDK pagination helpers, refer to the [SDK reference documentation](/sdk-reference/introduction#pagination).

Pagination is also available via the Management API list endpoint.

Request the first page:

```bash theme={null}
curl 'https://api.blaxel.ai/v0/drives?limit=50' \
  -H 'X-Blaxel-Authorization: Bearer YOUR-API-KEY' \
  -H 'Blaxel-Version: 2026-04-28'
```

The response includes a `data` array and a `meta` object:

```json theme={null}
{
  "data": [ ... ],
  "meta": {
    "hasMore": true,
    "nextCursor": "...",
    "total": 24
  }
}
```

Pass `meta.nextCursor` as `cursor` on the next request and repeat until `meta.hasMore` is `false`:

```bash theme={null}
curl 'https://api.blaxel.ai/v0/drives?limit=50&cursor=NEXT_CURSOR' \
  -H 'X-Blaxel-Authorization: Bearer YOUR-API-KEY' \
  -H 'Blaxel-Version: 2026-04-28'
```

<Tip>
  For accounts with multiple workspaces, specify the workspace as an additional request parameter, such as `?workspace=WORKSPACE_NAME&...`, or via an additional `X-Blaxel-Workspace: WORKSPACE_NAME` header in the request.
</Tip>

For more information, refer to the [API reference documentation](/api-reference/introduction#pagination).

## Get drive details

Retrieve details about a specific drive:

```bash CLI theme={null}
bl drive get my-drive
```

## Unmount a drive

Unmount a drive from a running sandbox by specifying the mount path:

<CodeGroup>
  ```tsx TypeScript theme={null}
  await sandbox.drives.unmount("/mnt/data");
  ```

  ```python Python theme={null}
  await sandbox.drives.unmount("/mnt/data")
  ```

  ```bash CLI theme={null}
  bl drive unmount --sandbox my-sandbox --mount-path /mnt/data
  ```
</CodeGroup>

## Delete a drive

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { DriveInstance } from "@blaxel/core";

  // Class-level
  await DriveInstance.delete("my-drive");

  // Or instance-level
  const drive = await DriveInstance.get("my-drive");
  await drive.delete();
  ```

  ```python Python theme={null}
  from blaxel.core.drive import DriveInstance

  # Class-level
  await DriveInstance.delete("my-drive")

  # Or instance-level
  drive = await DriveInstance.get("my-drive")
  await drive.delete()
  ```

  ```bash CLI theme={null}
  bl drive delete my-drive
  ```
</CodeGroup>

<Tip>
  Complete code examples demonstrating all operations are available in Blaxel's GitHub repositories, [for TypeScript](https://github.com/blaxel-ai/sdk-typescript/tree/main/tests/integration/sandbox), [for Python](https://github.com/blaxel-ai/sdk-python/tree/main/tests/integration/core/sandbox), and [for Go](https://github.com/blaxel-ai/sdk-go/tree/main/integration_tests).
</Tip>

## Full example

The following example creates a drive, creates a sandbox from a custom sandbox image using its image ID, mounts the drive, writes a file to the mounted path, and reads it back:

<CodeGroup>
  ```tsx TypeScript theme={null}
  import { SandboxInstance, DriveInstance } from "@blaxel/core";

  // 1. Create a drive
  const drive = await DriveInstance.createIfNotExists({
    name: "agent-storage",
    region: "us-was-1",
  });

  // 2. Create a sandbox
  //    Use the image ID of the custom sandbox image
  const sandbox = await SandboxInstance.createIfNotExists({
    name: "my-agent-sandbox",
    image: "my-sandbox-image-id",
    memory: 2048,
    region: "us-was-1",
  });

  // 3. Mount the drive to the sandbox
  await sandbox.drives.mount({
    driveName: "agent-storage",
    mountPath: "/mnt/storage",
    drivePath: "/",
  });

  // 4. Write a file to the mounted drive
  await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!");

  // 5. Read it back
  const content = await sandbox.fs.read("/mnt/storage/hello.txt");
  console.log(content); // "Hello from the drive!"

  // 6. List mounted drives
  const mounts = await sandbox.drives.list();
  console.log(mounts);
  ```

  ```python Python theme={null}
  import asyncio
  from blaxel.core.drive import DriveInstance
  from blaxel.core import SandboxInstance

  async def main():
      # 1. Create a drive
      drive = await DriveInstance.create_if_not_exists(
          {
              "name": "agent-storage",
              "region": "us-was-1",
          }
      )

      # 2. Create a sandbox
      sandbox = await SandboxInstance.create_if_not_exists(
          {
              "name": "my-agent-sandbox",
              "image": "my-sandbox-image-id",
              "memory": 2048,
              "region": "us-was-1",
          }
      )

      # 3. Mount the drive to the sandbox
      await sandbox.drives.mount(
          drive_name="agent-storage",
          mount_path="/mnt/storage",
          drive_path="/",
      )

      # 4. Write a file to the mounted drive
      await sandbox.fs.write("/mnt/storage/hello.txt", "Hello from the drive!")

      # 5. Read it back
      content = await sandbox.fs.read("/mnt/storage/hello.txt")
      print(content)  # "Hello from the drive!"

      # 6. List mounted drives
      mounts = await sandbox.drives.list()
      print(mounts)

  asyncio.run(main())
  ```
</CodeGroup>

<CardGroup cols={2}>
  <Card title="Drive permissions" href="/Agent-drive/Permissions">
    Restrict which sandboxes, agents, or jobs can access a drive.
  </Card>

  <Card title="Sandboxes overview" href="/Sandboxes/Overview">
    Learn about sandbox lifecycle and configuration.
  </Card>
</CardGroup>
