Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@

## Unreleased

No changes queued.

## 0.1.1 - 2026-10-09

- protect the reference HTTP server with authority/origin/fetch-metadata checks, JSON media-type
enforcement, strict action/file routes, and portable malformed-path errors;
- reject special filesystem write/list targets and cancel descendants after their group leader exits;
- validate an independently installed tarball, compile the packaged example, and smoke the actual
SDK/CLI through files, commands, SSE, recreation, fencing, and graceful resource cleanup;
- expand credential-shaped detection without printing matching values, including historical hits;
- make public-content scanning self-contained in Node.js and fail closed on scan/history errors,
including CI environments without ripgrep;
- isolate all test-created filesystem fixtures in unique temporary directories;
- align reference Provider and OpenAPI versions with the package and include a release acceptance map;
- allow generation-fenced termination during ambiguous pause/resume transitions;
- bound every conformance Provider call, validate timeout options, and verify cleanup state;
- use unique conformance create-intent keys and reject unsuccessful recovery before data-plane probes;
Expand Down
5 changes: 3 additions & 2 deletions DOCS-INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ authority: canonical
status: canonical
title: Sandbox Runtime API documentation index
genre: spec
last_verified: 2026-09-03
last_verified: 2026-10-09
---

# Documentation Index

## Active context

The `v0.1` MVP is the current public baseline. It owns portable lifecycle, capability negotiation,
The `v0.1.1` delivery implements the `0.1` contract. It owns portable lifecycle, capability negotiation,
command and file operations, event replay, the TypeScript SDK, the loopback-only reference server,
the unsafe Local Provider, and provider conformance.

Expand All @@ -35,6 +35,7 @@ network policy enforcement, snapshots, PTY, and port forwarding remain outside t
- [API and SDK guide](docs/api-and-sdk.md)
- [Local Provider](docs/providers/local.md)
- [Testing and conformance](docs/testing.md)
- [Release archive and acceptance map](docs/delivery.md)
- [Clean-room policy](docs/clean-room-policy.md)
- [Visual source and validation register](docs/visuals/README.md)

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ portable sandbox semantics.

## v0.1 Features

Version `0.1.0` contains:
Version `0.1.1` builds on the original `0.1.0` baseline and contains:

- a normative runtime model, protocol, capability vocabulary, and OpenAPI document;
- capability preflight;
Expand Down Expand Up @@ -79,6 +79,9 @@ pnpm build
Continue with the [Quickstart](docs/quickstart.md) or open the
[documentation index](DOCS-INDEX.md).

For a prebuilt, independently installable SDK/CLI archive, use the
[GitHub release guide](docs/delivery.md). npm registry publication is not enabled.

## Repository Map

| Path | Purpose |
Expand Down
5 changes: 4 additions & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Harness 执行;Sandbox Runtime API 规范 Harness 或工具运行所需的隔

## v0.1 能力

`0.1.0` 包含:
`0.1.1` 在原始 `0.1.0` 基础上包含:

- 规范化 Runtime 模型、协议、能力词表与 OpenAPI;
- capability preflight;
Expand All @@ -65,6 +65,9 @@ pnpm build

继续阅读 [快速开始](docs/quickstart.md) 或 [文档索引](DOCS-INDEX.md)。

预构建 SDK/CLI 安装包和最终验收标准见 [GitHub 交付指南](docs/delivery.md)。
当前不向 npm 注册表发布。

## Clean-room 边界

本仓库只基于公开规范、公开仓库和通用分布式系统原则独立设计。禁止提交私有代码、私有 API、
Expand Down
21 changes: 20 additions & 1 deletion SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authority: canonical
status: canonical
title: Security policy and deployment boundary
genre: spec
last_verified: 2026-09-02
last_verified: 2026-10-09
---

