Skip to content

feat(runtime): add pluggable OpenShell backend#107

Open
fshehadeh-sfl wants to merge 22 commits into
mainfrom
feat/pluggable-openshell-runtime
Open

feat(runtime): add pluggable OpenShell backend#107
fshehadeh-sfl wants to merge 22 commits into
mainfrom
feat/pluggable-openshell-runtime

Conversation

@fshehadeh-sfl

@fshehadeh-sfl fshehadeh-sfl commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add a runtime registry and per-project/per-agent/global runtime selection
  • retain Docker as a selectable backend and add an experimental OpenShell workspace runner
  • add host-side Git execution so review credentials and push orchestration remain in VE
  • persist runtime policies, dedicated project/agent runtime bindings, and denial audit events
  • keep OpenShell runtime policies isolated from PBAC policies and bindings
  • add runtime, policy, assignment, and denial management to the admin API and dashboard
  • add local OpenShell gateway automation plus Kubernetes deployment manifests
  • document the architecture and rollout decision in ADR 0001

Security

  • sandbox execution does not receive host VCS authentication variables
  • runtime policy storage is separate from PBAC access-control policy storage
  • runtime workspaces stay pinned to their selected backend for their complete lifecycle
  • Docker remains available as a fallback/kill switch
  • runner contract tests cover credential isolation

Validation

  • npm test — 2001 passing
  • npm run typecheck
  • npm run typecheck:ui
  • npm run lint
  • npm run build:ui
  • local OpenShell gateway health verified through ./scripts/start.sh --openshell

Known limitations

  • OpenShell remains experimental while sandbox workspace transfer, agent execution payloads, inference routing, and production Kubernetes behavior are completed and validated
  • Docker stays the seeded default; operators explicitly opt into OpenShell

aberaud
aberaud previously approved these changes Jul 9, 2026
Introduce RuntimeId (docker|openshell), resolveRuntimeId fallback chain (project>agent>default), and RuntimeRegistry that maps ids to WorkspaceRunner instances with safe default fallback. Default stays docker; no behavior change.
Add nullable projects.runtime, agents.runtime, app_settings.default_runtime (NULL=inherit). Add runtime_policies, policy_bindings, policy_denial_events tables mirrored in Drizzle schema. Additive migration only.
Add PolicyStore (runtime policies + project/agent bindings), DenialStore (policy denial audit log), and defaultRuntime to app settings. Compose both into the SqliteStateStore facade.
OpenShellClient wraps the openshell CLI (injectable runner) for sandbox lifecycle and policy set. openShellPolicyBuilder emits deterministic deny-by-default YAML + review/coding/strict templates. denyEventPoller parses and secret-scrubs policy denials.
HostGitExecutor runs native git (clone/checkout/cherry-pick/diff) on the orchestrator so push stays host-side. OpenShellWorkspaceRunner implements WorkspaceRunner: git via HostGitExecutor, agent exec via OpenShellClient with deny-by-default policy applied pre-run.
RuntimeAwareWorkspaceRunner implements WorkspaceRunner and delegates each call to the registry-resolved runner for the task (project>agent>default). Collapses to the default runner when selection is empty, so wiring it in keeps docker behavior identical.
index.ts builds a RuntimeRegistry (docker default + openshell), reads default_runtime from app_settings, and passes a RuntimeAwareWorkspaceRunner to the orchestrator, review trigger, and agent adapter. Add runtime field to Agent/Project records + stores. Default stays docker: behavior unchanged.
New adminRuntimeRoutes (default runtime + gateway health), adminPolicyRoutes (policy CRUD + project/agent bindings), adminDenialRoutes (denial audit log). Add runtime field to project/agent create/update + detail responses. Wire deps in adminServer + index.ts.
New ConfigView sections: Runtime (default backend selector + gateway health), Policies (YAML policy CRUD editor), Policy Denials (audit log table). Add per-project and per-agent runtime override selectors to the project/agent form modals.
Dockerfile.orchestrator gains an opt-in pinned OpenShell CLI install (INSTALL_OPENSHELL/OPENSHELL_VERSION build args; default off). Add deploy/k8s manifests (namespace, configmap, secret example, PVC, orchestrator Deployment/Service) + OpenShell gateway Helm values and a deployment README. Orchestrator runs non-root, read-only rootfs, no docker socket; git+push stay in-pod.
Contract test asserts docker+openshell runners satisfy WorkspaceRunner. Security regression tests assert push/review secrets (agentToken, host authEnv) never reach the OpenShell sandbox. Add scripts/benchmark-runtime.ts for dispatch+policy overhead. OpenShell runAgentInDocker now accepts (and ignores) authEnv per interface.
Implementation is merged and tested; OpenShell is experimental/opt-in per project/agent. Boot default stays docker (app_settings.default_runtime NULL) until acceptance criteria are met against a live gateway — flip is a one-setting change from the admin Runtime tab.
start.sh accepts --openshell (and optional --openshell-version) to build the orchestrator image with the pinned OpenShell CLI and automatically set the default runtime to openshell in the DB after first boot. Default (no flag) is unchanged.
start.sh --openshell now pulls and starts ghcr.io/nvidia/openshell/gateway as a Docker container (ve-openshell-gateway, port 127.0.0.1:8080), waits for health, and passes OPENSHELL_GATEWAY to the orchestrator. src/index.ts reads that env var to wire the gateway address into OpenShellClient. reset-instance.sh also removes ve-openshell-gateway.
GHCR only publishes 'latest' and commit-SHA tags for the gateway image — no semver/vX.Y.Z tags exist. OPENSHELL_VERSION still pins the CLI binary inside the orchestrator image.
Gateway container: mount a writable data dir (uid 1000), pass --db-url, --health-port 8081, --disable-tls explicitly. gatewayHealthy() now probes the HTTP /healthz endpoint directly instead of the non-existent 'openshell gateway status' CLI subcommand.
…iver)

- Add --bind-address 0.0.0.0 (default is 127.0.0.1, unreachable from host via mapped port)

- Mount data volume with :z SELinux relabel

- Add --group-add <docker-gid> + --security-opt label:disable so the gateway can reach the Docker socket

- Set HOME=/data so gateway cache dirs (.local/share) land on the writable volume

- Add --drivers docker flag (required; no auto-detection)
- sandbox rm -> sandbox delete <name> (positional, no --force)

- sandbox exec -> --name <name> -- <cmd> (named flag)

- policy set -> --policy <tmpfile> <name> (file, not stdin)

- Remove unused --gateway flag; CLI reads OPENSHELL_GATEWAY from env
Providers (integrations, oauth), Execution (agents, projects, prompts), Runtime & Security (runtime, policies, denials), System.
Use visible kind-specific icons and compact icon actions for runtime policy assignment, editing, and deletion. Keep each action accessible through labels and hover titles.
Keep sandbox runtime policies and bindings separate from PBAC policies, authorize runtime routes explicitly, and pin each workspace to its selected runtime for its full lifecycle.
@fshehadeh-sfl fshehadeh-sfl force-pushed the feat/pluggable-openshell-runtime branch from 51e240e to 480d031 Compare July 9, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants