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

# BYOC Storage

> Keep agent telemetry in a bucket in your own cloud account, and give Asymptote's hosted control plane read access to it.

With BYOC storage, the raw telemetry from your endpoints lands in a bucket in your own cloud account, and Asymptote's hosted control plane reads it with access you grant. You own the bucket and every object in it, and revoking Asymptote's read access stops it loading anything new. Asymptote runs the dashboard, search, detections and policy checks. See [Hosting Options](https://docs.asymptotelabs.ai/deployment/hosting-options.md) for how this compares with the other options.

## How data flows

```mermaid theme={null}
flowchart LR
  subgraph Endpoints["Your endpoints"]
    Beacon["AI agents and Beacon"]
  end
  subgraph Yours["Your cloud account (data plane)"]
    Bucket[("Telemetry bucket")]
    Queue["New-object queues"]
  end
  subgraph Asymptote["Asymptote's cloud (control plane)"]
    Loader["Loader"]
    Store[("Analytics store")]
    CP["Dashboard, API, policy service, detections"]
  end
  Beacon -->|"write-only credential"| Bucket
  Bucket -->|"new-object notice"| Queue
  Queue -->|"which objects are new"| Loader
  Bucket -->|"read-only access"| Loader
  Loader --> Store
  Store --> CP
```

1. **Upload.** A Vector forwarder on each endpoint uploads compressed batches of events to your bucket, with a credential that can add objects under one prefix. It cannot read or delete objects. On Google Cloud it cannot list them either; on AWS it can list object names by default, because the forwarder's startup health check needs `s3:ListBucket` (see the endpoint writer row below).
2. **Notify.** Each new object posts a notice to a queue or subscription in your account, one per stream (`runtime` for agent activity, `inventory` for what is installed). The queues let Asymptote load objects in any order, so an upload that arrives late, from a laptop that was offline, is never skipped.
3. **Load.** Asymptote's loader reads the notices, fetches each new object with read-only access, and loads it into your organization's own tables in Asymptote's analytics store.
4. **Use.** The dashboard, search, detections and background reviews read those tables, as in [Asymptote Cloud](https://docs.asymptotelabs.ai/deployment/asymptote-cloud.md).

## What you run and what Asymptote runs

| You (data plane) | Asymptote (control plane) |
| - | - |
| Beacon on each endpoint, with the forwarder settings for your bucket | The loader and the analytics store |
| The bucket, its encryption, versioning and lifecycle rules | The dashboard, API and sign-in |
| The endpoints' write-only credential, and its rotation | Policy checks, detections, background reviews and Slack notifications |
| Asymptote's read access, and revoking it | Upgrades, scaling and monitoring of the control plane |
| The new-object queues | |

## What Asymptote can see

Asymptote reads what your endpoints upload, after Beacon's local redaction of secrets, and keeps a copy in its analytics store so the dashboard can search it. The bucket forwarder uploads events in full: prompts, the commands agents ran and their output, tool inputs and outputs, and file paths and diffs. The [Metadata-only](https://docs.asymptotelabs.ai/cli/endpoint-connect.md#privacy-modes) privacy mode is a setting of the Asymptote Cloud forwarder and does not apply to uploads to your bucket.

Revoking the read credential stops new loads at once. The copy Asymptote already loaded stays under your agreement's retention terms unless you ask for it to be deleted.

### Policy enforcement with BYOC storage

[Policy enforcement](https://docs.asymptotelabs.ai/manage/policy-enforcement.md) does not go through your bucket. The hooks send each prompt or tool call being checked straight to Asymptote's policy service. Turning enforcement on also needs more than that today: `beacon endpoint enforcement enable` works only on a Mac connected to Asymptote in system mode (`beacon endpoint connect --system`), because it proves the device with that connection's key. A connected Mac also runs the Asymptote Cloud forwarder, which uploads its runtime telemetry to Asymptote's ingest as well as to your bucket, and `disconnect --keep-credentials` leaves the Mac not connected, so enforcement refuses to turn on. So with enforcement on, your telemetry also reaches Asymptote Cloud. `--no-backfill` on connect skips only the 30-day history upload. Talk to your Asymptote contact before turning enforcement on in a BYOC storage deployment.

## The BYOC component, by cloud

| Component | AWS | Google Cloud | Azure |
| - | - | - | - |
| **Status** | Available. [Setup guide](https://docs.asymptotelabs.ai/deployment/self-hosted-s3.md) | Available. [Setup guide](https://docs.asymptotelabs.ai/deployment/self-hosted-gcs.md) | By engagement |
| **Telemetry bucket** | A new, dedicated S3 bucket: public access blocked, ACLs disabled, HTTPS required, default encryption (SSE-S3 or your KMS key), versioning | A new, dedicated Cloud Storage bucket: uniform bucket-level access, public access prevention, versioning, Google-managed or your Cloud KMS key | A new storage account and container: public access disabled, HTTPS only, encryption with Microsoft-managed or your Key Vault key, blob versioning |
| **Endpoint writer** | IAM user `beacon-endpoint-writer`: `s3:PutObject` under the prefix, plus `s3:ListBucket` on the bucket by default, so it can list object names. The forwarder's startup health check needs it; `allow_writer_healthcheck = false` in the Terraform module, or leaving that statement out of the CLI policy, removes it, and the forwarder then logs a health-check error but still uploads | Service account `beacon-endpoint-writer`, `roles/storage.objectCreator` limited to the prefix by an IAM condition. It cannot read or list | A credential limited to creating and writing blobs in the container, such as a SAS token without read, list or delete |
| **Asymptote's read access** | IAM user `asymptote-s3-reader`: list the bucket, read under the prefix, consume the queues. An access key, because Asymptote's loader runs on Google Cloud and cannot assume an AWS role | `roles/storage.objectViewer` on the bucket for Asymptote's service account, `beacon-clickpipes-reader@asymptote-labs.iam.gserviceaccount.com`. No key changes hands | Read and list on the container, with a credential you can revoke |
| **New-object notifications** | One SQS queue per stream, each with a dead-letter queue, fed by S3 event notifications | A Pub/Sub topic fed by the bucket's `OBJECT_FINALIZE` notifications, with one subscription per stream | Event Grid notifications for new blobs, delivered to a Storage queue |
| **Infrastructure as code** | Terraform: [`aws-s3`](https://docs.asymptotelabs.ai/log-forwarding/aws-s3-terraform) for the bucket and writer, plus `aws-s3-asymptote-reader` for the reader and queues | Terraform: [`gcs`](https://docs.asymptotelabs.ai/log-forwarding/gcs-terraform) for the bucket and writer, plus `gcs-asymptote-reader` for the reader and subscriptions | Agreed during scoping |
| **What you send Asymptote** | Bucket, region and prefix, the queue URLs, the reader's access key, and your KMS key ARN if you use one | Bucket and prefix, and the subscription paths | Agreed during scoping |

> [!NOTE]
>
> Azure is not packaged yet. Beacon's forwarder helpers and the Terraform modules cover S3 and Cloud Storage, so an Azure deployment is set up with Asymptote as part of the engagement. [Contact us](https://asymptotelabs.ai/contact) to plan one.

## Get started

1. Ask your Asymptote contact to enable your organization for BYOC storage.
2. Follow the guide for your cloud: [Amazon S3](https://docs.asymptotelabs.ai/deployment/self-hosted-s3.md) or [Google Cloud Storage](https://docs.asymptotelabs.ai/deployment/self-hosted-gcs.md). Each covers the bucket, the access, what to send Asymptote, the rollout to your Macs and how to check that data arrives.
3. Roll Beacon out with your MDM. For S3: [Jamf](https://docs.asymptotelabs.ai/guides/jamf-s3-mdm.md), [Fleet](https://docs.asymptotelabs.ai/guides/fleet-s3-mdm.md) or [Rippling](https://docs.asymptotelabs.ai/guides/rippling-s3-mdm.md). For Cloud Storage: [Jamf](https://docs.asymptotelabs.ai/guides/jamf-gcs-mdm.md) or [Rippling](https://docs.asymptotelabs.ai/guides/rippling-gcs-mdm.md). Each sets up the forwarder and its credential for your bucket.

## Related

> [card] [Hosting Options](https://docs.asymptotelabs.ai/deployment/hosting-options.md)
>
> Compare BYOC storage with Asymptote Cloud and BYOC self-managed.

> [card] [Your own S3 bucket](https://docs.asymptotelabs.ai/deployment/self-hosted-s3.md)
>
> Set up the AWS bucket, access and queues step by step.

> [card] [Your own Cloud Storage bucket](https://docs.asymptotelabs.ai/deployment/self-hosted-gcs.md)
>
> Set up the Google Cloud bucket, access and subscriptions step by step.

> [card] [BYOC self-managed](https://docs.asymptotelabs.ai/self-hosting/self-hosted-asymptote.md)
>
> Run the control plane in your own cloud as well.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.