Skip to content

OSEP-0015: Declarative Sandbox Features#1302

Open
GodBlf wants to merge 7 commits into
opensandbox-group:mainfrom
GodBlf:feat/1289-declarative-sandbox-features
Open

OSEP-0015: Declarative Sandbox Features#1302
GodBlf wants to merge 7 commits into
opensandbox-group:mainfrom
GodBlf:feat/1289-declarative-sandbox-features

Conversation

@GodBlf

@GodBlf GodBlf commented Jul 15, 2026

Copy link
Copy Markdown

Summary

  • add OSEP-0015 defining the public API and lifecycle for declarative sandbox features
  • specify an administrator-controlled, digest-pinned OCI feature registry and self-contained artifact contract
  • define Docker pre-start injection and ordered Kubernetes init-container provisioning
  • document compatibility limits, security boundaries, failure semantics, testing, and phased implementation
  • complete the OSEP indexes with OSEP-0013, OSEP-0014, and OSEP-0015

Key decisions

  • online lifecycle JSON uses structured features entries, while SDKs may provide name@version conveniences
  • successful create/get responses persist ordered resolvedFeatures with exact version, OCI digest, OS, and architecture
  • callers cannot provide arbitrary OCI references, and provisioning cannot depend on base-image package managers or dependency downloads
  • version 1 supports Linux image-based standard creation on Docker and current Kubernetes workload providers; pool mode, snapshot restore, Windows, and dynamic mutation are rejected
  • deny_tools is excluded because command-name and PATH filtering are bypassable and do not form an enforceable security boundary

Related to #1289. This proposal does not close the issue; it should remain open until the OSEP is approved and the end-to-end implementation is complete.

Validation

  • cd docs && pnpm docs:build
  • git diff --check
  • verified all OSEP-0015 TOC anchors
  • verified both indexes are ordered through OSEP-0015

@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Jul 15, 2026
@GodBlf
GodBlf marked this pull request as ready for review July 15, 2026 09:51
Copilot AI review requested due to automatic review settings July 15, 2026 09:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds OSEP-0015 as a new enhancement proposal defining a public API and lifecycle for declarative, administrator-approved sandbox “features” (digest-pinned OCI artifacts provisioned pre-start across Docker and Kubernetes), and updates OSEP indexes to include OSEP-0013 through OSEP-0015.

Changes:

  • Added OSEP-0015 proposal document defining the contract, registry model, OCI artifact requirements, and Docker/Kubernetes provisioning semantics.
  • Updated the OSEP index lists under oseps/ and docs/community/ to include OSEP-0013, OSEP-0014, and OSEP-0015.
  • Linked OSEP-0015 from the docs community OSEP index.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
