Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9791c8a
feat(isolation): split supervisor and sandbox runtimes
drew Sep 8, 2026
99e192a
docs(agents): register supervisor runtime
drew Sep 8, 2026
cb9c0e6
fix(sandbox): harden boundary isolation and lifecycle ownership
drew Sep 8, 2026
e00e263
fix(sandbox): reject private root redirects and adopt typed errors
drew Sep 9, 2026
6d357ae
fix(sandbox): preserve accept thread ownership on musl
drew Sep 9, 2026
de86a4c
test(sandbox): isolate credential probes from filtered threads
drew Sep 9, 2026
1727994
fix(sandbox): return retained exec exit status to independent waiters
drew Sep 9, 2026
07838b3
fix(sandbox): bound network mediation and preserve socket authorization
drew Sep 9, 2026
520aaeb
fix(sandbox): bound control admission and retire stale mediation
drew Sep 9, 2026
a4a6666
ci(e2e): select migrated drivers per stack layer
drew Sep 9, 2026
b555923
refactor(sandbox): implement loopback connector
drew Sep 9, 2026
7cf8f93
feat(isolation): authenticate the Sandbox Protocol
drew Sep 11, 2026
d684ed3
feat(supervisor): rotate launch-scoped authentication
drew Sep 11, 2026
4bdd742
refactor(sandbox): consume dedicated backend crate
drew Sep 11, 2026
737628b
test(sandbox): align topology session fixture
drew Sep 11, 2026
0d749dc
fix(auth): use valid default session token lifetime
drew Sep 11, 2026
c6b64dd
fix(sandbox): align projected bootstrap bundle
drew Sep 11, 2026
f7b4b85
fix(auth): validate refreshed credentials before rotation
drew Sep 11, 2026
57e7b2d
fix(sandbox): fail closed across supervisor disconnects
drew Sep 11, 2026
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
19 changes: 19 additions & 0 deletions .github/actions/build-docker-image/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ inputs:
binary:
description: Binary staged in the Docker build context
required: true
additional-binary:
description: Optional second binary staged in the Docker build context
required: false
default: ""
triple:
description: Binary artifact target triple
required: true
Expand Down Expand Up @@ -53,6 +57,21 @@ runs:
INPUTS_BINARY: ${{ inputs.binary }}
INPUTS_ARCH: ${{ inputs.arch }}

- name: Download ${{ inputs.additional-binary }}
if: inputs.additional-binary != ''
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: ${{ inputs.additional-binary }}-${{ inputs.triple }}
path: additional-artifact

- name: Stage ${{ inputs.additional-binary }}
if: inputs.additional-binary != ''
shell: bash
run: install -Dm0755 additional-artifact/${INPUTS_ADDITIONAL_BINARY} deploy/docker/.build/prebuilt-binaries/${INPUTS_ARCH}/${INPUTS_ADDITIONAL_BINARY}
env:
INPUTS_ADDITIONAL_BINARY: ${{ inputs.additional-binary }}
INPUTS_ARCH: ${{ inputs.arch }}

- name: Build ${{ inputs.component }} image
shell: bash
env:
Expand Down
14 changes: 13 additions & 1 deletion .github/actions/check-job-results/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ inputs:
results:
description: JSON-encoded GitHub Actions needs context
required: true
allowed-skipped-jobs:
description: Comma-separated job IDs that may be skipped but must not fail
required: false
default: ""

runs:
using: composite
Expand All @@ -16,12 +20,20 @@ runs:
shell: bash
env:
JOB_RESULTS: ${{ inputs.results }}
ALLOWED_SKIPPED_JOBS: ${{ inputs.allowed-skipped-jobs }}
run: |
set -euo pipefail
failures="$(
jq -r '
jq -r --arg allowed_skipped "$ALLOWED_SKIPPED_JOBS" '
($allowed_skipped | split(",") | map(select(length > 0))) as $allowed_skipped_jobs
|
to_entries[]
| . as $job
| select(.value.result != "success")
| select(
.value.result != "skipped"
or ($allowed_skipped_jobs | index($job.key)) == null
)
| "\(.key) concluded \(.value.result)"
' <<< "$JOB_RESULTS"
)"
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/branch-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,20 +179,20 @@ jobs:
tasks/scripts/verify-telemetry-compiled-out.sh present target/debug/openshell-gateway
cargo build -p openshell-gateway --bin openshell-gateway --no-default-features --features defaults-without-telemetry
tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-gateway
cargo build -p openshell-sandbox --bin openshell-sandbox --no-default-features --features defaults-without-telemetry
tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-sandbox
cargo build -p openshell-supervisor --bin openshell-supervisor --no-default-features --features defaults-without-telemetry
tasks/scripts/verify-telemetry-compiled-out.sh absent target/debug/openshell-supervisor

- name: Verify the defaults-without-telemetry feature alias tracks the default feature set
run: tasks/scripts/verify-defaults-without-telemetry.sh

