111 Commits
Author SHA1 Message Date
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
Drew Newberry 0471c6d2ab fix(gateway): keep vm driver opt-in (#1375) 2026-05-13 22:32:58 -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 957daa0a0f docs(helm): document supervisor.sideloadMethod and sandboxNamespace default (#1309)
Add supervisor.sideloadMethod to the Kubernetes setup chart values table
and the compute drivers reference table. The value was added in the
ImageVolumeSource sideload PR and controls whether the supervisor binary
is delivered via an OCI image volume mount or an init container, with
auto-detection based on cluster version when left empty.

Update the server.sandboxNamespace description in both pages to reflect
that the Helm chart now derives it from the release namespace by default
when the value is left empty.
2026-05-11 13:21:56 -07:00
Drew Newberry daa2a362d5 fix(packaging): enable mTLS for local packages (#1271) 2026-05-08 13:02:12 -07:00
Mrunal Patel 1f35abbefb feat(sandbox): add Kubernetes user namespace isolation (hostUsers: false) (#983)
Add opt-in support for Kubernetes user namespace isolation on sandbox
pods. When enabled, container UID 0 maps to an unprivileged host UID
and capabilities become namespaced, providing defense-in-depth for the
supervisor process.

Configuration is two-layered: a cluster-wide default via
OPENSHELL_ENABLE_USER_NAMESPACES (default false) and a per-sandbox
override via the new `user_namespaces` field on SandboxTemplate.

When user namespaces are active, the pod security context is extended
with SETUID, SETGID, and DAC_READ_SEARCH capabilities to match the
bounding-set requirements inside a user namespace.

Introduces SandboxPodParams struct to replace long argument lists on
sandbox_to_k8s_spec and sandbox_template_to_k8s.

Validated end-to-end on OCP 4.22 (K8s 1.35.3, CRI-O 1.35, RHEL
CoreOS, kernel 5.14) with full SSH tunnel and non-identity UID mapping.
2026-05-08 12:39:48 -04:00
Drew Newberry 8ab5ee875b fix(vm): harden compute driver socket (#1248) 2026-05-07 20:03:16 -07:00
Drew Newberry 084c93b6ad fix(installer): repair dev install package and service setup (#1252) 2026-05-07 16:05:40 -07:00
Drew Newberry 310e1a5c14 docs(podman): restore driver architecture details (#1244) 2026-05-07 13:22:24 -07:00
Mesut Oezdil d2321a2c00 docs: fix broken policy-engine anchor in policies page (#1246) 2026-05-07 13:19:42 -07:00
Taylor Mutch d8f614fa31 docs(kubernetes): add initial reference docs (#1243)
* docs(kubernetes): add initial reference docs

Add a Kubernetes reference section under docs/reference/kubernetes/ covering
gateway setup, OIDC and reverse-proxy authentication, cert-manager PKI, and
Gateway API external access. Update installation.mdx to link to the new setup
page and nest the new folder under the Reference section in index.yml.

* docs(kubernetes): promote Kubernetes to top-level nav and retitle pages

Move docs/reference/kubernetes/ to docs/kubernetes/ so the section appears
as a top-level nav entry rather than nested under Reference. Retitle the
pages to broader, action-oriented names (Managing Certificates, Ingress,
Access Control) and rename the files to match. Update cross-references in
setup.mdx and the installation page.

* docs(nav): revert Reference to folder mode

The Reference section was switched to explicit section/contents to host
the nested Kubernetes subsection. With Kubernetes promoted to a top-level
folder, restore folder-mode auto-detection. Side effect: sandbox-compute-drivers
is picked up again, which was silently absent from the explicit list.

* docs(kubernetes): add OpenShift install page

Mirror the OpenShift install instructions from PR #1240 into the
Kubernetes docs section. Documents the SCC binding for sandbox pods
and the chart overrides required by OpenShift's Security Context
Constraints (disabled PKI init Job, plaintext TLS, cleared fsGroup
and runAsUser).
2026-05-07 12:55:56 -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 fd7df484f4 docs: fix tutorials card link on index page (#1204)
The Tutorials card on the home page was pointing to /tutorials instead
of /get-started/tutorials. This was missed in #1137.
2026-05-06 15:05:36 -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
Piotr Mlocek ee2de81bc9 fix(sandbox): preserve encoded slash policy from proto (#1073) 2026-04-29 16:36:49 -07:00
John T. Myers 0914f3f4f7 fix(sandbox): log L7 parse denials (#1072)
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-29 16:15:37 -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 a01b6dd820 fix(docs): scope fenced code language linting (#965) 2026-04-24 14:23:31 -07:00
Piotr Mlocek df38d1f66f feat(ci): add Markdown and Mermaid linting (#933) 2026-04-24 11:27:02 -07:00
John T. Myers f954e5927a fix(sandbox): resolve sandbox host aliases in SSRF checks (#912)
Closes #879

Resolve policy hostnames against the sandbox's /etc/hosts before DNS so Kubernetes hostAliases are visible to the proxy while keeping the existing allowed_ips SSRF enforcement semantics intact.

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-22 12:37:32 -07:00
Piotr Mlocek a6d45528c1 feat(server,sandbox): supervisor-initiated SSH connect and exec over gRPC-multiplexed relay (#867) 2026-04-21 08:38:18 -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 8a813aba49 fix(sandbox): apply supervisor seccomp prelude (#891)
* fix(sandbox): apply supervisor seccomp prelude

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

* fix(sandbox): delay supervisor prelude until bootstrap

---------

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-20 13:09:23 -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
Miyoung Choi 2c9c146cb6 docs: fix TOC structure (#797)
* docs: fix TOC structure

* docs: fix wrong section title

* remove Home

* fix(fern): properly add the landing page
2026-04-17 13:15:29 -07:00
Drew Newberry 5718553b97 feat(release): publish standalone openshell-gateway binaries (#853) 2026-04-16 16:58:24 -07:00
John T. Myers 25d2530b3c fix(inference): allowlist routed request headers (#826)
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-15 15:19:18 -07:00
John T. Myers 28db08eeb8 fix(sandbox): disable child core dumps (#821)
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
2026-04-14 22:28:18 -07:00
John T. Myers 28e1ff7b40 feat(policy): add deny rules to network policy schema (#822)
* feat(policy): add deny rules to network policy schema

Closes #565

Add L7 deny rules that block specific requests even when allowed by
access presets or explicit allow rules. Deny rules mirror the full
capability set of allow rules (method, path, query params, SQL command)
and take precedence -- if a request matches any deny rule, it is blocked
regardless of allow rules.

This enables the "allow everything except these specific operations"
pattern without enumerating every allowed endpoint. For example, granting
read-write access to GitHub while blocking PR approvals, branch
protection changes, and ruleset modifications.

* fix(policy): deny query matching fails closed, mirror allow-side validation

Addresses PR review findings P1 and P3:

P1: Deny-side query matching now uses fail-closed semantics. If ANY
value for a query key matches the deny matcher, the deny fires. The
previous implementation reused allow-side "all values must match"
logic which allowed ?force=true&force=false to bypass a deny on
force=true.

P3: Deny-side query validation now mirrors the full allow-side checks:
empty any lists, non-string matcher values, glob+any mutual exclusion,
glob type checks, and glob syntax warnings are all validated.
2026-04-14 21:52:14 -07:00
Drew Newberry 463f65a0bb fix(cli): support plaintext gateway registration (#824) 2026-04-13 17:08:08 -07:00
John T. Myers 2ca553a4a0 fix(sandbox): validate always-blocked IPs at load time, enrich denial logs, and filter un-fixable proposals (#814) (#815)
Policies with allowed_ips entries targeting loopback, link-local, or
unspecified ranges now fail at connection time instead of being silently
blocked at runtime. The shorthand log format for DENIED events includes
a [reason:...] suffix so operators can distinguish 'allowlist miss' from
'structurally un-allowable'. The mechanistic mapper skips proposals for
always-blocked destinations, preventing the infinite TUI notification
loop. The gateway validates proposed rules on approval as defense-in-depth.

- Extract shared IP helpers (is_always_blocked_ip, is_always_blocked_net,
  is_internal_ip) to openshell_core::net
- Reject always-blocked entries in parse_allowed_ips with hard error
- Skip implicit allowed_ips synthesis for always-blocked literal IP hosts
- Add status_detail to HttpActivityBuilder for denial reason propagation
- Enrich NET and HTTP shorthand with [reason:...] for DENIED events
- Add engine: tag to HTTP shorthand (consistency with NET shorthand)
- Filter always-blocked proposals in mechanistic mapper generate_proposals
- Add validate_rule_not_always_blocked server-side defense-in-depth
- Update architecture docs, published docs, and E2E test assertions
2026-04-13 09:47:50 -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