# Security Policy
Expand All @@ -18,6 +18,25 @@ The project is pre-1.0. Security fixes are applied to the latest development rel
Use GitHub private vulnerability reporting when enabled. Do not open a public issue containing
exploit details, credentials, private infrastructure, prompts, or user data.

## Reference HTTP defenses

The default server requires a loopback request authority and the actual listening port. It rejects
mismatched/opaque `Origin`, cross-origin fallback `Referer`, and cross-site/same-site Fetch Metadata
when present. JSON body
endpoints require `Content-Type: application/json`. Malformed paths return portable validation errors;
extra route components do not invoke actions; responses disable MIME sniffing. These controls apply
before Provider operations, including event and resource reads.

The explicit `allowUnsafeNetwork` override permits non-loopback bind/authority names, but does not
remove origin, Fetch Metadata, JSON, or port checks. The server does not trust proxy forwarding
headers. There is no CORS allowlist or proxy-authentication feature.

SDK/CLI clients may omit browser metadata. These checks are not authentication: local processes can
still use the server. Do not expose it through a public reverse proxy. The rationale follows public
[OWASP CSRF guidance](https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html)
on simple content types and complete-origin comparison, plus independent authority validation for a
directly accessed development server.

## Deployment boundary

The reference runtime and mock provider are development implementations. They do not provide:
Expand Down
4 changes: 2 additions & 2 deletions docs/00-v0.1-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ As of 2026-10-09, the original MVP has shipped as
`0b513eae4d88ac1c7b60f46b00ad7bd5b587e652`, with
[passing main CI](https://github.com/capa-cloud/sandbox-runtime-api/actions/runs/33732582026).

Maintenance after the tag is tracked under [Unreleased](../CHANGELOG.md). It does not change the
contents of the existing v0.1.0 tag. Use [Testing and conformance](testing.md) for current verification
Maintenance after the original tag is tracked in the [Changelog](../CHANGELOG.md), including the
`0.1.1` delivery. It does not change the existing v0.1.0 tag. Use [Testing and conformance](testing.md) for current verification
commands; the main-branch CI badge in the README shows current repository health.

## Architecture decision
Expand Down
90 changes: 90 additions & 0 deletions docs/delivery.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
---
id: release-delivery
authority: reference
status: active
title: Release delivery and acceptance
genre: primer
last_verified: 2026-10-09
---

# Release Delivery and Acceptance

## Scope

Version `0.1.1` delivers the public `0.1` contract, TypeScript SDK, reference runtime/server/CLI,
Mock and unsafe Local Providers, conformance runner, documentation, diagrams, and a prebuilt archive.
This is development infrastructure, not a hosted or production-isolated sandbox service.

The [roadmap](../ROADMAP.md) distinguishes completed work from candidate extensions. A real cloud,
container, or Kubernetes Provider requires a separate public-source RFC, capability map, isolation
boundary, and opt-in integration evidence. Those candidates are not unfinished parts of this release.

## Install a release archive

Download `sandbox-runtime-api-0.1.1.tgz` and `SHA256SUMS.txt` from the
[v0.1.1 GitHub release](https://github.com/capa-cloud/sandbox-runtime-api/releases/tag/v0.1.1).
Verify the archive before installing:

```bash
shasum -a 256 -c SHA256SUMS.txt
npm install --ignore-scripts ./sandbox-runtime-api-0.1.1.tgz
npx sandbox-runtime serve --host 127.0.0.1 --port 4311
```

Node.js 22 or later runs the package; source development uses Node.js 22.12+ (22.x) or 24.x and
pnpm 10. The package has no production dependencies. `private: true` intentionally prevents accidental
npm registry publication; it does not prevent local installation of the archive.

The CLI uses the **unsafe Local Provider**. Only run trusted, synthetic development commands, never
untrusted or AI-generated code. Ctrl-C cleans active resource directories. User-supplied `--root`
directories are retained; only this Provider's resource directories are removed.

For embedding without host execution, start with the packaged
[Mock example](../examples/embedded-runtime.mts). For HTTP operations, use the
[API/SDK guide](api-and-sdk.md) and [quickstart](quickstart.md).

## Requirement-to-evidence map

| Requirement | Verifier | What it establishes |
| --- | --- | --- |
| Contract/version alignment | spec tests, `pnpm docs:check` | HTTP routes, vocabulary, errors, OpenAPI and Provider versions |
| Lifecycle/capabilities | runtime tests | preflight, idempotency, concurrency, reconciliation, pause/resume, termination/recreation |
| Generation fencing | runtime and HTTP/SDK tests | reject stale-generation mutations and file reads; resource discovery remains available |
| Commands/files | Local and local-boundary tests | argv, limits, cancellation, regular-file boundaries, traversal and cleanup |
| SDK/HTTP/SSE | HTTP/SDK tests | mapping, error normalization, replay, stream closure and disconnect cancellation |
| Browser boundary | server-security tests | authority/origin rejection, JSON types, exact routing, no mutation on denied requests |
| Provider compatibility | conformance/deadline tests | manifest/method alignment, bounded calls, ambiguous failure cleanup and result validation |
| Independent consumer | `pnpm pack:check` | tarball links/assets; clean install; compiled example/types; real CLI and SDK scenarios |
| Public safety | `pnpm sanitize`, scanner tests and semantic review | credentials/history, machine paths and media metadata; scanner output does not print matched values |
| Supply chain/CI | full dependency audit, Node.js 22/24 CI | frozen lockfile and complete verification on both development lines |

`pnpm check` is the full local gate; CI additionally runs `pnpm sanitize` and a production dependency
audit. Exact commit, CI runs, scan triage, artifact checksums, and publication read-back belong in
release notes and merged PR evidence. Counts in the [original v0.1 summary](00-v0.1-summary.md) remain
dated evidence, not current health assertions.

## Security and provenance

Review covers HTTP inputs, lifecycle fencing, command/process cleanup, filesystem operations,
distributed package contents, and publication safety. Fixtures use task-owned temporary directories.
Default tests need no cloud credentials, real accounts, production responses, private repositories,
or customer data.

HTTP request defenses do not authenticate a local process. Commands retain host-user permissions.
POSIX process-group cancellation covers ordinary descendants, not adversarial children that detach
into another session. Windows does not provide the same POSIX semantics; Unix FIFO/descendant
regressions are not asserted there. CI verifies Linux; local validation also verifies macOS.

Passing these gates is not isolation, production availability, penetration-testing, or compliance
certification. See [Security policy](../SECURITY.md), [Local Provider](providers/local.md), and
[provenance](../ORIGIN_AND_PROVENANCE.md) before extending the project.

## Maintenance and next development

Start at [DOCS-INDEX](../DOCS-INDEX.md). Canonical `spec/` sources own the contract; implementation and
fresh tests own behavior; dated summaries and releases own historical evidence. Begin an approved
follow-up from a clean branch in the owning public repository. A candidate item, branch, or empty
directory alone does not establish an active phase.

Coordinate Vitest/coverage upgrades, rerun all gates after substantive changes, and preserve existing
release tags. Do not lower capability or security assertions just to make tests pass.
7 changes: 6 additions & 1 deletion docs/providers/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authority: reference
status: active
title: Local Provider boundary
genre: primer
last_verified: 2026-09-03
last_verified: 2026-10-09
---

# Local Provider
Expand Down Expand Up @@ -49,7 +49,12 @@ File operations reject:
- lexical `..` escape;
- existing paths whose real path escapes the sandbox directory;
- symbolic-link entries and symbolic-link write targets;
- FIFOs, sockets, devices, and other non-regular write/list targets;
- files above the configured byte limit;
- malformed base64 input.

These controls protect the file API contract. They do not constrain a spawned command.

Writes verify the opened descriptor is a regular file before truncating. Process-group cancellation
also applies when the group leader has exited but ordinary descendants still hold output streams.
These are development reliability controls, not kernel isolation or an adversarial process supervisor.
8 changes: 7 additions & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ authority: reference
status: active
title: Local quickstart
genre: how-to
last_verified: 2026-09-02
last_verified: 2026-10-09
---

# Local Quickstart
Expand All @@ -14,6 +14,9 @@ last_verified: 2026-09-02

## Install and verify

This section builds from a Git checkout. For an independently installable prebuilt archive, see
[Release delivery](delivery.md).

```bash
pnpm install
pnpm check
Expand All @@ -28,6 +31,9 @@ node dist/cli.js serve --host 127.0.0.1 --port 4311

The server prints its base URL and binds to loopback by default. It has no authentication and refuses
a non-loopback address unless the embedding application explicitly enables the unsafe override.
Requests must use a loopback authority with the listening port. Browser metadata must identify the
same origin; JSON body endpoints reject simple form/text media types. These checks do not authenticate
local processes or make the Local Provider safe for untrusted code.

## Create and use a sandbox

Expand Down
11 changes: 9 additions & 2 deletions docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ pnpm audit:dependencies

`pnpm check` runs formatting, lint, type checking, the complete test suite, documentation validation,
build, coverage thresholds, and actual tarball validation. The package gate checks exports, CLI,
documentation, and every packaged Markdown local link, including image assets. CI runs the same gates
on Node.js 22 and 24. The final check gate audits all dependencies, including development tooling,
documentation, and every packaged Markdown local link, including image assets.
The package gate also performs an isolated install, compiles the packaged Mock example, and runs the
actual SDK/CLI through command, files, SSE, recreation, fencing, and shutdown cleanup.
CI runs the same gates on Node.js 22 and 24. The final check gate audits all dependencies, including
development tooling,
against high-severity advisories and requires registry access. CI then runs the public-content scan
and a separate production dependency audit.

The public-content scanner uses Node.js built-ins, not an optional `rg`/`strings` installation.
Unreadable roots or failed Git history scans fail closed. Regression fixtures explicitly remove
ripgrep from `PATH` and verify that detection still blocks publication without printing values.

## Test dimensions

| Dimension | Coverage |
Expand Down
19 changes: 19 additions & 0 deletions examples/embedded-runtime.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { InMemorySandboxRuntime, MockSandboxProvider } from 'sandbox-runtime-api'

// The Mock Provider executes no host code. This example needs no credentials.
const runtime = new InMemorySandboxRuntime(new MockSandboxProvider())
const context = { requestId: 'embedded-example' }
const resource = await runtime.create({ clientRequestId: 'example-create' }, context)
const result = await runtime.execute(
resource.id,
{
expectedGeneration: resource.generation,
argv: ['synthetic-probe'],
},
context,
)
await runtime.terminate(resource.id, resource.generation, context)
if (result.exitCode !== 0 || runtime.get(resource.id).state !== 'terminated') {
throw new Error('embedded example failed')
}
console.log('embedded package example passed')
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sandbox-runtime-api",
"version": "0.1.0",
"version": "0.1.1",
"private": true,
"description": "A provider-neutral runtime contract for isolated AI agent execution environments.",
"license": "Apache-2.0",
Expand Down Expand Up @@ -33,6 +33,7 @@
"dist",
"docs",
"spec",
"examples",
"DOCS-INDEX.md",
"README.md",
"README.zh-CN.md",
Expand Down Expand Up @@ -65,9 +66,9 @@
"devDependencies": {
"@biomejs/biome": "2.5.14",
"@types/node": "22.20.4",
"@vitest/coverage-v8": "5.0.2",
"@vitest/coverage-v8": "5.0.3",
"typescript": "7.0.2",
"vitest": "5.0.2",
"vitest": "5.0.3",
"yaml": "2.9.1"
}
}
Loading
Loading