- name: Verify system CA roots build mode compiles and excludes bundled Mozilla roots
run: |
cargo check -p openshell-sandbox --all-targets --no-default-features --features system-ca-roots
if cargo tree -p openshell-sandbox -i webpki-roots --no-default-features --features system-ca-roots 2>/dev/null | grep -q webpki-roots; then
cargo check -p openshell-supervisor --all-targets --no-default-features --features system-ca-roots
if cargo tree -p openshell-supervisor -i webpki-roots --no-default-features --features system-ca-roots 2>/dev/null | grep -q webpki-roots; then
echo "ERROR: webpki-roots found in system CA roots build" >&2
exit 1
fi
if cargo tree -p openshell-sandbox -i webpki-root-certs --no-default-features --features system-ca-roots 2>/dev/null | grep -q webpki-root-certs; then
if cargo tree -p openshell-supervisor -i webpki-root-certs --no-default-features --features system-ca-roots 2>/dev/null | grep -q webpki-root-certs; then
echo "ERROR: webpki-root-certs found in system CA roots build" >&2
exit 1
fi
Expand Down
61 changes: 51 additions & 10 deletions .github/workflows/branch-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ jobs:
run_kubernetes_ha_e2e: ${{ steps.labels.outputs.run_kubernetes_ha_e2e }}
run_kubernetes_credential_drivers_e2e: ${{ steps.labels.outputs.run_kubernetes_credential_drivers_e2e }}
run_any_e2e: ${{ steps.labels.outputs.run_any_e2e }}
run_docker_e2e: ${{ steps.labels.outputs.run_docker_e2e }}
run_podman_e2e: ${{ steps.labels.outputs.run_podman_e2e }}
run_vm_e2e: ${{ steps.labels.outputs.run_vm_e2e }}
run_kubernetes_e2e: ${{ steps.labels.outputs.run_kubernetes_e2e }}
allowed_skipped_core_jobs: ${{ steps.labels.outputs.allowed_skipped_core_jobs }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- id: gate
Expand Down Expand Up @@ -68,12 +73,46 @@ jobs:
else
run_any_e2e=false
fi

run_docker_e2e="$run_core_e2e"
run_podman_e2e="$run_core_e2e"
run_vm_e2e="$run_core_e2e"
run_kubernetes_e2e="$run_core_e2e"
allowed_skipped_core_jobs=""

# The RFC 0012 stack deliberately introduces the split runtime before
# migrating each driver. At those intermediate layers, run only the
# drivers whose isolation adapter is present. Before and after the
# stack this resolves to the complete legacy or migrated driver set.
if [ "$run_core_e2e" = "true" ] && [ -f crates/openshell-supervisor/Cargo.toml ]; then
if [ ! -f crates/openshell-driver-docker/src/isolation.rs ]; then
run_docker_e2e=false
allowed_skipped_core_jobs="docker-e2e,docker-external-driver-e2e"
fi
if [ ! -f crates/openshell-driver-podman/src/isolation.rs ]; then
run_podman_e2e=false
allowed_skipped_core_jobs="${allowed_skipped_core_jobs:+$allowed_skipped_core_jobs,}podman-e2e,podman-external-driver-e2e"
fi
if [ ! -f crates/openshell-driver-vm/src/isolation/mod.rs ]; then
run_vm_e2e=false
allowed_skipped_core_jobs="${allowed_skipped_core_jobs:+$allowed_skipped_core_jobs,}vm-e2e,vm-external-driver-e2e"
fi
if [ ! -f crates/openshell-driver-kubernetes/src/isolation.rs ]; then
run_kubernetes_e2e=false
allowed_skipped_core_jobs="${allowed_skipped_core_jobs:+$allowed_skipped_core_jobs,}kubernetes-e2e,kubernetes-external-driver-e2e,kubernetes-workspace-managed-e2e,kubernetes-workspace-operator-e2e"
fi
fi
{
echo "run_core_e2e=$run_core_e2e"
echo "run_gpu_e2e=$run_gpu_e2e"
echo "run_kubernetes_ha_e2e=$run_kubernetes_ha_e2e"
echo "run_kubernetes_credential_drivers_e2e=$run_kubernetes_credential_drivers_e2e"
echo "run_any_e2e=$run_any_e2e"
echo "run_docker_e2e=$run_docker_e2e"
echo "run_podman_e2e=$run_podman_e2e"
echo "run_vm_e2e=$run_vm_e2e"
echo "run_kubernetes_e2e=$run_kubernetes_e2e"
echo "allowed_skipped_core_jobs=$allowed_skipped_core_jobs"
} >> "$GITHUB_OUTPUT"

version:
Expand Down Expand Up @@ -262,12 +301,13 @@ jobs:
with:
component: supervisor
binary: openshell-sandbox
additional-binary: openshell-supervisor
target-suffix: unknown-linux-musl
secrets: inherit

docker-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_docker_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -280,7 +320,7 @@ jobs:

podman-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_podman_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -292,7 +332,7 @@ jobs:

vm-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway, build-vm-driver]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_vm_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -303,7 +343,7 @@ jobs:

docker-external-driver-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-plain, build-driver-docker, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_docker_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -320,7 +360,7 @@ jobs:

