You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit d24c951
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: README.md
+341Lines changed: 341 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -397,6 +397,343 @@ process-global Sandbox URL override. Native A3S SDK applications use only
397
397
`A3S_BOX_*` connection settings and do not read `E2B_API_URL`; that variable is
398
398
reserved for the optional unchanged-official-SDK migration path.
399
399
400
+
#### Self-hosted usage
401
+
402
+
`a3s-box-e2b` is a network service. The Python and TypeScript packages connect
403
+
to that service; they do not start a local Box runtime. The production-tested
404
+
preview requires a Linux Sandbox host with the certified `crun` runtime, a
405
+
public control-plane address, and a TLS Sandbox gateway with wildcard DNS.
406
+
See [Host Sandbox Backend Design](docs/host-sandbox-backend-design.md) for the
407
+
host boundary and [E2B-Compatible SDK Design](docs/e2b-compatible-sdk-design.md)
408
+
for the complete protocol and release gates.
409
+
410
+
The simplest single-host production topology uses two public listeners:
411
+
412
+
| Public address | Purpose | Service destination |
413
+
| --- | --- | --- |
414
+
|`https://api.box.example.com`| Control API used by `A3S_BOX_ENDPOINT`| TLS reverse proxy to `api_listen`, for example `127.0.0.1:3000`|
415
+
|`https://<port>-<sandbox-id>.box.example.com:8443`| Direct Sandbox data plane |`gateway.listen`, for example `0.0.0.0:8443`|
416
+
|`https://sandbox.box.example.com:8443`| Shared Sandbox route form | The same `gateway.listen`|
417
+
418
+
Create explicit DNS for `api.box.example.com` and wildcard DNS for
419
+
`*.box.example.com`. The Sandbox gateway terminates TLS itself and its
420
+
certificate must cover `*.box.example.com`. Port `8443` avoids competing with
421
+
the control-plane TLS proxy on a single IP. A deployment with separate IP
422
+
addresses or an SNI-aware load balancer can use port `443` for both.
423
+
424
+
The client and server settings map as follows:
425
+
426
+
| Client setting | What to enter | Matching server setting |
427
+
| --- | --- | --- |
428
+
|`A3S_BOX_ENDPOINT`| The externally reachable control API origin, including `http://` or `https://` and any non-default port |`e2b_compat.api_public_url`|
429
+
|`A3S_BOX_API_KEY`| The **raw** API key issued to this client | The raw key whose PBKDF2-SHA256 encoding is stored in `account.hash`|
430
+
|`A3S_BOX_DOMAIN`| Optional Sandbox wildcard suffix, with no scheme or port |`e2b_compat.sandbox_domain`|
431
+
|`A3S_BOX_SANDBOX_URL`| Single-Sandbox fixture override only; normally unset | Not a production multi-Sandbox setting |
432
+
433
+
Use the bare control origin for `A3S_BOX_ENDPOINT`. Do not append `/api`,
434
+
`/v1`, `/sandboxes`, a query string, or a fragment, and omit the trailing
`A3SConnectionConfig` passes the API key to the pinned E2B client, which sends
694
+
it as `X-API-Key`. It derives `A3S_BOX_DOMAIN` only when the endpoint hostname
695
+
starts with `api.`; otherwise set the domain explicitly.
696
+
697
+
##### 5. Use unchanged official E2B SDKs
698
+
699
+
The unchanged official SDKs use their own environment names. Point them at the
700
+
same A3S Box service without setting a process-global Sandbox URL:
701
+
702
+
```bash
703
+
export E2B_API_URL="${A3S_BOX_ENDPOINT}"
704
+
export E2B_API_KEY="${A3S_BOX_API_KEY}"
705
+
export E2B_DOMAIN="box.example.com"
706
+
unset E2B_SANDBOX_URL
707
+
```
708
+
709
+
The generated `e2b_` key passes the official clients' default API-key
710
+
validation. Do not set `E2B_SANDBOX_URL` to the shared
711
+
`sandbox.<domain>` endpoint in a multi-Sandbox deployment: it is a fixed URL,
712
+
and file-transfer URLs would lose the Sandbox identity. The native A3S
713
+
packages intentionally ignore these `E2B_*` connection variables.
714
+
715
+
##### Troubleshooting
716
+
717
+
| Symptom | Check |
718
+
| --- | --- |
719
+
|`A3S_BOX_ENDPOINT is required`| Export it in the same process that starts the application; the native package does not read `E2B_API_URL`. |
720
+
| HTTP `401`|`A3S_BOX_API_KEY` must be the raw `e2b_...` value, not `account.hash`; also confirm the reverse proxy preserves `X-API-Key`. |
721
+
| Official SDK rejects the key before sending a request | Regenerate it in the required `e2b_[0-9a-f]+` form. Uppercase hex and `a3s_` prefixes are rejected by the current compatibility service. |
722
+
| HTTP `404` from every SDK operation | Remove `/api`, `/v1`, `/sandboxes`, and the trailing slash from `A3S_BOX_ENDPOINT`; ensure the reverse proxy does not add or strip a path prefix. |
723
+
| Control listing works but commands, files, PTY, or health fail | Check wildcard DNS, gateway firewall/port, wildcard certificate trust, and `sandbox_public_domain`. |
724
+
| TLS hostname mismatch on a Sandbox URL | The certificate must cover `*.sandbox_domain`; `A3S_BOX_DOMAIN` contains only the DNS suffix, without a scheme or port. |
725
+
| A custom control hostname routes Sandbox calls to the wrong domain | Set `A3S_BOX_DOMAIN` exactly to `e2b_compat.sandbox_domain`. |
726
+
| Sandbox creation reports an unknown template | Pass a template ID declared by `template_policy`, such as `a3s-base`. |
727
+
| Existing Sandbox tokens fail after a restart | Restore the token encryption/digest key version used to issue them; rotate with a new retained version instead of replacing key material in place. |
728
+
729
+
Use HTTPS everywhere outside loopback, never commit raw account or token keys,
730
+
and keep credentials out of logs. To rotate an account key without an outage,
731
+
add a second `account` block with the same `owner_id`, a new label and
732
+
`client_id`, and the new hash; restart the service, update clients, then remove
733
+
the old account in a later restart.
734
+
735
+
#### Current implementation status
736
+
400
737
The Phase 2 preview includes an owner-scoped Rust lifecycle router for create,
|`A3S_BOX_ENDPOINT`| Native Python/TypeScript SDK control-plane origin for the E2B-compatible service, for example `https://api.box.example.com`. Do not append an API path or trailing slash. |
1398
+
|`A3S_BOX_API_KEY`| Raw self-hosted compatibility API key sent as `X-API-Key`. It must match `e2b_[0-9a-f]+`; do not use the PBKDF2 hash stored in the server ACL. |
1399
+
|`A3S_BOX_DOMAIN`| Optional Sandbox wildcard DNS suffix when it cannot be derived from a conventional `https://api.<domain>` endpoint. Do not include a scheme or port. |
1400
+
|`A3S_BOX_SANDBOX_URL`| Fixed single-Sandbox fixture override. Leave unset for normal self-hosted multi-Sandbox deployments. |
0 commit comments