maf-sandbox-acas
Experimental. Releases before 1.0 may change or remove APIs. Importing this package emits
MafSandboxAcasExperimentalWarning.
Run workloads in microVM-isolated Azure Container Apps Sandboxes. This backend supplies commands, input and output files, directory listing and guest-to-host tool calls.
This is an independent package for Microsoft Agent Framework, built on the Azure Container Apps Sandboxes preview. It is not a Microsoft product.
Quickstart
pip install maf-sandbox-acas
from maf_sandbox import SandboxRouter
from maf_sandbox_acas import AcasSandboxBackend, AcasSandboxConfig
backend = AcasSandboxBackend(
AcasSandboxConfig(
endpoint="https://management.<region>.azuredevcompute.io",
subscription_id="<sub-id>",
resource_group="<resource-group>",
sandbox_group="<sandbox-group>",
registry="<registry>.azurecr.io",
)
)
router = SandboxRouter([backend])
The backend meets the router's default microVM minimum. The isolation boundary is provided by the Azure service.
Authentication defaults to DefaultAzureCredential. The SDK is pinned to azure-containerapps-sandbox==0.1.0b4; the adapter needs its tested byte-capture and file-metadata interfaces.
See the Bicep sample or CodeAct sample for caller context, tool wiring and teardown.
Images and capabilities
| Image setting | Resolution |
|---|---|
Bare name, such as python-3.13 |
The service's prebuilt image catalogue. |
Tagged reference, such as bicep-sandbox:0.46.1 |
A disk image already imported into this sandbox group; registry qualifies short references. |
image_id |
A pinned service disk-image ID; no reference lookup. |
Unknown bare names are refused. Tagged references must be imported before use. The scripts guide covers import and lifecycle recovery.
| Setting | Value |
|---|---|
| Isolation / guest | MICROVM / POSIX |
| Capabilities | EXEC, FILES_IN, FILES_OUT, FILES_LIST, FILES_DELETE, HOST_TOOLS |
| Network | CLOSED or host ALLOWLIST |
| Lifetime | Conversation or separate sandbox per call |
| Transfer ceiling | 32 MiB per file, 128 MiB total, 128 files in each direction |
| Cleanup | Disposal; no reclaim or snapshot reset |
Capabilities also depend on the image. Acquisition checks byte-capture utilities and guest removal behavior. Missing prerequisites refuse the requested capability. Output collection and host tools can be refused when the guest cannot remove a probe file beside uploaded files.
Command capture needs sh, mkdir, mkfifo, head, cat, wc, dd, base64, rm, rmdir and writable /tmp. Host tools also need mv and nohup. The workload supplies its own interpreter or compiler.
File authority and limits
Acquisition prepares the storage base as the guest: it creates any missing directories with mkdir run under the guest's own authority, never the file plane's, so a parent swapped mid-preparation can only redirect a creation to where the guest could already have made one. Acquisition refuses when the guest cannot create a missing directory. work_dir=None selects /maf-sandbox/work; an explicit path selects that exact base. Existing directories keep their contents, ownership and modes; preparation does not check whether the guest could create or write to them. For a workload that needs to write, bake a guest-writable base into a non-root image, or place work_dir under a writable parent such as /tmp.
Writes always run as the guest. The image needs a guest-writable directory and the shell transfer utilities. A permission failure has no privileged file-API fallback. Bake the writable base into a non-root image rather than assuming acquisition will grant access.
The transfer stages base64 chunks and renames the complete file into place. read_timeout_seconds bounds the whole transfer. Larger files cost more guest commands and can time out before reaching the declared byte ceiling.
remove also runs as the guest, then checks absence through the file API. The path checks and guest command are separate; a changed parent can redirect the operation within the guest's existing permissions.
Native reads retain a path race
Reads, stat and listing use the service's file API with host authority. They reject links observed during checks, but cannot hold those paths unchanged through the operation.
| Method | A concurrent replacement can expose |
|---|---|
read_file |
Bytes outside the checked directory, including bytes the guest cannot read. |
stat_file |
Metadata outside the checked directory. |
list_dir |
Names and metadata from another directory. |
The service's file flags also cannot reliably distinguish a FIFO from an empty regular file. A bounded read timeout prevents an endless wait; it does not establish that the entry is regular.
Byte caps, timeouts, root images and disposal do not close the path race. Select a backend with a held filesystem boundary when that guarantee is required. See the file contract.
Network and identity
The spec supplies network policy. The backend applies default deny and one allow rule per permitted host. It provides no method-level enforcement declaration or egress observations.
A warm instance keeps its original network policy. Changing mode or hosts raises AcasEgressPolicyConflict. Coordinate active calls and dispose that kind successfully before changing policy, or use another key.
Managed identity configured on the sandbox group is deployment-owned authority. The host must route workloads to groups with the intended permissions. The adapter performs no ARM assignment discovery and does not apply core ATTACHED_IDENTITY opt-in or retention checks to that identity.
The host's SDK credential remains outside the guest. Deleting sandboxes does not revoke group principals or previously issued tokens.
Host-selected credentials
Set credential_resolver to an async callback returning AcasCredentialBinding(authority, generation, create_credential). Its request identifies acquire, disposal or conversation purge and the trusted scope and conversation.
Acquire may use a request grant. Disposal must independently recover a cleanup grant, including on another host replica. Resolver failure never falls back to default identity.
The factory creates a fresh async credential on its owning loop; the backend owns closure. Shared singleton credentials are unsupported. Equal authority and generation values assert equivalent grants. Use a new generation when authentication state changes.
| Setting | Default |
|---|---|
max_clients_per_loop |
32 |
client_wait_seconds |
30 seconds |
client_close_seconds |
30 seconds |
Capacity applies per host replica and event loop. Call await backend.aclose() before stopping owner loops. It permanently refuses new work and raises AcasClientCloseError if SDK cleanup is incomplete. It closes clients; it does not delete sandboxes.
See the credential guide for host wiring and grant rotation. Offline tests do not verify Azure's acceptance of a particular delegated token.
Execution and cleanup
Core disposes after each sandboxed tool call. Direct callers must arrange disposal too. dispose(key, kind=...) reaches locally known instances; dispose_scope(scope, thread_id) queries service labels and can find another replica's sandboxes.
Stop new work across replicas before conversation deletion. Local acquisition and purge guards do not coordinate other processes. Retained deletion failures refuse acquisition until cleanup succeeds; incomplete purges need retry.
The backend configures service auto-suspend and auto-delete on new sandboxes. These timers supplement host cleanup. See the lifecycle contract for configuration failure and retention limits.
ExecResult preserves program bytes in stdout_bytes and stderr_bytes; text views use UTF-8 replacement decoding. After complete capture, a reported scratch-removal failure warns and returns the captured result. Scratch may remain until disposal.
Incomplete capture, exceptions, cancellation and execution timeouts invalidate and attempt to dispose the sandbox. A deadline during an observed HTTP 429 Retry-After sleep can retain it because no retry started. That exception does not cover direct cancellation or other retry statuses.
The backend guide covers probes and failure behavior. The live service suite requires Azure credentials and configured images; it is separate from ordinary offline checks.
Maintained by SOKOLAI BV.
Release files for maf-sandbox-acas 0.27.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| maf_sandbox_acas-0.27.1.tar.gz | 49.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| maf_sandbox_acas-0.27.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 101.2 kB
Release files / maf_sandbox_acas-0.27.1.tar.gz
| Download URL | maf_sandbox_acas-0.27.1.tar.gz |
|---|---|
| Size | 49.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
869f7f16fed9915e74aa7dfbec026e5706dda88e6c169952ccf7d3b7b444b2b0
|
|
BLAKE2b-256 checksum How to use checksums |
0bac9932f3e60bfb19aa49738d1b66b93181ea140899108d791d6766d0606eda
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency logRelease files / maf_sandbox_acas-0.27.1-py3-none-any.whl
| Download URL | maf_sandbox_acas-0.27.1-py3-none-any.whl |
|---|---|
| Size | 52.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
47aa2f89428d6fd8aaea70b7b7c930dde9c6e5166923f7844af219e68a8aae92
|
|
BLAKE2b-256 checksum How to use checksums |
b2f1f521d30c1e417ed0162ace106b4d3aa6b09fd73f9de69e333e30cfaf3019
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 24, 2026.
Transparency log