Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
42f443f
initial kubernetes isolation provider with kata, standard k8s, and lo…
dustin-sale Aug 25, 2026
f0210f3
fix: bound sandbox cleanup and disable OCI retries
dustin-sale Aug 26, 2026
42da490
adding openspec artifacts, will integrate it into full repo at a late…
dustin-sale Aug 26, 2026
fe07508
harden kubernetes and rpc channel, update kubernetes examples
dustin-sale Sep 1, 2026
c14853e
sync and archive harden-kubernetes-and-rpc-channel openspec change
dustin-sale Sep 1, 2026
a652aab
unit test fixes and expanded coverage
dustin-sale Sep 3, 2026
e576b6d
updated continerfiles to use ol9 base images
dustin-sale Sep 4, 2026
055ac40
Merge origin/main into dustin-sale/oci-javascript-k8s-isolation-provider
dustin-sale Sep 30, 2026
da8eb7b
initial updates for k8s isolation provider and gRPC handling
dustin-sale Oct 1, 2026
c5811db
resolves a handful of findings from a local review
dustin-sale Oct 1, 2026
f225817
updates to containerfiles for smoother builds
dustin-sale Oct 1, 2026
7abd65f
Merge origin/main into dustin-sale/oci-javascript-k8s-isolation-provider
dustin-sale Oct 1, 2026
48281cc
Merge branch 'main' into dustin-sale/oci-javascript-k8s-isolation-pro…
dustin-sale Oct 2, 2026
75c1718
fix(oci-javascript): close unit test gaps and correct runtime edge cases
dustin-sale Oct 2, 2026
a6e07b5
addressing PR comments
dustin-sale Oct 8, 2026
b0ad446
Merge remote-tracking branch 'origin/main' into dustin-sale/oci-javas…
dustin-sale Oct 9, 2026
fba4dca
updated agent context
dustin-sale Oct 9, 2026
8771845
lazy load isolation provider adapters
dustin-sale Oct 9, 2026
968ee18
creates deployment validation script
dustin-sale Oct 12, 2026
f68536f
moves k8s policy validation out of server startup
dustin-sale Oct 12, 2026
57b730b
feat: support fixed TLS file bootstrap for runners
dustin-sale Oct 12, 2026
2164bef
feat: model execution TLS Secrets and direct pod endpoints
dustin-sale Oct 12, 2026
116e008
feat: use direct execution-scoped mTLS for in-cluster runners
dustin-sale Oct 12, 2026
4f9f0db
feat: reconcile execution Secrets and preflight direct transport perm…
dustin-sale Oct 12, 2026
b1ef50f
feat: constrain direct runner networking and TLS mounts
dustin-sale Oct 12, 2026
e786d99
docs: document direct Kubernetes gRPC deployment and validation
dustin-sale Oct 12, 2026
ae850f6
fix: support IPv6 runners and validate running cancellation
dustin-sale Oct 12, 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
25 changes: 18 additions & 7 deletions src/oci-javascript-mcp-server/.dockerignore
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
*

