Skip to content

Chore/resync 20260820 - #4

Merged
rodbutters merged 461 commits into
aiblefrom
chore/resync-20260820
Aug 24, 2026
Merged

Chore/resync 20260820#4
rodbutters merged 461 commits into
aiblefrom
chore/resync-20260820

Conversation

@rodbutters

Copy link
Copy Markdown

Summary

updates aible branch to v0.0.110 and updates the SDK to match.

Related Issue

Changes

SDK updates are backwards compatible with v0.0.92

Testing

rebuilt and validated with sandbox launch, egress rules, availability of start/stop

Checklist

elezarand others added 30 commits June 29, 2026 18:59
…#1974)
* refactor(server): remove unused compute runtime constructor parameter
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* refactor(server): normalize compute driver type imports
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* refactor(server): key driver config tables by name
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* refactor(server): normalize compute driver config acquisition
Signed-off-by: Evan Lezar <elezar@nvidia.com>
---------
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* test(e2e): add workload manifest build flow
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* test(e2e): add gpu workload validation tests
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* ci(e2e): build gpu workloads before gpu e2e
Signed-off-by: Evan Lezar <elezar@nvidia.com>
---------
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* fix(providers): reserve credential placeholder revisions
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* fix(providers): share placeholder namespace parser
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* test(providers): cover non-revision env key
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
---------
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
…templates (NVIDIA#2062)
The certgen hook and cert-manager Certificate template hardcoded
openshell.openshell.svc.cluster.local in server certificate SANs,
breaking deployments in any namespace other than openshell. Use
.Release.Namespace in the templates so the SANs match the actual
service FQDN regardless of the target namespace.
ClosesNVIDIA#2060
Signed-off-by: Akram <akram.benaissi@gmail.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* feat(kubernetes): add combined topology config surface
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
* docs(kubernetes): clarify topology defaults
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
---------
Signed-off-by: Taylor Mutch <taylormutch@gmail.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
…2088)
The field was added during the Kubernetes driver extraction refactor
(NVIDIA#817) as a pass-through mechanism, but was never wired up to a CLI
flag, Python SDK helper, or any documentation. The only reachable
user path was raw gRPC construction.
The Kubernetes driver now always injects the default workspace PVC,
removing the branching logic that checked for a user-supplied VCT.
Field number 9 is reserved in the proto to prevent reuse.
Signed-off-by: Evan Lezar <elezar@nvidia.com>
The chart's optional Gateway API ingress only rendered a plaintext HTTP
listener, so the gateway could not be exposed over TLS. Add an HTTPS
listener option that terminates TLS at the Envoy Gateway and forwards
plaintext gRPC to the gateway pod.
- gateway.yaml renders an HTTPS listener with `tls.mode: Terminate` and
`certificateRefs` when `grpcRoute.gateway.listener.protocol=HTTPS`,
keeping the default HTTP listener unchanged. Guards fail the render when
`certificateRefs` is empty or `server.disableTls` is not true (the chart
does not render a BackendTLSPolicy for re-encryption).
- values.yaml adds `grpcRoute.gateway.listener.tls.certificateRefs`.
- ci/values-gateway-tls.yaml exercises the HTTPS branch in lint/render.
- docs/kubernetes/ingress.mdx documents HTTPS setup and clarifies that
Envoy Gateway only terminates TLS (no OIDC SecurityPolicy); client
identity uses OIDC bearer tokens, with the client-credentials grant for
headless agents.
- debug-openshell-cluster skill gains HTTPS-ingress troubleshooting rows.
- Regenerated the chart README values table.
Signed-off-by: Huabing (Robin) Zhao <zhaohuabing@gmail.com>
* chore(gator): add gator gate skill
* chore(gator): add sandbox launcher scaffold
* chore(gator): add codex image and docs checks
* chore(gator): fold approved provider policy rules
* chore(gator): add deterministic reviewer runner
* chore(gator): clarify ok-to-test comments
* chore(gator): structure launcher harnesses
* chore(gator): require e2e for dependabot
* chore(gator): add codex refresh profile
* chore(gator): wip manifest agent launcher
* feat(agents): supervise watch cycles in sandbox
* fix(agents): preserve gateway refresh state
* fix(gator): continue human response threads
* fix(agents): keep watch supervisor retrying
* fix(agents): use refreshed Codex credential aliases
* fix(gator): avoid misleading gh auth checks
* docs(agents): remove architecture build update
* fix(gator): use REST-backed GitHub writes
* fix(agents): bake immutable agent payloads
* fix(agents): upload writable agent workspace
* fix(agents): surface gator watch progress
* fix(agents): prevent codex stdin hang
* fix(agents): align codex subagent input
* fix(agents): heartbeat during active cycles
* fix(agents): clean up heartbeat sleep
* fix(agents): disable gh telemetry in codex harness
* fix(agents): reconcile closed gator PRs
* fix(agents): query closed gator PR labels separately
* fix(agents): tolerate rotated credential placeholders
* fix(agents): enforce gator same-sha comment guard
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* docs(agents): scope gator trusted commentary
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* fix(gator): treat reviewer failures as transient
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* feat(agents): refine gator supervised workflow
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* fix(agents): stream codex prompts via stdin
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* docs(agents): clarify trusted gator responses
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
* refactor(agents): scope gator PR to scripts
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
---------
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Signed-off-by: Evan Lezar <elezar@nvidia.com>
Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
Co-authored-by: Evan Lezar <elezar@nvidia.com>
…A#2092)
* feat(docker,podman): add SELinux label support for bind mounts
The Docker Engine structured Mount API does not support SELinux
relabelling (:z / :Z). Move user-supplied bind mounts from the
structured `mounts` field to the legacy string-format `binds` field,
which does support these options.
Add a shared `SelinuxLabel` enum (shared/private) to openshell-core so
both Docker and Podman drivers accept an optional `selinux_label` field
on bind mount configs. For Docker, labels are appended to the bind
string; for Podman, they are pushed to the mount options vec.
Signed-off-by: Florian Bergmann <fbergman@redhat.com>
* fix(docker): reject missing bind source paths on legacy binds
Moving user bind mounts from the structured Mount API to the legacy
Binds field changed Docker's behavior for missing source directories:
the legacy path silently creates them as empty root-owned dirs instead
of erroring. Add an explicit Path::exists() check to preserve the
fail-fast behavior operators expect.
Signed-off-by: Florian Bergmann <fbergman@redhat.com>
---------
Signed-off-by: Florian Bergmann <fbergman@redhat.com>
* test(e2e): run rootless podman on ubuntu host
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* test(e2e): probe rootless capability behavior
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* test(e2e): make capability probe observational
Signed-off-by: Evan Lezar <elezar@nvidia.com>
---------
Signed-off-by: Evan Lezar <elezar@nvidia.com>
…A#1973)
* feat(policy): accept numeric UIDs in sandbox process identity validation
Allow run_as_user and run_as_group to be either the literal 'sandbox'
or a numeric UID/GID within [1000, 2_000_000_000]. This removes the
hard dependency on a baked-in 'sandbox' user in container images,
enabling compute drivers to inject resolved UIDs at sandbox creation.
Phase 1 of NVIDIA#1959.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
* feat(supervisor): accept numeric UIDs for process identity dropping
Allow run_as_user and run_as_group to be numeric UIDs/GIDs, removing
the hard dependency on a baked-in 'sandbox' user in container images.
Changes:
- validate_sandbox_user(): accepts numeric UIDs without passwd lookup
(logs OCSF event); keeps passwd check for "sandbox" name; rejects
non-numeric non-sandbox strings that fail passwd lookup
- prepare_filesystem(): passes numeric UIDs/GIDs directly to chown()
instead of requiring a passwd entry
- drop_privileges(): resolves numeric UIDs/GIDs directly via UID::from_raw
/ Gid::from_raw; skips initgroups when target uid matches current euid;
uses guard conditions before setgid/setuid calls
- session_user_and_home(): falls back to ("{uid}", "/sandbox") for
numeric UIDs, avoiding a passwd lookup that will fail
Re-exports MIN_SANDBOX_UID and MAX_SANDBOX_UID from openshell-policy
so callers have consistent range constants.
Phase 2 of NVIDIA#1959.
Signed-off-by: Seth Jennings <sjenning@redhat.com>
* feat(driver-kubernetes): resolve sandbox UID/GID from config or OpenShift SCC annotations
Phase 3 of the numeric-UID plan: allow operators to specify explicit
sandbox_uid/sandbox_gid in Kubernetes driver config, auto-detect from
OpenShift SCC namespace annotations, and propagate resolved values to
supervisor container env vars and PVC init container securityContext.
Changes:
- Add sandbox_uid/sandbox_gid fields to KubernetesComputeConfig
- Add SANDBOX_UID/SANDBOX_GID env var constants to openshell-core
- Implement resolve_sandbox_identity() to fetch namespace annotations
and auto-detect OpenShift SCC UID ranges (sa.scc.uid-range)
- Pass resolved UID/GID through SandboxPodParams to pod spec builder
- Inject SANDBOX_UID/SANDBOX_GID env vars into supervisor container
- Update PVC init container securityContext with resolved UID/GID
instead of hard-coded root
- Add comprehensive unit tests for resolution logic and annotation
parsing (resolve_sandbox_uid, resolve_sandbox_gid, OpenShift SCC
annotation parsing)
Signed-off-by: Seth Jennings <sjenning@redhat.com>
* feat(driver-vm): add configurable sandbox UID/GID and update docs/examples
Phase 4 of the numeric-UID plan: replace hardcoded SANDBOX_UID (10001)
in VM rootfs preparation with configurable sandbox_uid/sandbox_gid fields.
Changes:
- Add sandbox_uid/sandbox_gid to VmDriverConfig with serde derives
- Pass resolved UID/GID through prepare_sandbox_rootfs_from_image_root
to ensure_sandbox_guest_user which writes /etc/passwd/group/gshadow
- Update BYOC Dockerfile: remove groupadd/useradd, document runtime UID
injection and the ability to skip baked-in sandbox user
- Update gateway-config.mdx: document sandbox_uid/sandbox_gid for both
Kubernetes (with OpenShift SCC autodetection) and VM drivers
- Update sandbox-compute-drivers.mdx: add Sandbox User Identity section
explaining numeric UID support across all compute drivers
- Update rootfs tests to use non-default UIDs, verify config passthrough
Signed-off-by: Seth Jennings <sjenning@redhat.com>
* code review changes
* fix(supervisor): harden tests for restricted CI container environments
Guard tests against CI-specific constraints: root without CAP_SETPCAP,
UIDs with no /etc/passwd entry, and restricted /proc access.
Signed-off-by: Seth Jennings <sjennings@nvidia.com>
Signed-off-by: Seth Jennings <sjenning@redhat.com>
---------
Signed-off-by: Seth Jennings <sjenning@redhat.com>
Signed-off-by: Seth Jennings <sjennings@nvidia.com>
* docs(rfc): add driver config passthrough proposal
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* docs(rfc): link driver config proposal PR
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* docs(rfc): clarify driver config scope
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* docs(rfc): clarify driver-local config schemas
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* docs(rfc): clarify driver config extension path
* docs(rfc): update driver config baseline
* docs(drivers): document bind-mount selinux_label and whitespace rules
---------
Signed-off-by: Evan Lezar <elezar@nvidia.com>
…IA#2124)
Add a reminder to the bug report template's Logs field and a new row in
the security best-practices Common Mistakes table advising reporters to
redact credentials, API keys, and tokens from stack traces before pasting.
Signed-off-by: Evan Lezar <elezar@nvidia.com>
Signed-off-by: Adam Miller <admiller@redhat.com>
NVIDIA#2126)
* docs: remove deprecated --keep flag from tutorials and examples
The --keep flag is deprecated, hidden, and a no-op since sandboxes
are kept by default. Remove references from tutorial docs and example
READMEs that explain it as a real feature.
- Remove --keep from sandbox create commands
- Remove --keep explanation text
- Clarify that sandboxes are kept by default
Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>
* chore: remove deprecated --keep usage from scripts and e2e tests
The --keep flag is a deprecated no-op since sandboxes are kept by
default. Stop passing it in internal scripts, e2e test scripts,
and example demo scripts.
Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>
---------
Signed-off-by: Ignas Baranauskas <ibaranau@redhat.com>
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.2.0 to 8.3.0.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](astral-sh/setup-uv@fac544c...d31148d)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-version: 8.3.0
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Apply the Linux cfg to the Path import so native macOS lint runs do not report
it as unused when the only call site is compiled out.
This fixes `mise run rust:lint` on macOS.
Signed-off-by: Kris Hicks <khicks@nvidia.com>
…selectors (NVIDIA#2170)
* fix(sandbox): acknowledge initial policy revision
The supervisor loaded and enforced a sandbox-scoped policy but never told
the gateway which revision it loaded. The policy poll loop seeded itself
with the initial revision's hash on its first poll, so `policy_changed`
was never true for that revision and `ReportPolicyStatus(LOADED)` — which
only ran in the hot-reload branch — was never called. The revision stayed
`Pending` and `current_policy_version` stayed 0 even though the sandbox was
`Ready` and the policy was effective. This was most visible with sparse
policies that get baseline-enriched into a new revision during startup.
After the OPA engine is constructed, report the exact sandbox revision the
supervisor loaded as LOADED, and seed the poll loop from that revision so
it is not re-reported. Report FAILED with the original construction error
if engine construction or conversion fails. Only sandbox-sourced revisions
(version > 0) whose canonical content matches the loaded policy are
acknowledged; global and local-file policies are untouched. Delivery uses
the shared bounded retry, is non-fatal on transient failure, and a pending
initial acknowledgement is delivered before any newer revision so policy
history is never reordered.
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* feat(python): expose sandbox labels and selectors
The gateway protobuf and CLI already support request-level sandbox labels
(`CreateSandboxRequest.name`/`labels`) and selector-based listing
(`ListSandboxesRequest.label_selector`), but the public Python SDK dropped
them, so Python-created sandboxes could not be found via
`openshell sandbox list --selector ...`.
Add optional, source-compatible `name`/`labels` to `SandboxClient.create`,
`create_session`, and the high-level `Sandbox`, and `label_selector` to
`list`/`list_ids`. `SandboxRef` now carries the gateway labels as an
immutable mapping (default empty, so `SandboxRef(id, name, status)` still
works). Caller-provided label mappings are copied. Attaching the high-level
`Sandbox` to an existing sandbox rejects `name`/`labels` since creation
metadata cannot change on attach. Template labels remain a separate concept.
No protobuf changes are required.
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(python): keep SandboxRef hashable and copy high-level labels
Excluding the new immutable `labels` field from SandboxRef equality/hash
(`compare=False`) preserves the original (id, name, status) identity and keeps
the frozen dataclass hashable — a MappingProxyType field would otherwise make
`hash(SandboxRef(...))` raise. Also defensively copy caller-provided labels in
the high-level `Sandbox` so later caller mutation cannot change what is sent.
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(sandbox): bound initial-policy-ack retries
The poll loop retried a pending initial acknowledgement before processing any
newer revision, but retried unconditionally forever. A permanently
undeliverable ack (e.g. the revision was superseded before it could be
reported) would then stall all later policy hot-reloads and provider-env
refreshes. Cap the retries; after the bound, give up and resume normal polling
so the loop cannot livelock on a stuck acknowledgement.
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* test(sandbox): add sparse-policy revision-2 acknowledgement e2e
Regression for NVIDIA#2159: create a sandbox with the network-only policy-advisor
fixture, which the supervisor enriches with baseline filesystem paths during
startup (creating revision 2, superseding revision 1). Assert the effective
policy reaches revision 2 and no revision remains Pending once the supervisor
acknowledges the load. Adds SandboxGuard::create_keep_with_args to create a
kept sandbox with an initial --policy.
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(ci): correct sandbox checks
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* test(cli): serialize mTLS environment access
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(sandbox): address policy review feedback
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(sandbox): preserve exact policy acknowledgements
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
* fix(sandbox): preserve local policy overrides
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
---------
Signed-off-by: Kyle Zheng <kyzheng@nvidia.com>
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Co-authored-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Bumps [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) from 8.3.0 to 8.3.1.
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](astral-sh/setup-uv@d31148d...f98e069)
---
updated-dependencies:
- dependency-name: astral-sh/setup-uv
dependency-version: 8.3.1
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
derekwaynecarrand others added 26 commits August 14, 2026 21:22
…IDIA#2656)
* feat(k8s): add namespace-per-workspace support (RFC 0011 Phase 3)
Implement three workspace namespace modes for the Kubernetes compute
driver: shared (default, preserves current single-namespace behavior),
managed (auto-creates/deletes namespaces per workspace), and operator
(pre-provisioned namespaces with dynamic discovery via label selector
or drop-in allowlist file).
Key changes:
- WorkspaceMode enum and namespace resolution in driver config
- Managed namespace lifecycle with ServiceAccount and OpenShift SCC
annotation propagation
- Cluster-wide sandbox CR watchers for managed/operator modes
- NamespaceValidator (Exact/Prefix/Allowlist) for SA token auth
- Workspace-aware credential secret storage
- Helm ClusterRole for multi-namespace RBAC
- Gateway config, architecture, and reference docs
Signed-off-by: Derek Carr <decarr@redhat.com>
* test(k8s): add e2e tests for workspace namespace modes
Add end-to-end tests for managed and operator workspace modes
introduced in RFC 0011 Phase 3. The managed mode tests verify
namespace creation with correct labels, ServiceAccount provisioning,
sandbox CR placement, and namespace survival with remaining sandboxes.
The operator mode tests verify rejection of unlabeled and nonexistent
namespaces. The positive operator path (sandbox in labeled namespace)
is known to fail due to an RBAC gap and will be addressed separately.
Also fixes Helm 4 compatibility: move SPDX license headers inside
conditional guards in 8 chart templates to prevent empty comment-only
documents, and fix a trailing whitespace trimmer in clusterrole.yaml
that concatenated the license header with apiVersion.
Adds cleanup sweep in with-kube-gateway.sh to remove managed and
operator namespaces before Helm uninstall, and mise tasks for running
each mode independently.
Signed-off-by: Derek Carr <decarr@redhat.com>
* feat(k8s): add operator namespace label watcher
Spawn a background kube::runtime::watcher in the K8s driver that
watches namespaces matching the configured label selector and populates
the OperatorNamespaceAllowlist at runtime. The driver owns the
allowlist and exposes its Arc so the server can share the same set with
the SA token authenticator.
create_sandbox now gates pod creation on the allowlist in operator
mode — workspaces whose namespace is not yet labeled are rejected at
resource render time rather than silently proceeding. Workspace
lifecycle itself is unaffected; only sandbox (resource) creation is
gated.
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): harden operator mode and address review findings
Close the fail-open gap in operator mode when only
operator_namespace_file is configured: the allowlist is now created
unconditionally in operator mode (fail-closed from startup).
Implement the namespace file watcher using the notify crate, following
the TLS hot-reload pattern (parent-directory watch, 1s debounce,
ConfigMap symlink-swap safe). The file format is a JSON array of
namespace name strings.
Additional fixes from the 10-reviewer audit:
- Change allowlist rejection from InvalidArgument to FailedPrecondition
so callers know the request may succeed later once the namespace is
provisioned.
- NamespaceValidator::Allowlist now holds the OperatorNamespaceAllowlist
newtype instead of a raw Arc<RwLock<BTreeSet>>, eliminating silent
denial on RwLock poison.
- Verify LABEL_MANAGED_BY and LABEL_GATEWAY_ID ownership before
deleting a managed namespace.
- Replace fixed 5s sleep in operator e2e test with a 30s poll loop.
- Add Helm validation for workspaceMode values.
- Fix Helm README type column and description for operator fields.
- Add insert/remove methods to OperatorNamespaceAllowlist; label
watcher now uses them instead of reaching through shared().
- Reject configs with both operator_namespace_label and
operator_namespace_file set.
Signed-off-by: Derek Carr <decarr@redhat.com>
* feat(k8s): add workspace-level compute driver RPCs and harden RBAC
Decouple namespace lifecycle from sandbox lifecycle by adding
EnsureWorkspace/DeleteWorkspace RPCs to the ComputeDriver service.
Namespace creation now happens before credential storage and namespace
deletion happens on workspace delete, fixing credential storage in
managed workspace mode.
- Add EnsureWorkspace and DeleteWorkspace proto RPCs with
implementations across all compute drivers (K8s managed delegates to
ensure_namespace/delete_namespace_if_empty; others no-op)
- Wire ensure_workspace into provider create/update/refresh paths so
the namespace exists before the credential driver writes secrets
- Wire delete_workspace into workspace deletion for cleanup
- Remove delete_namespace_if_empty from sandbox deletion path
- Scope ClusterRole secrets access to non-shared workspace modes
- Add TODO for TLS cert hot-reload in sandbox gRPC client
- Harden e2e tests with control-plane sandbox resolution assertions
- Fix docker image save --platform flag for OCI index manifests
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): address re-review findings and add test coverage
- Use server-side apply for TLS secret sync (fixes second sandbox
creation failure when TLS is enabled)
- Scope gateway-ID label selector unconditionally across all workspace
modes (fixes operator reads/watches/deletes seeing foreign sandboxes)
- Validate operator allowlist in EnsureWorkspace and DeleteWorkspace
RPCs (prevents credential writes to namespaces outside the allowlist)
- Extend ClusterRole secrets patch+delete to all non-shared modes with
credential driver enabled (fixes operator credential storage RBAC)
- Validate namespace ownership on 409 conflict in ensure_namespace
(prevents adopting unowned namespaces in managed mode)
- Replace delete_namespace_if_empty with unconditional delete_namespace
letting Kubernetes cascade cleanup (fixes stuck terminating CRs)
- Strengthen NetworkPolicy TODO to cover both managed and operator modes
- Extract selector and ownership logic into testable free functions
- Add unit tests for gateway-ID selectors and namespace ownership
- Add Helm ClusterRole RBAC tests for operator credential driver
Signed-off-by: Derek Carr <decarr@redhat.com>
* ci(k8s): add workspace managed and operator mode e2e to CI
Wire the existing e2e:kubernetes:workspace-managed and
e2e:kubernetes:workspace-operator mise tasks into the branch-e2e
workflow so they run alongside the other core Kubernetes e2e suites.
Both are gated by run_core_e2e and included in the Core E2E result
gate.
Signed-off-by: Derek Carr <decarr@redhat.com>
* test(k8s): add e2e tests for workspace namespace modes
Add 7 new e2e tests covering workspace namespace lifecycle, TLS secret
copying, ownership conflict detection, DNS-1123 validation, operator
namespace preservation, and dynamic label watcher behavior. Fix async
sandbox deletion race condition in existing tests by polling sandbox
list instead of asserting immediately after delete.
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): grant secrets/patch unconditionally and backfill gateway-id labels
Address two review findings:
1. RBAC: server-side apply (PATCH) is used for TLS secret sync in
multi-namespace modes, but the ClusterRole only granted patch when
the kubernetes-secrets credential driver was enabled. Grant patch
unconditionally for non-shared modes since TLS sync always needs it;
keep delete gated on the credential driver.
2. Upgrade safety: the new gateway-id label selector would orphan
legacy Sandbox CRs that predate its introduction. Add a startup
backfill in shared mode that patches any managed Sandbox CR missing
the gateway-id label before the driver begins serving requests.
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): address workspace namespace review findings
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): address follow-up review findings
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): preserve workspace lookup after rebase
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(helm): allow managed secret creation
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): stop pods in workspace namespace
Signed-off-by: Derek Carr <decarr@redhat.com>
* test(k8s): scope pod deletion check to v1alpha1
Signed-off-by: Derek Carr <decarr@redhat.com>
* fix(k8s): address workspace namespace review findings
Signed-off-by: Derek Carr <decarr@redhat.com>
---------
Signed-off-by: Derek Carr <decarr@redhat.com>
* feat(middleware): inspect websocket text messages
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): address websocket review feedback
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): bound websocket message assembly
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): harden websocket upgrade lifecycle
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): unify in-process and remote transports
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(middleware): support regex websocket redaction
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): bound persistent streaming sessions
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): accept websocket sequence gaps
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): refine websocket introspection contract
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): clarify websocket preflight lifecycle
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): clarify websocket coverage semantics
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): type websocket frame failures
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): return 503 when middleware admission is exhausted
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): align streaming API contract
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): clarify WebSocket event result scope
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(rfc): simplify middleware revision history
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* feat(examples): add WebSocket content guard support
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): unify binding payload limits
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(middleware): align payload limit terminology
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): address websocket review feedback
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): address websocket review findings
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* test(network): allow Linux handler setup in preflight regression
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): harden websocket relay finalization
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(network): inspect compressed websocket messages
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* test(network): stabilize compressed websocket regressions
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(go-sdk): regenerate middleware protobuf binding
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): clarify websocket skip lifecycle
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* fix(middleware): address WebSocket review feedback
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
---------
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(driver): extract shared supervisor binary helpers
Move supervisor binary extraction, caching, and validation helpers from
the Docker driver into openshell-core::driver_utils so both Docker and
Podman drivers can reuse them.
Moved helpers: extract_first_tar_entry, write_cache_binary_atomic,
supervisor_cache_path, temp_extract_container_name, and
validate_linux_elf_binary.
The shared extract_first_tar_entry gains entry-type and empty-payload
checks that the Docker-local version lacked. supervisor_cache_path
takes a driver_subdir parameter so each driver caches under its own
namespace (docker-supervisor vs podman-supervisor).
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
* feat(driver-podman): add userns config
Add a `userns` option to the Podman compute driver that maps to
Podman's user namespace modes. The mode string is split on the first
colon into the API's `nsmode` and `value` fields so parameterized
values like `auto:size=65536` and `keep-id:uid=1000,gid=1000` are
forwarded correctly. When the mode is `auto`, the container spec
also sets `idmappings.AutoUserNs = true` as required by the API.
An allowlist validates the mode at startup: `auto` and `keep-id`
accept optional parameters; `host`, `private`, and `nomap` reject
them; everything else is an error.
Podman image volumes use overlay mounts internally and the kernel
does not support idmapped mounts on overlay (`mount_setattr` returns
EINVAL). When userns is configured (any mode except `host`), the
driver extracts the supervisor binary from the image to a host-side
cache and bind-mounts it instead of using an image volume.
Configurable via TOML `userns = "auto"`, CLI `--userns`, or
environment variable `OPENSHELL_PODMAN_USERNS`.
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
---------
Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
Signed-off-by: Simon Scatton <sscatton@nvidia.com>
Signed-off-by: Adrien Langou <alangou@nvidia.com>
…els (NVIDIA#2735)
* fix(inference): prepend publisher prefix for Vertex non-Anthropic models
Vertex AI's OpenAI-compatible endpoint requires the request body's model
field to carry a publisher prefix (e.g. google/gemini-2.5-flash), but
validate_vertex_model_id rejects slash as a path-traversal guard. This
created a deadlock: bare model IDs pass validation but are rejected by
Vertex with HTTP 400 "Malformed publisher model"; prefixed IDs are
rejected at configuration time.
Fix: in resolve_vertex_ai_route, compute body_model_id for non-Anthropic
routes by prepending the publisher from infer_vertex_publisher() or the
explicit VERTEX_AI_PUBLISHER config value. The bare model_id still goes
through the path-traversal validator unchanged. Anthropic rawPredict routes
encode the model in the URL path, not the body, and are unaffected. Both
the project/region path and the base-URL-override path apply the prefix.
For unrecognised models with no explicit publisher the bare ID is forwarded
unchanged; Vertex's 400 is the correct observable signal in that case.
Add an integration test in openshell-router that spins up a mock Vertex
endpoint accepting only the publisher-prefixed form and rejecting the bare
model name, verifying the body rewrite produces the required format.
ClosesNVIDIA#2351
Signed-off-by: politerealism <burdcat17@gmail.com>
* fix(inference): propagate publisher-prefixed model_id through inference bundle
resolve_route_by_name_with_credentials built the ResolvedRoute with
config.model_id (the bare stored value) rather than resolved.route.model
(the publisher-prefixed value computed by resolve_vertex_ai_route). As a
result, the bundle delivered to sandboxes carried e.g. "gemini-2.5-flash"
instead of "google/gemini-2.5-flash", so live sandbox requests still hit
Vertex AI with the bare model name and received HTTP 400 "Malformed
publisher model".
Fix: use resolved.route.model in the bundle construction so the
publisher prefix survives the bundle boundary and the router sends the
correct body to Vertex AI.
Update the existing gemini bundle test to assert the prefixed model_id
and add a dedicated regression test that verifies the bundle carries the
publisher prefix for non-Anthropic Vertex routes.
Signed-off-by: politerealism <burdcat17@gmail.com>
* style(inference): apply rustfmt to new regression test
Signed-off-by: politerealism <burdcat17@gmail.com>
* fix(inference): address clippy lints in build_vertex_route
- Invert if !is_anthropic to satisfy clippy::if_not_else
- Replace match on Option with map_or_else to satisfy clippy::option_if_let_else
Signed-off-by: politerealism <burdcat17@gmail.com>
---------
Signed-off-by: politerealism <burdcat17@gmail.com>
* docs(rfc): add RFC 0013 native Windows support via MXC
Propose native Windows 11 support through a build-only MSVC lane and a new
in-process, supervisor-free MXC compute driver, with host-side governed egress
and an OpenShell to MXC policy-translation seam.
Refs: NVIDIA#2050
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
* docs(rfc): address native Windows MXC review feedback
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
* docs(rfc): update governed egress proxy topology
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
* docs(rfc): clarify Windows proxy and gateway topology
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
---------
Signed-off-by: Shailendra Singh <shailendras@nvidia.com>
* Update docs.yml
Remove warning banner from docs page.
* Update README.md
…uation (NVIDIA#2699)
* fix(supervisor-network): strip path parameters before dot-segment resolution
Signed-off-by: Adrien Langou <alangou@nvidia.com>
* fix(supervisor-network): scope allow_encoded_slash to the matched L7 endpoint
Signed-off-by: Adrien Langou <alangou@nvidia.com>
* fix(supervisor-network): check the canonical target for encoded slashes
Signed-off-by: Adrien Langou <alangou@nvidia.com>
---------
Signed-off-by: Adrien Langou <alangou@nvidia.com>
* ci(drivers): lint portable drivers on macOS
Signed-off-by: Evan Lezar <elezar@nvidia.com>
* fix(driver-podman): compile container spec on macOS
Signed-off-by: Evan Lezar <elezar@nvidia.com>
---------
Signed-off-by: Evan Lezar <elezar@nvidia.com>
Test coverage artifact was accidentally committed. Already in .gitignore.
Signed-off-by: Roland Huß <rhuss@redhat.com>
…ctivity (NVIDIA#2664)
Apply the official OCSF ai_operation profile (introduced in v1.8.0) to
ApiActivity [6003] events when the inference proxy routes a model call
through inference.local. Attaches an ai_model object (name, ai_provider)
and puts token counts and latency in unmapped fields.
ApiActivity [6003] is the schema-correct class for the ai_operation
profile in v1.8.0 (HttpActivity only gets it in v1.9.0). In Splunk CIM,
ApiActivity maps to the "Change" data model, naturally separating
inference events from regular HTTP proxy traffic.
Changes:
- Add AiModel object and ai_model field on BaseEventData
- Add ApiActivityEvent struct and ApiActivityBuilder
- Add emit_ai_inference in proxy.rs using ApiActivity with ai_operation
- Vendor OCSF v1.8.0 schemas including api_activity class, ai_model
object, and ai_operation profile definitions
- Bump OCSF_VERSION to 1.8.0
- Update schema validation to skip profile-gated required fields
Shorthand: API:INFERENCE [INFO] claude-3-haiku via anthropic 701ms [POST /v1/messages]
Splunk/SIEM backward compatibility (v1.1/v1.3 CIM mapping) is tracked
separately in NVIDIA#2662 as a configurable serialization concern.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix(providers): keep refresh credential handles stable
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* fix(providers): protect refresh-owned credentials
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
---------
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* fix(policy): gate uninspected credentialed endpoints
Signed-off-by: Adrien Langou <alangou@nvidia.com>
* refactor(cli): extract allowed-ip option parsing
Signed-off-by: Adrien Langou <alangou@nvidia.com>
* fix(policy): gate endpointless credential bindings
Signed-off-by: Adrien Langou <alangou@nvidia.com>
---------
Signed-off-by: Adrien Langou <alangou@nvidia.com>
Signed-off-by: Gordon Sim <gsim@redhat.com>
…NVIDIA#2795)
* feat(cli): support OIDC device authorization grant for headless login
ClosesNVIDIA#2793
Add OAuth 2.0 Device Authorization Grant (RFC 8628) support to the OpenShell CLI's OIDC login flow. When running in a headless environment (OPENSHELL_NO_BROWSER=1) without a client secret configured, the CLI now uses the device code flow instead of the browser-based PKCE flow.
The device code flow:
- Requests a device code and user code from the IdP's device authorization endpoint
- Displays a verification URL and user code to the user
- Polls the token endpoint until the user completes authorization or the code expires
- Supports slow_down responses per RFC 8628 by increasing the polling interval
This implementation:
- Extends OidcDiscovery to optionally capture device_authorization_endpoint
- Adds oidc_device_code_flow function with proper error handling for all RFC 8628 error codes
- Updates gateway add and gateway login to dispatch to device flow when browser is suppressed
- Adds comprehensive unit tests for device flow structs and response parsing
- Updates gateway authentication documentation to describe the device code fallback
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
* fix(cli): validate OIDC device token responses
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
* fix(cli): add PKCE to OIDC device flow
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
* docs(cli): document PKCE device flow
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
---------
Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
…DIA#2801)
* feat(providers): store refresh credentials in credential drivers
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* fix(providers): harden refresh credential lifecycle
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* fix(providers): migrate legacy refresh secrets before skip
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* refactor(providers): defer credential migration
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
* fix(providers): make refresh configuration atomic
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
---------
Signed-off-by: Mrunal Patel <mrunalp@gmail.com>
And collect the other agent-related entries together.
Signed-off-by: Kris Hicks <khicks@nvidia.com>
Signed-off-by: Seth Jennings <sjenning@redhat.com>
* fix(podman): wait for container stop completion
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* docs(podman): clarify stop restart race
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
---------
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
* refactor(compute): unify gateway restart reconciliation
Remove the Docker-specific gateway shutdown cleanup and reconcile persisted running intent through ComputeDriver::StartSandbox for Docker, Podman, and VM drivers. Explicitly stopped sandboxes remain stopped.
Refs NVIDIA#2417
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* refactor(compute): stop local sandboxes on shutdown
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* test(e2e): match managed Podman containers
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* fix(compute): synchronize lifecycle sweeps
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
---------
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Signed-off-by: Simon Scatton <sscatton@nvidia.com>
* refactor(compute): negotiate external driver behavior
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* docs(compute): revert external driver documentation
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* refactor(compute): negotiate gateway-managed lifecycle
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* refactor(compute): remove driver feature negotiation
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* feat(compute): let drivers declare gateway lifecycle
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
* refactor(compute): clarify lifecycle ownership
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
---------
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
@rodbutters
rodbutters merged commit dab1dee into aibleAug 24, 2026
7 of 9 checks passed
@rodbutters
rodbutters deleted the chore/resync-20260820 branch August 24, 2026 20:08
@rodbutters

Copy link
Copy Markdown
Author

aible branch is up to date with v0.0.110 and SDK updated in fork. SDK backward compatible back to v0.0.92

@rodbutters

Copy link
Copy Markdown
Author

chore/resync-v0.0.92 branch is available for building OpenShell container to aible/openshell:v0.0.92

Sign up for freeto 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.

20 participants

@rodbutters@elezar@johntmyers@jgarciao@akram@shiju-nv@TaylorMutch@zhaohuabing@bergmannf@sjenning@mesutoezdil@maxamillion@Ygnas@krishicks@KyleZheng1284@hunglp6d@kirit93@shaneutt@r3v5@ChristianZaccaria