oseps/README.md Adds OSEP-0013/0014/0015 entries to the OSEP list.
oseps/0015-declarative-sandbox-features.md New OSEP describing declarative sandbox features: API shape, registry allowlist, artifact contract, provisioning flows, and phased implementation/testing plan.
docs/community/oseps.md Adds OSEP-0015 to the docs-site OSEP index.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread docs/community/oseps.md Outdated
Comment on lines +29 to +30
| [OSEP-0014](https://github.com/opensandbox-group/OpenSandbox/blob/main/oseps/0014-multi-tenancy.md) | Multi-Tenancy Support for Kubernetes Runtime | draft | 2026-04-29 |
| [OSEP-0015](https://github.com/opensandbox-group/OpenSandbox/blob/main/oseps/0015-declarative-sandbox-features.md) | Declarative Sandbox Features | draft | 2026-07-14 |

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: de7e5b60bf

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +933 to +936
and end-to-end coverage. New SDKs send `features` only when a caller requests
them. They must not downgrade the request into `extensions` when connected to an
older server; the older server's unsupported-field response is safer than
silently creating a sandbox without requested tools.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard feature requests against older servers

With a new SDK talking to any current/pre-feature server, this migration plan assumes the unknown top-level features field will be rejected, but the existing CreateSandboxRequest model only sets populate_by_name and does not forbid extra fields (server/opensandbox_server/api/schema.py:534-535), so Pydantic will ignore the field and create a sandbox without the requested tools. The rollout needs an explicit compatibility guard/version check, or a prior server change to reject unknown fields, before relying on this failure mode.

Useful? React with 👍 / 👎.

Comment on lines +481 to +483
4. Add a final activation-compiler init container from the pinned execd image.
It validates all activation documents against the request environment and
writes one ordered, shell-escaped activation file into the shared volume.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Persist activation documents before compiling them

In the Kubernetes flow, the preceding feature init step only places payload/ under features/<name>/<version>, but activation.json is defined outside payload/; this final compiler therefore has no activation documents to read for any feature that declares env or PATH changes. The contract should require the installer/provisioning step to copy validated activation metadata into the shared volume before this compiler runs, otherwise Kubernetes creates will either fail here or silently miss activation.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eef0444437

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +314 to +316
it. SDKs MUST call this endpoint, or use a result cached for the same resolved
server base URL and authentication context, before the first create with a
non-empty `features` list.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind capability negotiation to the create target

In a rolling or mixed-version deployment, this separate cacheable GET can reach a feature-aware instance while the subsequent create reaches an older instance; a rollback behind the same URL can also leave the cached result valid. Because lines 296-299 establish that those older instances silently ignore features, the sandbox can still start without its requested tools despite this new guard. Require a fleet-wide compatibility gate/prior server change or another mechanism that guarantees the create is handled by the negotiated server version.

Useful? React with 👍 / 👎.

Comment thread oseps/0015-declarative-sandbox-features.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cae6b733c3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread oseps/0015-declarative-sandbox-features.md Outdated
Comment on lines +518 to +521
1. Keep the existing `execd-installer` init container.
2. Add one feature init container per requested feature, in request order. Each
uses the registry's digest-pinned OCI image and invokes its self-contained
installer.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Supply pull credentials to feature init containers

When an allowlisted feature image is private and the sandbox ServiceAccount has no preconfigured registry secret, this flow adds only the image reference, so kubelet cannot use the operator credentials with which the server validated the artifact. The existing BatchSandbox path injects imagePullSecrets only from caller image.auth (batchsandbox_provider.py:231-233), while other providers require credentials to already exist on the ServiceAccount or template (kubernetes_service.py:340-357). Specify how operator-controlled feature credentials are propagated to generated Pods for both providers; otherwise supported private feature images fail with ImagePullBackOff.

Useful? React with 👍 / 👎.

@GodBlf
GodBlf requested a review from Copilot July 17, 2026 06:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7748857bc1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +566 to +570
Kubernetes init containers are sequential, so request order is preserved. The
Pod retains `automountServiceAccountToken: false`; feature init containers do
not receive API credentials and do not need network access after kubelet pulls
their OCI image. Implementations SHOULD apply the existing restricted
init-container security defaults and grant no additional Linux capabilities.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce egress policy before feature installers run

For Kubernetes sandboxes with a restrictive networkPolicy, these feature init containers run before the egress sidecar and can therefore make unrestricted outbound connections while executing an explicitly untrusted installer. The current wiring appends egress as a normal container (server/opensandbox_server/services/k8s/egress_helper.py:104-131), and that process installs the network rules only when it starts (components/egress/main.go:111-116), after all init containers have completed. This both bypasses the caller's policy and leaves the stated no-download requirement unenforced; the design needs enforcement active during feature initialization rather than merely noting that installers do not need network access.

Useful? React with 👍 / 👎.

Comment thread oseps/0015-declarative-sandbox-features.md
@Pangjiping

Copy link
Copy Markdown
Collaborator

For stable, large-scale sandbox fleets, I'd argue that pre-baked OCI images and VM templates are still the optimal path — resolving and provisioning features at create time introduces non-trivial overhead on the hot path (image pulls, ordered init containers, activation before execd), which is hard to justify when the toolchain rarely changes.

This design looks great for newcomers and interactive/exploratory use cases where the toolchain is fluid and per-request. But for hyperscale scheduling, where cold-start latency, cache locality, and deterministic startup dominate, I'd expect most operators to still consolidate features into a curated base image rather than composing them dynamically.

Not opposing the proposal — just wondering if it's worth calling out in Non-Goals or Alternatives that declarative features are not intended to replace pre-baked images for high-throughput workloads, and that the two approaches are complementary.

@GodBlf

GodBlf commented Jul 21, 2026

Copy link
Copy Markdown
Author

Thanks @Pangjiping, agreed. The intent is for declarative features to complement, not replace, pre-baked images or VM templates.

I updated the proposal in 395eeb5 to make that boundary explicit:

  • Non-Goals now excludes replacing pre-baked images or VM templates for stable, high-throughput workloads where cold-start latency, cache locality, and deterministic startup are the primary constraints.
  • The Alternatives section now positions pre-baked images as a potentially preferred optimization for stable toolchains and high-throughput fleets, while declarative features target dynamic, per-request toolchains.

Thanks for calling out the large-scale fleet perspective.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 395eeb5b1d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +578 to +581
When `platform` is explicit, all selected features must contain that platform.
When it is omitted, the resolver computes the intersection of platforms across
the selected feature versions and constrains Pod scheduling to that
intersection. The init-container `image` uses the pinned OCI index digest, so

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include sandbox image platforms in Kubernetes resolution

For Kubernetes creates where platform is omitted, this computes scheduling constraints only from the selected feature versions. In a mixed-architecture cluster, a linux/amd64-only sandbox image plus features that also allow arm64 can still be scheduled onto an arm64 node; current provider helpers only add kubernetes.io/os/arch selectors from an explicit PlatformSpec (server/opensandbox_server/services/k8s/workload_provider.py:306-336), so kubelet fails later with ImagePullBackOff/readiness timeout instead of the documented pre-create FEATURE_PLATFORM_UNSUPPORTED. The resolver should intersect the sandbox image's supported platforms, or require an explicit platform, before creating the workload.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation OSEP

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants