Commit Graph
68 Commits
Author SHA1 Message Date
Alexander Watson e98ea3ee93 feat(policy): add agentic approval loop (#1528) 2026-05-29 21:11:31 -07:00
mjamivandJohn Myers f1fc87e1ad fix(sandbox): trust exact declared private endpoints (#1560)
* fix(sandbox): trust exact declared private endpoints

* fix(sandbox): preserve advisor endpoint provenance

* fix(sandbox): repair advisor provenance lint failures

---------

Co-authored-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-29 16:18:42 -07:00
Mesut Oezdil f6d0fd175b docs(providers): note that ANTHROPIC_API_KEY requires an API account, not a subscription (#1542)
* docs(providers): note that ANTHROPIC_API_KEY requires an API account, not a subscription

Anthropic subscription users authenticate via OAuth, not an API key,
causing a silent failure when creating the provider. Adds a Note callout
in the provider type table and quickstart guide directing subscription
users to generate an API key from console.anthropic.com.

Closes #620

* docs(providers): fix Note placement and remove subscription brand names

Move the Note callout in manage-providers.mdx to after the complete
provider type table so it does not break table rendering. Remove
subscription brand names from both Note callouts.
2026-05-29 13:15:43 -07:00
John T. Myers b6d58251f6 fix(cli): preserve symlinks during sandbox upload (#1595)
* fix(cli): preserve symlinks during sandbox upload

* docs(sandboxes): document upload symlink behavior
2026-05-27 11:46:17 -07:00
Drew Newberry 603b3e27fa docs: update NemoClaw/OpenClaw references (#1529) 2026-05-22 10:31:59 -07:00
John T. Myers 0cef26521a feat(providers): derive discovery from profiles (#1503)
* feat(providers): derive discovery from profiles

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* fix(providers): keep v2 discovery profile-only

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): update providers v2 behavior

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* fix(providers): make github profile read-only

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-22 08:54:15 -07:00
John T. Myers c5c3f03ce7 docs(sandboxes): add policy advisor guide (#1480)
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-21 18:06:42 -07:00
John T. Myers 14c5329f91 docs(providers): add Providers v2 guide (#1442)
* docs(providers): add Providers v2 guide

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): clarify built-in profile location

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): remove refresh-backed profile bullet

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): clarify persisted query registry key

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): simplify binary schema example

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): add Microsoft Graph refresh tutorial

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): link Microsoft Graph refresh tutorial

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(providers): announce providers v2

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-20 08:57:24 -07:00
John T. Myers d255cdd9c9 feat(providers): add credential refresh foundation (#1349)
* feat(providers): add credential refresh foundation

* feat(providers): mint oauth refresh token credentials

* fix(providers): allow delegated refresh bootstrap

* fix(providers): guard refresh credential modes

* fix(providers): refine refresh lifecycle UX

* fix(cli): restore provider test gateway response import

* fix(server): clean auth endpoint test qualifications

* fix(providers): tighten refresh authorization and collisions

* chore(providers): trim bundled v2 profiles

* fix(providers): resolve refresh rebase fallout

* fix(cli): accept rfc3339 credential expiry

* test(providers): update inferred claude provider type

* test(providers): avoid removed outlook default profile

* test(providers): isolate attach limit fixtures
2026-05-19 07:42:10 -07:00
Florent BENOIT 0cbd2d6c96 feat(cli): add -o json/yaml output format to sandbox list (#1422)
Support machine-readable output for `openshell sandbox list` via
`-o json` and `-o yaml` flags, matching the pattern established for
provider profile commands. Rename ProviderProfileOutput to shared
OutputFormat enum.

Signed-off-by: Florent Benoit <fbenoit@redhat.com>
2026-05-18 09:06:48 -07:00
Drew Newberry f855c3d8bb feat(cli): add sandbox resource flags (#1376)
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
2026-05-13 22:37:47 -07:00
Tinson Lai c99849bcb7 fix(cli): cp-style sandbox download and workspace-boundary check (#1353)
* fix(cli): cp-style sandbox download and workspace-boundary check

`openshell sandbox download` produced a directory at the host destination
instead of writing the source bytes as a regular file, and did not refuse
sandbox-side paths that resolved outside `/sandbox` (only `creds.json` was
rejected, by filesystem policy rather than by an explicit check).

Mirrors the cp-style design from the upload-side fixes (#667 / #694 and
#885 / #952): destination resolution now respects trailing slashes and
existing-directory destinations, single-file sources land as regular files
via a staged extraction and atomic rename, and the function delegates the
SSH tar stream to a shared helper. Adds an explicit lexical
workspace-boundary check on the sandbox-side source — required on the
download side because filesystem policy alone is not a substitute for an
explicit check when crossing the trust boundary in the leak direction.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

* fix(cli): canonicalise sandbox download path remotely and quote tar member

The lexical check in `validate_sandbox_source_path` clears any path whose
components stay under `/sandbox` after `.` and `..` are folded out, but it
cannot see symlinks. A workspace-relative symlink such as
`/sandbox/etc-link -> /etc` lets `openshell sandbox download <name>
/sandbox/etc-link/passwd /tmp/passwd` slip through, then `tar -C
/sandbox/etc-link passwd` follows the link on the sandbox side and
streams `/etc/passwd` back to the host.

Add `canonicalize_sandbox_source_path` which runs `realpath -e --` over
SSH and rejects the result unless it still equals `/sandbox` or starts
with `/sandbox/`. The lexical guard stays as a cheap fail-fast for
obviously-bad inputs, and the rest of the download flow now uses the
canonical path everywhere a tar invocation or probe might dereference a
symlink.

While editing the single-file branch, also add the `--` separator before
the basename in `tar cf - -C <parent> -- <name>`. Without it, a sandbox
file whose basename starts with `-` (e.g. `--checkpoint-action=...`) is
parsed by GNU tar as an option rather than a member, which at best
fails the wrap and at worst triggers tar option behaviour. The directory
branch passes literal `.` and is unaffected.

Cover both fixes with pure-function tests: `is_under_sandbox_workspace`
gets accept/reject pairs (the same predicate the post-realpath
validator uses) and the new `build_single_file_tar_cmd` helper asserts
the `--` separator and shell escaping survive any future refactor.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

* chore(cli): drop redundant tempfile dev-dependency entry

`tempfile` was promoted from `[dev-dependencies]` to `[dependencies]`
once the cp-style single-file download path started using
`TempDir::new_in` from production code. The original `[dev-dependencies]`
line stayed behind by accident — entries under `[dependencies]` are
already available to test compilation, so the second declaration is
dead weight.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

* test(cli): add E2E coverage for sandbox download paths

Adds four end-to-end tests for `openshell sandbox download` so the
happy path and both Codex regressions have explicit coverage:

* `sandbox_download_file_only` — seeds a single file via the new
  `SandboxGuard::exec` harness helper and pulls it back, exercising
  `sandbox_sync_down_file` without an upload phase.
* `sandbox_download_directory_only` — seeds a small directory tree and
  pulls it recursively, exercising `sandbox_sync_down_directory`.
* `sandbox_download_rejects_symlinks_pointing_outside_workspace` —
  regression for the high-severity finding. Plants three escape shapes
  (`/sandbox/etc-link -> /etc`, `/sandbox/passwd-link -> /etc/passwd`,
  and a path with a symlinked component `/sandbox/etc-link/passwd`) and
  asserts all three are refused with a workspace-boundary error before
  any tar streams. Also checks the host destination stays empty so a
  silent leak would surface.
* `sandbox_download_handles_dash_leading_basename` — regression for the
  medium-severity finding. Seeds a file named `--checkpoint-action=evil`
  and verifies it downloads with byte-for-byte contents, proving the
  `--` separator stops tar parsing the basename as an option.

The harness gains a single new method, `SandboxGuard::exec`, that wraps
`openshell sandbox exec --name <name> --no-tty -- <argv>`. Existing
tests preferred the upload path to populate sandbox state, but the
regression cases need to plant filesystem state the upload flow cannot
produce (symlinks, files whose basenames clap would otherwise reject).

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

* docs(cli): note cp-style destination and workspace boundary on download

`openshell sandbox download` now refuses any source path that resolves
outside `/sandbox` (lexically or through a symlink), and the
single-file branch follows `cp`-style placement rules. Document both
so users hitting the workspace-boundary error or the
"land at exact path vs land inside dir" decision can self-serve.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

* test(cli): tolerate miette line-wrapping in symlink-rejection assertions

`sandbox_download_rejects_symlinks_pointing_outside_workspace` matched
the substring `"outside the sandbox workspace"` against the CLI's error
output. The check is correct in spirit but fragile in practice: miette
wraps long single-line errors across multiple lines at terminal width
and inserts a `│ ` continuation marker, so the substring breaks across
the wrap and the test fails even though the canonicalisation step
correctly refused the source.

Split the match into three short markers — `resolves to`, `outside the`,
`sandbox workspace` — each guaranteed to fit on one wrapped line. The
combined check is stricter than the original (it now requires evidence
that the remote `realpath -e` step actually ran, not just the boundary
refusal) without inheriting the wrap fragility.

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>

---------

Signed-off-by: Tinson Lai <tinsonl@nvidia.com>
2026-05-13 17:17:06 -07:00
Piotr Mlocek 0797fefa44 feat(gateway): add local-domain service routing (#1101) 2026-05-12 17:44:55 -07:00
Miyoung Choi 8322e4fd00 docs: style fixes (#1341)
* docs: style fixes

* docs: drop observability section overview page and rename a section title

* docs: title updates
2026-05-12 16:36:15 -07:00
Aaron Erickson 🦞andJohn Myers 9ea94b645d fix(sandbox): rewrite messaging credential placeholders (#1286)
* fix(sandbox): rewrite credential placeholders in websocket text frames

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(sandbox): harden websocket credential rewrite

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* feat(sandbox): add websocket l7 inspection and compression

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(sandbox): harden websocket upgrade validation

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* test(sandbox): cover route-selected websocket upgrades

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(sandbox): harden websocket negotiation parsing

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* test(sandbox): add websocket conformance relay matrix

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* test(e2e): add websocket conformance lane

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(policy): support websocket incremental rules

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* feat(policy): enable websocket credential rewrite updates

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(cli): make websocket rewrite endpoint-local

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* feat(sandbox): support graphql websocket policy

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(policy): allow private IPs for websocket endpoints

* feat(sandbox): rewrite REST credential placeholders

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* refactor(sandbox): generalize credential aliases

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(sandbox): rewrite encoded form credentials

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(sandbox): close websocket policy and provider alias gaps

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>

* fix(e2e): route websocket probe through host gateway

* fix(e2e): stabilize websocket probe handshake

* fix(e2e): exercise websocket probe through proxy

* ci: remove websocket conformance workflow

---------

Signed-off-by: Aaron Erickson <aerickson@nvidia.com>
Co-authored-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-11 22:40:44 -07:00
Mesut Oezdil d2321a2c00 docs: fix broken policy-engine anchor in policies page (#1246) 2026-05-07 13:19:42 -07:00
Drew Newberry 70a0f6c547 refactor(cli): remove gateway lifecycle management (#1221) 2026-05-07 09:54:13 -07:00
Drew Newberry 728165a12c docs: consolidate documentation structure (#1231) 2026-05-07 09:14:08 -07:00
John T. Myers fb472f5d61 fix(cli): warn when env gateway overrides selection (#1219)
Closes #1206

Warn when gateway select saves a new active gateway while OPENSHELL_GATEWAY is set to a different value, and document the override precedence.

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-06 16:58:27 -07:00
Mesut Oezdil cdfd548af8 docs: replace generic Index link text with actual page titles (#1216)
Four cross-reference links used the label "Index" instead of the
destination page's title, making them ambiguous for readers. Replaced
with the correct titles: "About Gateways and Sandboxes" and "About
Inference Routing".
2026-05-06 15:06:11 -07:00
Mesut Oezdil a1a5a015ae docs: fix OpenCode capitalization in provider types table (#1205) 2026-05-06 13:03:27 -07:00
Mesut Oezdil 56ba935e3f docs: add missing provider types to supported providers table (#1180)
* docs: add missing provider types to supported providers table
2026-05-06 09:09:18 -07:00
Max Dubrinsky c0cc196a08 feat(cli): add openshell gateway list subcommand (#1179)
Wires up a first-class `gateway list` command that calls the existing
`run::gateway_list()` helper. Resolves the dead reference in
`crates/openshell-bootstrap/src/errors.rs:248`, where the port-conflict
recovery hint already pointed users at this command.

Updates the manage-gateways doc to teach the new verb instead of the
`gateway select`-with-no-arg fallback.

Closes #1173

Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com>
2026-05-05 17:28:34 -04:00
Drew Newberry f56c09c7df docs: update gateway deployment architecture (#1108) 2026-05-04 22:52:29 -07:00
John T. Myers 043bde279a feat(providers): add profile-backed policy composition (#1037)
Foundation for providers v2. Add provider profiles and provider profile composition with user policies.
2026-05-04 18:34:33 -07:00
John T. Myers 6b21804258 feat(policy): add GraphQL L7 inspection (#1083)
Support GraphQL L7 policies
2026-05-04 11:50:09 -07:00
Drew Newberry 2e0afeabe1 feat(vm): derive guest rootfs from sandbox images (#957) 2026-05-03 23:23:30 -07:00
Drew Newberry 08001ca616 fix(docker): harden supervisor startup and gateway routing (#1128) 2026-05-03 21:38:20 -07:00
Mesut Oezdil 721c39f1f3 docs: fix tutorial links pointing to /tutorials instead of /get-started/tutorials (#1137) 2026-05-02 13:35:31 -07:00
Mesut Oezdil c0352272e5 docs: fix broken link and capitalise GitHub correctly (#1135)
Close the missing closing parenthesis on the Manage Providers link in
github-sandbox.mdx and correct four instances of "Github" to "GitHub"
across the docs.

Signed-off-by: mesutoezdil <mesudozdil@gmail.com>
2026-05-02 08:06:34 -07:00
John T. Myers 5d0a44cbac fix(sandbox): invalidate stale l7 tunnels after reload (#1118)
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-05-01 13:01:30 -07:00
Evan Lezar 0c0f3e32e1 feat(docker): enable CDI GPU sandboxes (#1036) 2026-04-30 13:23:57 -07:00
Miyoung Choi cde20dc312 docs: weekly documentation refresh (#993)
* docs(release-notes): refresh weekly documentation

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

* docs(release-notes): remove weekly refresh entry

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

---------

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
2026-04-27 12:57:05 -07:00
Piotr Mlocek df38d1f66f feat(ci): add Markdown and Mermaid linting (#933) 2026-04-24 11:27:02 -07:00
Taylor Mutch 9ac725f00d fix(cli): sandbox get returns currently active runtime policy (#880)
* feat(cli): Allow printing only the policy when retrieving sandbox info

* feat(cli): Indicate policy source and revision when retrieving sandboxes

* cargo fmt
2026-04-20 16:44:48 -07:00
John T. Myers 40e9bf6feb feat(policy): add incremental sandbox policy updates (#860)
* feat(policy): add incremental sandbox policy updates

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* docs(policies): expand incremental update guidance

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* feat(policy): audit incremental updates in gateway logs

* docs(policy): quote glob specs in shell examples

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-20 08:00:02 -07:00
Miyoung Choi b7c763204d docs: refresh user-facing docs for recent sandbox and inference changes (#868)
* docs: refresh user-facing docs for recent sandbox and inference changes

- architecture: document system CA loading for upstream TLS, `tls: skip`
  as the opt-out, gateway state persistence across restarts, and OCSF
  structured logging surface.
- inference: document per-provider header allowlist, Authorization
  stripping, 120s streaming idle tolerance, and extended-thinking
  timeout guidance.
- manage-sandboxes: add "Execute a Command in a Sandbox" section for
  `openshell sandbox exec` with flag reference.
- security best practices: expand seccomp denylist (unconditional and
  conditional blocks), document two-phase Landlock probe, High-severity
  `landlock-unavailable` finding, and inference keep-alive closure.
- observability logging: document port in HTTP log URLs, `[reason:...]`
  denial suffixes, proxy 403/502 JSON error bodies, and Landlock
  CONFIG:ENABLED/CONFIG:OTHER events.

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

* docs(architecture): tighten high-level architecture page

Trim implementation detail (CA bundle paths, deprecated TLS keys, SSH
handshake secret) from the high-level architecture page, fix accuracy
issues surfaced during deep audit, and expand uncommon acronyms on first
mention.

- Drop unsupported "cost-based routing" claim from Privacy Router row.
- Replace "brokers requests across the platform" with auth-boundary
  description.
- Add "inference" to Policy Engine constraint list per AGENTS.md.
- Expand Deny rule to include SSRF, blocked control-plane port, and L7
  deny paths in addition to deny-by-default.
- Switch Allow/Deny labels from hyphen to colon; remove em dashes and a
  double space.
- Expand LLM, SSRF, L7, TLS, CA, PEM, SSH, OCSF, and JSONL on first use.

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Made-with: Cursor

* docs: address audit feedback on refresh PR

- observability/logging: rewrite the allowed_ips paragraph after the
  Denial Reasons table; the previous wording said authors "can use"
  invalid entries while also stating they were rejected, which was
  contradictory and conflated load-time validation with the runtime
  per-CONNECT denial phrases the section documents.
- about/architecture: split compound sentences in the new Gateway
  Lifecycle and Observability sections so each clause stands alone.
- inference/about: drop the streaming-tolerance sentence from the prose
  paragraph since the dedicated Streaming reliability table row already
  covers it.

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Made-with: Cursor

* docs(architecture): address review feedback on architecture page

- Drop the Privacy Router row from the Components table; it is not
  yet a separately exposed customer-facing component.
- Update the page description and intro count to match the remaining
  three components (gateway, sandbox, policy engine).
- Split the policy decision into the three modes that the engine
  actually implements: Explicit Deny (deny rules and hardening rules,
  takes precedence), Allow, and Implicit Deny (no rule matched).

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Made-with: Cursor

* docs(architecture): convert policy decisions to a table

Promote the three policy decisions (Explicit Deny, Allow, Implicit
Deny) to a top-level table with Decision, When it applies, and
Outcome columns instead of a nested bulleted list under list item 5.
Top-level tables render reliably across markdown renderers, where
nested-in-list tables do not.

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
Made-with: Cursor

* docs: repharse a bit

---------

Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>
2026-04-17 13:15:59 -07:00
Drew Newberry 463f65a0bb fix(cli): support plaintext gateway registration (#824) 2026-04-13 17:08:08 -07:00
Piotr Mlocek 8b15ef772e docs(fern): move published docs into docs tree (#796)
Remove the legacy Sphinx pipeline and make docs/ the single source of truth so the published site matches the repository layout.
2026-04-09 15:02:27 -07:00
John T. Myers a2f9da5b88 feat(sandbox): extend L7 credential injection to query params, Basic auth, and URL paths (#708)
* feat(sandbox): extend L7 credential injection to query params, Basic auth, and URL paths

Closes #689

Extend SecretResolver to resolve openshell:resolve:env:* placeholders in
URL query parameters, Basic auth tokens, and URL path segments. Absorbs
working code from PR #631 for query param and Basic auth support. Adds
path rewriting for Telegram-style APIs (/bot{TOKEN}/method).

Changes all placeholder rewriting to fail-closed: unresolved placeholders
cause HTTP 500 instead of forwarding raw placeholder strings. Validates
resolved secret values for CRLF/null injection (CWE-113). Validates path
credentials for traversal sequences (CWE-22).

Rewrites request targets before OPA L7 policy evaluation. OPA receives a
redacted path with [CREDENTIAL] markers. Real secrets appear only in the
upstream connection. All log statements use redacted targets.

* fix(docs): remove base64 example that triggers secret scanning alert

* test(sandbox): add relay integration tests for all credential injection methods

Add 9 integration tests that exercise credential injection through the
full relay_http_request_with_resolver pipeline with simulated upstream:

- Bearer header injection
- Exact header value injection (x-api-key)
- Basic auth decode/resolve/re-encode
- Query parameter injection
- URL path injection (Telegram-style concatenated)
- URL path injection (standalone segment)
- Combined path + header injection
- Fail-closed: unresolved header placeholder
- Fail-closed: unresolved path placeholder
2026-03-31 17:21:58 -07:00
Evan LezarandPiotr Mlocek 047de66b22 feat(bootstrap,cli): switch GPU injection to CDI where supported (#495)
* feat(bootstrap): switch GPU injection to CDI where supported

Use an explicit CDI device request (driver="cdi", device_ids=["nvidia.com/gpu=all"])
when the Docker daemon reports CDI spec directories via GET /info (SystemInfo.CDISpecDirs).
This makes device injection declarative and decouples spec generation from consumption.

When the daemon reports no CDI spec directories, fall back to the legacy NVIDIA device
request (driver="nvidia", count=-1) which relies on the NVIDIA Container Runtime hook.
Failure modes for both paths are equivalent: a missing or stale NVIDIA Container Toolkit
installation will cause container start to fail.

CDI spec generation is out of scope for this change; specs are expected to be
pre-generated out-of-band, for example by the NVIDIA Container Toolkit.

---------

Signed-off-by: Evan Lezar <elezar@nvidia.com>
Co-authored-by: Piotr Mlocek <pmlocek@nvidia.com>
2026-03-31 08:23:52 -07:00
John T. MyersandJohn Myers e8950e624c feat(sandbox): add L7 query parameter matchers (#617)
* feat(sandbox): add L7 query parameter matchers

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>

* fix(sandbox): decode + as space in query params and validate glob syntax

Three improvements from PR #617 review:

1. Decode + as space in query string values per the
   application/x-www-form-urlencoded convention. This matches Python's
   urllib.parse, JavaScript's URLSearchParams, Go's url.ParseQuery, and
   most HTTP frameworks. Literal + should be sent as %2B.

2. Add glob pattern syntax validation (warnings) for query matchers.
   Checks for unclosed brackets and braces in glob/any patterns. These
   are warnings (not errors) because OPA's glob.match is forgiving,
   but they surface likely typos during policy loading.

3. Add missing test cases: empty query values, keys without values,
   unicode after percent-decoding, empty query strings, and literal +
   via %2B encoding.

* fix(sandbox): add missing query_params field in forward proxy L7 request info

* style(sandbox): fix formatting in proxy L7 query param parsing

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
2026-03-30 13:53:12 -07:00
John T. MyersandJohn Myers 758c62d18d fix(sandbox): handle per-path Landlock errors instead of abandoning entire ruleset (#677)
* fix(sandbox): handle per-path Landlock errors instead of abandoning entire ruleset

A single missing path (e.g., /app in containers without that directory)
caused PathFd::new() to propagate an error out of the entire Landlock
setup closure. Under BestEffort mode, this silently disabled all
filesystem restrictions for the sandbox.

Changes:
- Extract try_open_path() and classify_path_error() helpers that handle
  PathFd failures per-path instead of per-ruleset
- BestEffort mode: skip inaccessible paths with a warning, apply
  remaining rules
- HardRequirement mode: fail immediately on any inaccessible path
- Add zero-rule safety check to prevent applying an empty ruleset that
  would block all filesystem access
- Pre-filter system-injected baseline paths (e.g., /app) in enrichment
  functions so missing paths never reach Landlock
- Add unit tests for try_open_path, classify_path_error, and error
  classification for ENOENT, EACCES, ELOOP, ENAMETOOLONG, ENOTDIR
- Update user-facing docs and architecture docs with Landlock behavior
  tables, baseline path filtering, and compatibility mode semantics
- Fix stale ABI::V1 references in docs (code uses ABI::V2)

Closes #664

* fix(sandbox): use debug log for NotFound in Landlock best-effort mode

NotFound errors for stale baseline paths (e.g. /app persisted in the
server-stored policy but absent in this container) are expected in
best-effort mode. Downgrade from warn! to debug! so the message does
not leak into SSH exec stdout (the pre_exec hook inherits the tracing
subscriber whose writer targets fd 1).

Genuine errors (permission denied, symlink loops, etc.) remain at warn!
for operator visibility.

Also move custom_image e2e marker from /opt to /etc (a Landlock baseline
read-only path) since the security fix now properly enforces filesystem
restrictions.

---------

Co-authored-by: John Myers <johntmyers@users.noreply.github.com>
2026-03-30 13:19:19 -07:00
John T. Myers f37b69b5e5 feat(sandbox): auto-detect TLS and terminate unconditionally for credential injection (#544)
* feat(sandbox): auto-detect TLS and terminate unconditionally for credential injection

Closes #533

The proxy now auto-detects TLS by peeking the first bytes of each
connection. When TLS is detected, it terminates unconditionally —
enabling credential injection and optional L7 inspection without
requiring explicit 'tls: terminate' in the policy.
2026-03-23 18:45:18 -07:00
Khai Le b4e20c19f5 docs(providers): add Groq to the supported providers table (#518) 2026-03-21 13:34:23 -07:00
Parth Sareen ba19aade08 docs(ollama): update ollama tutorial and references to match latest (#511)
features
2026-03-20 14:42:54 -07:00
John T. Myers a831a8921b feat(settings): gateway-to-sandbox runtime settings channel (#474)
* feat(gateway/sandbox): add global and sandbox runtime settings flow
2026-03-20 14:08:57 -07:00
Miyoung Choi 510dcd1d92 docs: add guidance for OpenAI-compatible cloud providers (#458)
* add guidance for OpenAI-compatible cloud providers

* add provider list and xref link

* add xref

* add provider name value column
2026-03-19 09:58:33 -07:00
Parth Sareen efb80e7382 docs(ollama): add ollama to community sandboxes catalog and supported agents (#383)
* docs(ollama): add ollama to community sandboxes catalog and supported agents

* update readme
2026-03-17 14:02:40 -07:00
Piotr Mlocek 85903b95e0 docs: add debug-inference skill, Ollama tutorial, and remove stale inference policy references (#353) 2026-03-16 07:26:25 -07:00