podman-external-driver-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-plain, build-driver-podman, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_podman_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -336,7 +376,7 @@ jobs:

vm-external-driver-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-plain, build-vm-driver]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_vm_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -362,7 +402,7 @@ jobs:

kubernetes-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-image, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_e2e == 'true'
strategy:
fail-fast: false
matrix:
Expand Down Expand Up @@ -393,7 +433,7 @@ jobs:

kubernetes-workspace-managed-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-image, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -407,7 +447,7 @@ jobs:

kubernetes-external-driver-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-plain, build-driver-kubernetes, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_e2e == 'true'
permissions:
actions: read
contents: read
Expand All @@ -424,7 +464,7 @@ jobs:

kubernetes-workspace-operator-e2e:
needs: [pr_metadata, build-cli, build-conformance, build-gateway-image, build-supervisor-image]
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_core_e2e == 'true'
if: needs.pr_metadata.outputs.should_run == 'true' && needs.pr_metadata.outputs.run_kubernetes_e2e == 'true'
permissions:
actions: read
contents: read
Expand Down Expand Up @@ -477,6 +517,7 @@ jobs:
- uses: ./.github/actions/check-job-results
with:
results: ${{ toJSON(needs) }}
allowed-skipped-jobs: ${{ needs.pr_metadata.outputs.allowed_skipped_core_jobs }}

gpu-e2e-result:
name: GPU E2E result
Expand Down
18 changes: 16 additions & 2 deletions .github/workflows/build-sandbox-binaries.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,27 @@ jobs:
- triple: x86_64-unknown-linux-musl
runner: linux-amd64-cpu8
dev_shell: .#devShells.x86_64-linux.musl
package: openshell-sandbox
binary: openshell-sandbox
- triple: x86_64-unknown-linux-musl
runner: linux-amd64-cpu8
dev_shell: .#devShells.x86_64-linux.musl
package: openshell-supervisor
binary: openshell-supervisor
- triple: aarch64-unknown-linux-musl
runner: linux-arm64-cpu8
dev_shell: .#devShells.aarch64-linux.musl
package: openshell-sandbox
binary: openshell-sandbox
- triple: aarch64-unknown-linux-musl
runner: linux-arm64-cpu8
dev_shell: .#devShells.aarch64-linux.musl
package: openshell-supervisor
binary: openshell-supervisor
uses: ./.github/workflows/build-binaries.yml
with:
package: openshell-sandbox
binary: openshell-sandbox
package: ${{ matrix.package }}
binary: ${{ matrix.binary }}
triple: ${{ matrix.triple }}
runner: ${{ matrix.runner }}
dev-shell: ${{ matrix.dev_shell }}
Expand Down
5 changes: 5 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ on:
binary:
required: true
type: string
additional-binary:
required: false
type: string
default: ""
target-suffix:
required: true
type: string
Expand Down Expand Up @@ -54,6 +58,7 @@ jobs:
with:
component: ${{ inputs.component }}
binary: ${{ inputs.binary }}
additional-binary: ${{ inputs['additional-binary'] }}
triple: ${{ matrix.rust_arch }}-${{ inputs['target-suffix'] }}
arch: ${{ matrix.arch }}
platform: ${{ matrix.platform }}
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ jobs:
with:
component: supervisor
binary: openshell-sandbox
additional-binary: openshell-supervisor
target-suffix: unknown-linux-musl
secrets: inherit

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/release-tag.yml
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ jobs:
with:
component: supervisor
binary: openshell-sandbox
additional-binary: openshell-supervisor
target-suffix: unknown-linux-musl
image-tag: ${{ needs.compute-versions.outputs.source_sha }}
checkout-ref: ${{ inputs.tag || github.ref }}
Expand Down
3 changes: 2 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ These pipelines connect skills into end-to-end workflows. Individual skill files
| `crates/openshell-conformance/` | CLI conformance library | Reusable driver-agnostic scenarios and command runner |
| `crates/openshell-conformance-cli/` | Conformance CLI | Distributable `list` and `run` entrypoint for gateway conformance |
| `crates/openshell-server/` | Gateway server | Control-plane API, sandbox lifecycle, auth boundary |
| `crates/openshell-sandbox/` | Sandbox runtime | Container supervision, policy-enforced egress routing |
| `crates/openshell-sandbox/` | Sandbox runtime | Capability-free workload launcher, process identity, and seccomp-mediated I/O |
| `crates/openshell-supervisor/` | Supervisor runtime | Gateway session, policy evaluation, credentials, and upstream networking |
| `crates/openshell-binary-identity/` | Binary identity | Shared trusted procfs executable identity resolution for isolation backends |
| `crates/openshell-isolation-interface/` | Isolation backend interface | RFC 0012 `IsolationBackend` trait + types; the supervisor-facing runtime contract for the boundary |
| `crates/openshell-sandbox-backend/` | OpenShell sandbox backend | `OpenShellRuntimeBackend` plus the authenticated OpenShell Sandbox Protocol shared with `openshell-sandbox` |
Expand Down
Loading
Loading