# Container builds require the manifests, install policy/setup, and TS sources.
# This excludes local dependencies, tests, coverage, documentation, and VCS files.
!package.json
!package-lock.json
!.npmrc
!scripts/
scripts/*
!scripts/setup-native.mjs
!buf.gen.yaml
!proto/
proto/*
!proto/runner.proto
!src/
!src/grpc.ts
!src/protocol.ts
!src/sandbox-common.ts
!src/sandbox-isolate.ts
!src/sandbox-prelude.ts
!src/sandbox-worker.ts
!src/types.ts
# Re-including directories admits descendants, so filter their contents before
# including host sources. The context regression checks the complete source
# tree; add new source directories here when introducing them.
src/*
!src/*.ts
!src/isolation/
src/isolation/*
!src/isolation/*.ts
# Bindings are freshly generated in each image's dependency stage. The runner
# still copies only its explicit eight source files in Containerfile.
1 change: 1 addition & 0 deletions src/oci-javascript-mcp-server/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ignore-scripts=true
20 changes: 15 additions & 5 deletions src/oci-javascript-mcp-server/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ This TypeScript server runs JavaScript in an isolated runner and mediates OCI ca

- [server.ts](src/server.ts): MCP tool handling and entry point; [oci-host.ts](src/oci-host.ts): host-side OCI calls, credentials and exposed SDK behavior.
- [Protocol](src/protocol.ts), [gRPC boundary](src/grpc.ts) and [protobuf contract](proto/runner.proto): typed host/runner messages, bounded encoding and session contract; [sandbox.ts](src/sandbox.ts), [worker](src/sandbox-worker.ts) and [isolate](src/sandbox-isolate.ts): execution orchestration.
- [Podman provider](src/isolation/podman.ts) and [gRPC lifecycle](src/isolation/grpc-execution.ts): process/network arguments, fresh mTLS identities, execution limits and cleanup.
- [Provider factory](src/isolation/provider-factory.ts), [Podman](src/isolation/podman.ts), [Kubernetes](src/isolation/kubernetes.ts) and [gRPC lifecycle](src/isolation/grpc-execution.ts): explicit provider/profile selection, startup preflight, fresh execution boundaries and cleanup.
- [Documentation baseline](docs/README.md): current public behavior, architecture, provider/deployment procedures, implementation evidence and known differences.
- [Test directory](test), [Moon tasks](moon.yml), [package.json](package.json) and [README](README.md): behavior definitions, native commands and runtime setup.

## Setup / build / run
Expand All @@ -19,15 +20,15 @@ From the repository root, run `proto install`, then `moon run oci-javascript-mcp

From the repository root, use `moon run oci-javascript-mcp-server:test` for tests with coverage, `moon run oci-javascript-mcp-server:check` for TypeScript checks and `moon run oci-javascript-mcp-server:build` for the npm tarball. All three depend on compile. The package exposes only the `start` npm script; former npm test/coverage/check/CI scripts are unavailable. Use the [shared validation map](../../docs/agent-development.md#validation-map) for sources and cross-runtime limits.

Protocol work starts with [protocol tests](test/protocol.test.ts), [gRPC tests](test/grpc.test.ts) and [sandbox tests](test/sandbox.test.ts); host changes with [OCI host tests](test/oci-host.test.ts); MCP changes with [server tests](test/server.test.ts); packaging changes with [packaging tests](test/packaging.test.ts). Tests use [fake Podman](test/fake-podman.ts) for command construction and the mTLS gRPC session. c8 config enforces 90% **line** coverage with explicit exclusions; neither those definitions nor this unexecuted check list prove deployment isolation.
Protocol work starts with [protocol tests](test/protocol.test.ts), [gRPC tests](test/grpc.test.ts) and [sandbox tests](test/sandbox.test.ts); host changes with [OCI host tests](test/oci-host.test.ts); MCP changes with [server tests](test/server.test.ts); packaging changes with [packaging tests](test/packaging.test.ts). Tests use [fake Podman](test/fake-podman.ts) for command construction and the mTLS gRPC session. c8 config enforces 90% **statements, branches, functions and lines** coverage with explicit exclusions; neither those definitions nor this unexecuted check list prove deployment isolation.

## Architecture and dependencies

Preserve the host/runner split described in [README architecture](README.md#architecture): credentials, SDK clients and HTTPS calls remain on the host; runner communication uses the bounded mTLS gRPC session defined by `proto/runner.proto`. Trace message validation, size/time/call limits, cancellation and teardown together. The v4 endpoint requires matching host/runner versions; rebuild the runner image after a host update, with no fallback or execution replay. Moon compile generates codecs/bindings from the schema; generated `src/generated/` and `dist/` are not committed. Python/Common credential implementations are not the authentication interface of this Node SDK path.

## Security and secrets handling

The [provider](src/isolation/podman.ts) defines a fresh internal network with no external route, a gRPC port published to host loopback, a read-only root, dropped capabilities, non-root execution and bounded resources. Each execution receives fresh mTLS identities; the runner receives its server key and the host's public certificate, never the host's private key. Preserve those constraints and cleanup; keep OCI credentials and raw SDK/process errors out of runner-visible responses. The [README security model](README.md#security-model) distinguishes nested isolate/container controls from a VM security boundary. Mocked command/protocol checks do not certify real Podman isolation.
The [provider](src/isolation/podman.ts) defines a fresh internal network with no external route, a gRPC port published to host loopback, a read-only root, dropped capabilities, non-root execution and bounded resources. Each execution receives fresh mTLS identities; the runner receives its server key and the host's public certificate, never the host's private key. Preserve those constraints and cleanup; keep OCI credentials and raw SDK/process errors out of runner-visible responses. The [README security model](README.md#security-model) distinguishes nested isolate/container controls from a VM security boundary. Kubernetes uses a host-constructed credential-free pod under exactly one local, in-cluster or Kata profile; credentials stay on the trusted host. Use the [profile guide](docs/kubernetes-isolation-profiles.md) for strict settings, preflight, namespace/image policy and reconciliation, and the [Kata guide](docs/kata-kubernetes-poc.md) for unverified external controls. Mocked command/protocol checks do not certify effective Podman, CNI or Kata isolation.

## Change impact

Expand All @@ -36,8 +37,9 @@ Protocol, host OCI, sandbox, provider or task/schema changes affect runtime exec
## Known gaps

- Root's subprocess rule names API alone as the exception, while this package already launches Podman. Record the conflict and resolve policy through the owning project; this guide grants no exception or new backend authority.
- Native dependency/toolchain setup can block checks. A setup failure is separate from a test result; c8 coverage is line coverage with exclusions.
- Fake-control-plane test definitions cover command construction and gRPC behavior, not Podman itself. No real runtime, OCI service or isolation checks ran in this adoption.
- Native dependency/toolchain setup can block checks. A setup failure is separate from a test result; c8 enforces all four metrics at 90%, with explicit exclusions.
- Fake-control-plane tests cover host command/protocol and provider lifecycle behavior, not effective runtime isolation. No runtime, OCI, container or cluster checks ran in this baseline pass.
- [Baseline differences](docs/README.md#known-differences-and-evidence-limits) include RPC ID uniqueness, cumulative traffic/combined-result budgets, permissive wire tags, request-control filtering, caller authorization and the dependency-range/native-setup mismatch.
- Explicit [Moon tasks](moon.yml) own compilation, tests, type checking and packaging; inspecting those definitions is not evidence that they passed.

## Workflow and context routing
Expand All @@ -46,6 +48,14 @@ Protocol, host OCI, sandbox, provider or task/schema changes affect runtime exec
| --- | --- | --- | --- |
| **Know:** Changing exposed OCI calls or credentials | [Host implementation](src/oci-host.ts), [README](README.md) | Root quality/security guidance and host/runner boundary | [Host tests](test/oci-host.test.ts); no Python/Common-auth assumption |
| **Know:** Changing execution/protocol/isolation | [Protocol](src/protocol.ts), [schema](proto/runner.proto), [provider](src/isolation/podman.ts), [gRPC lifecycle](src/isolation/grpc-execution.ts) | [Security model](README.md#security-model), matching host/runner contract, recorded root-policy conflict | [Protocol](test/protocol.test.ts), [gRPC](test/grpc.test.ts), [sandbox](test/sandbox.test.ts) and [server tests](test/server.test.ts); fake provider limits explicit |
| **Know:** Understanding public behavior, auth or execution limits | [Architecture baseline](docs/architecture-and-isolation-design.md#72-public-mcp-behavior), [source/evidence index](docs/README.md) | Root requirements, this guide and native interfaces | [Server](test/server.test.ts), [host](test/oci-host.test.ts), [sandbox](test/sandbox.test.ts) tests; baseline review did not execute them |
| **Know / Do:** Selecting a Kubernetes profile or assessing Kata deployment | [Profile guide](docs/kubernetes-isolation-profiles.md), [Kata POC](docs/kata-kubernetes-poc.md), [local setup](docs/kubernetes-local-in-cluster-setup.md) | Host/runner boundary, strict [config](src/isolation/kubernetes-config.ts), target cluster/image prerequisites | [Profile](test/kubernetes-profiles.test.ts), [provider](test/kata-provider.test.ts), [transport](test/kubernetes-grpc.test.ts), [manifest](test/kata-manifests.test.ts) checks; real-environment limits explicit |
| **Do:** Preparing or validating this runtime | [Moon tasks](moon.yml), [manifest](package.json), [validation map](../../docs/agent-development.md#validation-map) | Node/native dependencies, repository task directory, generated compile prerequisites | Actual test/coverage/type/package reports; [evidence routes](../../docs/agent-development.md#evidence-and-context-routes) |

Use native sources for local details and inherited shared guidance for repository requirements. This adoption's Now/Proof record is the [summary](../../docs/plans/adopt-monorepo-agent-context/adoption-summary.md); startup/deployment checks remain separate from documentation review.

## Documentation maintenance

This component keeps maintained explanations in README and the architecture/provider guides. Preserve this broad guide and update its relevant routes when sources move.

When tool schemas/results, OCI identity or exposure, protocol fields/limits, cleanup precedence, provider/profile configuration, installation policy or Moon tasks change, review the corresponding baseline route and owning docs against the changed source/tests. Record source identity and actual check scope; source review does not establish current runtime validation or production admission.
80 changes: 80 additions & 0 deletions src/oci-javascript-mcp-server/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,44 @@

## Unreleased

### Added

- Add a standalone Kubernetes deployment validator with explicit
kubeconfig/context and verified host identity, optional service-account
impersonation, bounded permission/RuntimeClass/admission checks, JSON reporting
and an opt-in `validate-deployment` Moon task.

### Changed

- Start in-cluster and Kata runners normally from an execution-scoped read-only
TLS Secret and connect directly over pod-network mTLS gRPC. Replace exec and
port-forward permissions with Secret lifecycle permissions; require narrow
host-to-runner ingress. Workstation local-development retains its tunnel path.
- Delete and reconcile execution TLS Secrets alongside pods, including orphans
and uncertain or late creation, under the existing bounded cleanup contract.

- Restrict Kubernetes startup preflight to namespace access, execution permissions
and expiry reconciliation. Admission probes and live RuntimeClass/handler
checks belong to deployment validation; remove server assurance descriptors
and gate execution on operational readiness.

### Fixed

- Bound Kubernetes reconciliation listing and propagate standalone reconciler
shutdown cancellation into list and deletion requests.
- Resume Kubernetes deletion watches from the observed resource version and
recover expired versions within the original confirmation deadline.
- Require port-forward WebSocket closure before tunnel cleanup succeeds,
including forwarding handles acquired after shutdown begins.

- Require an observed Running Kubernetes pod before runner startup; respect
cancellation and execution deadlines during the initial readiness request.
- Select OCI session authentication for named profiles that inherit token
configuration from DEFAULT, while respecting explicit profile overrides.
- Preserve the final JavaScript expression result when trailing comments are
present, including expressions containing strings or regular expressions.
- Generate arrays for required array fields in `discover_oci` request examples,
including arrays of models, while retaining bounded model expansion.
- Preserve OCI status codes, service codes, operation details, and request IDs in
uncaught `run_javascript` errors so callers can assess failures and retry decisions.

Expand All @@ -21,13 +57,37 @@

### Added

- Add an opt-in Kubernetes isolation provider with `local-development`,
`in-cluster`, and `kata-in-cluster` profiles. Podman remains the default;
provider and profile selection is explicit and fails closed at startup.
- Run each Kubernetes execution in a fresh, credential-free pod with bounded
deletion and expiry reconciliation. Add versioned standard and Kata deployment
examples, including separate host, runner, and cleanup identities.
- Add a Kata proof-of-concept profile with an exact RuntimeClass and handler
check, digest-pinned runner image, admission checks, and a deployment guide.
- Add a Moon `k8s-build` task to build the Kubernetes runner and host Docker images.
- Build-generated TypeScript codecs and gRPC bindings, tested before release and
included in the npm package and runner image rather than source control. No
runtime schema loading or generation is required. Wire-format compatibility
tests preserve the contract; OCI data retains bounded JSON validation.

### Changed

- Update architecture and operator guides for protobuf gRPC v4, current Moon
commands, installation policy, and cleanup outcomes; ship the README-linked
architecture document and label historical security-review evidence.
- Make container source filtering explicit and exclude stale generated/local
artifacts; add opt-in builder-context and host/reconciler/runner smoke checks.
- Harden the in-cluster and Kata profiles with scoped RBAC, fail-closed pod
admission checks, reviewed resource ranges, and a cleanup-only reconciler.
Add a helper to sync host OCI credentials into a host-only Kubernetes Secret.
- Clarify local in-cluster image digest lookup, all four manifest replacements,
and rollout verification, and update setup commands to use the existing tools.
- Migrate the Kubernetes isolation provider from the removed framed pipe to the
shared protobuf gRPC v4 transport, bootstrapped over `pods/exec` and carried
through one execution-scoped loopback `pods/portforward` connection with mTLS.
Trusted host roles now require `create` and `get` on `pods/portforward`;
runner and cleanup identities receive no added authority.
- Return stdout/stderr with the final result and use native gRPC readiness,
deadlines, cancellation, and failure status; remove the obsolete custom framing
layer and duplicate transport timer/timeout field. The overall execution
Expand All @@ -37,6 +97,17 @@

### Fixed

- Build container native dependencies with the bundled Node headers offline,
avoiding header-download timeouts; cache npm installation separately from native setup.
- Find the local `ts-proto` plugin when generating bindings in the runner and host image builds.
- Delete Kubernetes execution pods alongside transport teardown under one
cleanup deadline, so stalled startup or channel closure cannot skip deletion;
unconfirmed cleanup still fails the execution.
- Observe Kubernetes runner failures throughout startup so readiness and tunnel
faults return sanitized execution failures without terminating the MCP host;
stop runner and tunnel handles delivered after cancellation.
- Keep host-only certificate generation out of the runner image so Podman and Kubernetes executions can start.
- Generate protobuf bindings when building the host image so fresh checkouts do not need a prior compile.
- Disable SDK circuit breakers and retries on per-call OCI clients while retaining
cancellation, so successful responses and service errors are returned promptly
instead of failing with an OCI cleanup timeout.
Expand All @@ -62,5 +133,14 @@

### Security

- Disable automatic dependency lifecycle scripts in controlled repository and
container installs; validate the pinned `isolated-vm` version and install
command before explicitly building its native addon. Document manual setup
for npm package consumers.
- Reject guest request-level `retryConfiguration` so OCI SDK calls retain the
host-controlled single-attempt policy.
- Suppress OCI session-refresh and Kubernetes Secret/restart subprocess output
so failed credential synchronization cannot expose private keys or tokens;
report fixed stage summaries, including restart failures after a Secret update.
- Bound all runner RPC frames, including rejected requests, and attempt Podman
resource removal even if its run command does not close.
Loading
Loading