Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
41c8fe7
feat(sandbox): import host corporate proxy CA into sandbox trust (#6210)
yimoj Jul 6, 2026
379a3dc
test(sandbox): keep corporate CA test bodies linear (#6210)
yimoj Jul 6, 2026
5f99716
fix(sandbox): harden corporate CA import per review (#6210)
yimoj Jul 6, 2026
03c0960
fix(sandbox): correct Hermes CA env + validate all CA blocks (#6210)
yimoj Jul 6, 2026
577bfb7
test(sandbox): add issue-ref suffixes and Hermes bail-path test (#6210)
yimoj Jul 6, 2026
e2420fb
fix(security): harden corporate-CA merge against symlink + missing ba…
prekshivyas Jul 6, 2026
78c4e99
Merge remote-tracking branch 'upstream/main' into pr6292m
prekshivyas Jul 6, 2026
d76dc2b
Merge remote-tracking branch 'upstream/main' into pr6292fix
prekshivyas Jul 6, 2026
04d9a51
test(rebuild): make prepared-recovery acceptance self-contained (#6210)
prekshivyas Jul 6, 2026
bccdc7c
docs(onboard): narrow #6210 corporate-CA scope to env-configured sour…
prekshivyas Jul 6, 2026
b849a52
Merge remote-tracking branch 'origin/main' into fix/6210-corporate-pr…
prekshivyas Jul 6, 2026
800d5b2
Merge branch 'main' into fix/6210-corporate-proxy-ca
prekshivyas Jul 6, 2026
01d4fff
fix(onboard): detect host trust-store corporate CA and bake only vali…
yimoj Jul 8, 2026
7456050
fix(onboard): surface silent-skip and runtime-merge failures for corp…
yimoj Jul 8, 2026
3c7ae76
fix(onboard): harden Dockerfile corporate-CA decode against malformed…
yimoj Jul 8, 2026
79d7f6d
fix(onboard): reject group-writable corporate CA sources and cover an…
yimoj Jul 8, 2026
55bb6ac
docs(onboard): clarify /etc/ssl/certs contract, permanent fallbacks, …
yimoj Jul 8, 2026
dd980a1
docs(onboard): document the corporate-CA merge trust-anchor path safe…
yimoj Jul 8, 2026
4c5f6c7
merge(main): sync PR #6292 with latest main
cv Jul 9, 2026
f89b641
fix(onboard): reject merged OS trust stores as corporate CA sources (…
yimoj Jul 9, 2026
e3554bf
test(onboard): normalize corporate CA test issue suffixes
cv Jul 9, 2026
fd2844d
docs(onboard): clarify /etc/ssl/certs JSDoc note and custom-Dockerfil…
yimoj Jul 9, 2026
c7ff2d8
test: add corporate CA live evidence
prekshivyas Jul 9, 2026
a60e3b1
test: make corporate CA live probe file-backed
prekshivyas Jul 9, 2026
7cab7e3
test: shell quote cloud onboard installer command
prekshivyas Jul 9, 2026
9799a74
docs(onboard): pin corporate CA anchor-source scope
prekshivyas Jul 9, 2026
51ed9da
fix(onboard): warn on literal ssl certs-only CA
prekshivyas Jul 9, 2026
455ea2c
fix(onboard): tighten corporate CA trust handling
prekshivyas Jul 9, 2026
81cf13f
Merge remote-tracking branch 'upstream/main' into pr-6292-corp-ca
prekshivyas Jul 9, 2026
4d5a899
fix(onboard): import standalone ssl cert CAs
prekshivyas Jul 9, 2026
9ac7e4d
fix(onboard): bound corporate CA anchor scans
prekshivyas Jul 9, 2026
16a8e53
Merge branch 'main' into fix/6210-corporate-proxy-ca
prekshivyas Jul 9, 2026
faf0a76
test(e2e): clean corporate CA fixtures on skip
prekshivyas Jul 10, 2026
7ddde82
Merge remote-tracking branch 'upstream/main' into pr-6292-corp-ca
prekshivyas Jul 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,12 @@ ARG NEMOCLAW_OPENCLAW_OTEL=0
ARG NEMOCLAW_OPENCLAW_OTEL_ENDPOINT=http://host.openshell.internal:4318
ARG NEMOCLAW_OPENCLAW_OTEL_SERVICE_NAME=openclaw-gateway
ARG NEMOCLAW_OPENCLAW_OTEL_SAMPLE_RATE=1.0
# Base64-encoded host corporate-proxy CA bundle (#6210). Empty by default. When
# onboard detects an operator-supplied corporate CA on the host it bakes it
# here; the RUN below decodes it to a root-owned file that the entrypoint
# appends to the OpenShell trust bundle at runtime. The CA is a public
# certificate, not a secret, so baking it into an image layer is acceptable.
ARG NEMOCLAW_CORPORATE_CA_B64=

# SECURITY: Promote build-args to env vars so the TypeScript script reads them
# via process.env, never via string interpolation into executable source code.
Expand Down Expand Up @@ -924,6 +930,26 @@ ENV NEMOCLAW_MODEL=${NEMOCLAW_MODEL} \
NEMOCLAW_OPENCLAW_OTEL_SERVICE_NAME=${NEMOCLAW_OPENCLAW_OTEL_SERVICE_NAME} \
NEMOCLAW_OPENCLAW_OTEL_SAMPLE_RATE=${NEMOCLAW_OPENCLAW_OTEL_SAMPLE_RATE}

# Decode the host corporate-proxy CA (#6210) to a root-owned, read-only file
# when onboard baked one in. No-op when NEMOCLAW_CORPORATE_CA_B64 is empty. The
# ARG is expanded by the shell (not interpolated into source), and its value is
# base64 sanitized host-side, so this is not an injection vector.
# hadolint ignore=DL3059,DL4006
RUN if [ -n "${NEMOCLAW_CORPORATE_CA_B64}" ]; then \
command -v base64 >/dev/null 2>&1 || { echo "[nemoclaw] base64 is required to decode NEMOCLAW_CORPORATE_CA_B64 but is not installed in the build image" >&2; exit 1; }; \
command -v openssl >/dev/null 2>&1 || { echo "[nemoclaw] openssl is required to validate NEMOCLAW_CORPORATE_CA_B64 but is not installed in the build image (#6210)" >&2; exit 1; }; \
mkdir -p /usr/local/share/nemoclaw \
&& { printf '%s' "${NEMOCLAW_CORPORATE_CA_B64}" | base64 --decode > /tmp/nemoclaw-corporate-ca.decoded 2>/dev/null \
|| { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 is not valid base64; expected a single-line base64-encoded PEM (#6210)" >&2; exit 1; }; } \
&& awk '/-----BEGIN CERTIFICATE-----/{f=1} f{print} /-----END CERTIFICATE-----/{f=0}' /tmp/nemoclaw-corporate-ca.decoded > /usr/local/share/nemoclaw/corporate-ca.pem \
&& rm -f /tmp/nemoclaw-corporate-ca.decoded \
&& { grep -qF -- "-----BEGIN CERTIFICATE-----" /usr/local/share/nemoclaw/corporate-ca.pem || { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 did not decode to a bundle of valid X.509 certificates (#6210)" >&2; exit 1; }; } \
&& { openssl crl2pkcs7 -nocrl -certfile /usr/local/share/nemoclaw/corporate-ca.pem >/dev/null 2>&1 || { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 did not decode to a bundle of valid X.509 certificates (#6210)" >&2; exit 1; }; } \
&& chown root:root /usr/local/share/nemoclaw/corporate-ca.pem \
&& chmod 0444 /usr/local/share/nemoclaw/corporate-ca.pem \
&& echo "[nemoclaw] baked host corporate-proxy CA into image trust (#6210)"; \
fi

# Bake reduced messaging runtime metadata for the entrypoint. The full
# NEMOCLAW_MESSAGING_PLAN_B64 is a build input; OpenShell sandbox create only
# forwards explicit runtime env, so nemoclaw-start reads this generic artifact
Expand Down
27 changes: 27 additions & 0 deletions agents/hermes/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,12 @@ ARG NEMOCLAW_HERMES_TOOL_GATEWAY_BROKER=0
ARG NEMOCLAW_HERMES_TOOL_GATEWAY_PRESETS_B64=W10=
ARG NEMOCLAW_BUILD_ID=default
ARG NEMOCLAW_DARWIN_VM_COMPAT=0
# Base64-encoded host corporate-proxy CA bundle (#6210). Empty by default. When
# onboard detects an operator-supplied corporate CA on the host it bakes it
# here; the RUN below decodes it to a root-owned file that the entrypoint
# appends to the OpenShell trust bundle at runtime. The CA is a public
# certificate, not a secret, so baking it into an image layer is acceptable.
ARG NEMOCLAW_CORPORATE_CA_B64=
# Total model context window (input + output tokens). Empty by default so
# Hermes auto-detects from the endpoint's /v1/models max_model_len; onboard
# rewrites this ARG (via dockerfile-patch) when it probes a runtime value or
Expand Down Expand Up @@ -308,6 +314,27 @@ WORKDIR /opt/hermes
# hadolint ignore=DL3059
RUN node --experimental-strip-types /src/lib/messaging/applier/build/messaging-build-applier.mts --agent hermes --phase agent-install

# Decode the host corporate-proxy CA (#6210) to a root-owned, read-only file
# when onboard baked one in. No-op when NEMOCLAW_CORPORATE_CA_B64 is empty. The
# ARG is expanded by the shell (not interpolated into source), and its value is
# base64 sanitized host-side, so this is not an injection vector. Must run as
# root, before the USER sandbox drop below.
# hadolint ignore=DL3059,DL4006
RUN if [ -n "${NEMOCLAW_CORPORATE_CA_B64}" ]; then \
command -v base64 >/dev/null 2>&1 || { echo "[nemoclaw] base64 is required to decode NEMOCLAW_CORPORATE_CA_B64 but is not installed in the build image" >&2; exit 1; }; \
command -v openssl >/dev/null 2>&1 || { echo "[nemoclaw] openssl is required to validate NEMOCLAW_CORPORATE_CA_B64 but is not installed in the build image (#6210)" >&2; exit 1; }; \
mkdir -p /usr/local/share/nemoclaw \
&& { printf '%s' "${NEMOCLAW_CORPORATE_CA_B64}" | base64 --decode > /tmp/nemoclaw-corporate-ca.decoded 2>/dev/null \
|| { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 is not valid base64; expected a single-line base64-encoded PEM (#6210)" >&2; exit 1; }; } \
&& awk '/-----BEGIN CERTIFICATE-----/{f=1} f{print} /-----END CERTIFICATE-----/{f=0}' /tmp/nemoclaw-corporate-ca.decoded > /usr/local/share/nemoclaw/corporate-ca.pem \
&& rm -f /tmp/nemoclaw-corporate-ca.decoded \
&& { grep -qF -- "-----BEGIN CERTIFICATE-----" /usr/local/share/nemoclaw/corporate-ca.pem || { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 did not decode to a bundle of valid X.509 certificates (#6210)" >&2; exit 1; }; } \
&& { openssl crl2pkcs7 -nocrl -certfile /usr/local/share/nemoclaw/corporate-ca.pem >/dev/null 2>&1 || { echo "[nemoclaw] NEMOCLAW_CORPORATE_CA_B64 did not decode to a bundle of valid X.509 certificates (#6210)" >&2; exit 1; }; } \
&& chown root:root /usr/local/share/nemoclaw/corporate-ca.pem \
&& chmod 0444 /usr/local/share/nemoclaw/corporate-ca.pem \
&& echo "[nemoclaw] baked host corporate-proxy CA into image trust (#6210)"; \
fi

WORKDIR /sandbox
USER sandbox

Expand Down
92 changes: 91 additions & 1 deletion agents/hermes/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1428,6 +1428,96 @@ export http_proxy="$_PROXY_URL"
export https_proxy="$_PROXY_URL"
export no_proxy="$_NO_PROXY_VAL"

# Corporate proxy CA merge (NemoClaw#6210).
# OpenShell injects SSL_CERT_FILE for its own L7 proxy CA at runtime. When a
# separate corporate MITM proxy sits in front of the host and re-signs external
# TLS with a different root, that root is absent from the OpenShell bundle, so
# external endpoints (e.g. api.telegram.org) fail verification even when policy
# allows the connection. If onboard baked an operator-supplied corporate CA
# into the image, append it to the OpenShell bundle — never replace it (the
# #1828 OpenShell CA behavior stays intact) — and repoint SSL_CERT_FILE at the
# merged bundle before the CURL/REQUESTS/GIT derivation below picks it up.
_NEMOCLAW_CORPORATE_CA_FILE="/usr/local/share/nemoclaw/corporate-ca.pem"
# Concise, secret-free warning when a baked corporate CA fails to merge at
# runtime. Names the failed step + target path only (never certificate bytes)
# so an operator can distinguish "no CA was baked" from "runtime merge failed".
_nemoclaw_ca_merge_warn() {
echo "[nemoclaw] WARNING: corporate proxy CA merge failed at ${1}; keeping OpenShell-only trust — external TLS through the corporate proxy may fail (#6210)" >&2
}
merge_corporate_proxy_ca() {
[ -s "$_NEMOCLAW_CORPORATE_CA_FILE" ] || return 0
_base_bundle=""
if [ -n "${SSL_CERT_FILE:-}" ] && [ -f "${SSL_CERT_FILE}" ]; then
_base_bundle="$SSL_CERT_FILE"
elif [ -f /etc/ssl/certs/ca-certificates.crt ]; then
_base_bundle="/etc/ssl/certs/ca-certificates.crt"
fi
_merged="/tmp/nemoclaw-ca-bundle.pem"
# Trust-anchor path safety (#6210): in the normal container start this
# entrypoint runs as root (the step-down prefix wraps only the later agent
# commands, not this top-level merge), so the merged bundle is written
# root-owned 0444 — the non-root sandbox user that the agent later runs as
# inherits SSL_CERT_FILE but cannot rewrite it. The predictable /tmp path is
# still handled safely: it is built in a fresh mktemp sibling and atomically
# renamed into place; a pre-planted symlink at the target is dropped first
# (below); and rename(2) replaces the target link/file rather than writing
# through it, so a pre-planted symlink or file cannot redirect the write. On a
# non-root start the whole entrypoint (and the agent) is the same sandbox user,
# so there is no privilege boundary to cross.
# Build the bundle in a private temp file next to the target, verifying every
# write, then atomically rename into place. If any step fails we bail without
# exporting anything, leaving the OpenShell-only trust intact rather than
# pointing tools at a partial/empty bundle.
_tmp="$(mktemp "${_merged}.XXXXXX" 2>/dev/null)" || {
_nemoclaw_ca_merge_warn "create temp bundle (${_merged})"
return 0
}
if [ -n "$_base_bundle" ]; then
cat "$_base_bundle" >>"$_tmp" 2>/dev/null || {
rm -f "$_tmp"
_nemoclaw_ca_merge_warn "append OpenShell bundle"
return 0
}
printf '\n' >>"$_tmp" 2>/dev/null || {
rm -f "$_tmp"
_nemoclaw_ca_merge_warn "append OpenShell bundle"
return 0
}
fi
cat "$_NEMOCLAW_CORPORATE_CA_FILE" >>"$_tmp" 2>/dev/null || {
rm -f "$_tmp"
_nemoclaw_ca_merge_warn "append corporate CA"
return 0
}
chmod 0444 "$_tmp" 2>/dev/null || {
rm -f "$_tmp"
_nemoclaw_ca_merge_warn "set merged bundle permissions (${_merged})"
return 0
}
# Defense-in-depth for the predictable /tmp path (#6210): if a co-tenant
# pre-planted a symlink at the target, drop it first so we rename into a fresh
# regular file we own rather than through an attacker-controlled link.
if [ -L "$_merged" ]; then
rm -f "$_merged" 2>/dev/null || true
fi
mv -f "$_tmp" "$_merged" 2>/dev/null || {
rm -f "$_tmp"
_nemoclaw_ca_merge_warn "install merged bundle (${_merged})"
return 0
}
# Export all CA env vars explicitly (not via the ${VAR:-…} defaulting below,
# which would keep an OpenShell-preset CURL/REQUESTS/GIT value pointing at the
# OpenShell-only bundle instead of the merged one).
export SSL_CERT_FILE="$_merged"
export CURL_CA_BUNDLE="$_merged"
export REQUESTS_CA_BUNDLE="$_merged"
export GIT_SSL_CAINFO="$_merged"
export NODE_EXTRA_CA_CERTS="$_merged"
export _NEMOCLAW_CORPORATE_CA_MERGED=1
echo "[nemoclaw] merged corporate proxy CA into sandbox trust bundle (#6210)" >&2
}
merge_corporate_proxy_ca

Comment thread
coderabbitai[bot] marked this conversation as resolved.
# OpenShell injects SSL_CERT_FILE/CURL_CA_BUNDLE for its L7 proxy CA. Persist
# them into connect-session shells so Python Slack probes and Hermes tools trust
# the same proxy CA that the entrypoint received at startup.
Expand Down Expand Up @@ -1469,7 +1559,7 @@ if [ -f /opt/hermes/ui-tui/dist/entry.js ]; then
export HERMES_TUI_DIR="/opt/hermes/ui-tui"
fi
TUIENVEOF
for _ca_env_name in SSL_CERT_FILE CURL_CA_BUNDLE REQUESTS_CA_BUNDLE GIT_SSL_CAINFO; do
for _ca_env_name in SSL_CERT_FILE CURL_CA_BUNDLE REQUESTS_CA_BUNDLE GIT_SSL_CAINFO NODE_EXTRA_CA_CERTS; do
_ca_env_value="${!_ca_env_name:-}"
if [ -n "$_ca_env_value" ]; then
printf 'export %s=%q\n' "$_ca_env_name" "$_ca_env_value"
Expand Down
27 changes: 27 additions & 0 deletions docs/reference/troubleshooting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1227,6 +1227,33 @@ If they are missing on an older sandbox, upgrade NemoClaw and run:
$$nemoclaw <name> rebuild
```

### External channel TLS fails behind a corporate MITM proxy (`NET:FAIL`)

On networks where a corporate proxy in front of the host re-signs external TLS with its own root CA, external endpoints such as `api.telegram.org` fail certificate verification even when the network policy allows the connection. Logs show the request opening (`NET:OPEN ... api.telegram.org:443`) followed by `NET:FAIL`. OpenShell injects only its own L7-proxy CA into the sandbox, so the separate corporate root is missing from the trust path.

To fix this, point NemoClaw at your corporate CA bundle on the host **before** onboarding, then onboard (or rebuild). The recommended, explicit way is `NEMOCLAW_CORPORATE_CA_BUNDLE`. NemoClaw validates the bundle, bakes it into the sandbox image, and at startup appends it to the OpenShell trust bundle — it never replaces the OpenShell CA — repointing `SSL_CERT_FILE`, `CURL_CA_BUNDLE`, `REQUESTS_CA_BUNDLE`, `GIT_SSL_CAINFO`, and `NODE_EXTRA_CA_CERTS` at the merged bundle so curl, Python, Git, and Node all trust both roots:

```bash
export NEMOCLAW_CORPORATE_CA_BUNDLE=/path/to/corporate-ca.pem
$$nemoclaw onboard
```

If your corporate CA is already installed in the host system trust store, NemoClaw detects it automatically. It scans the administrator anchor directories (recursively, matching `update-ca-certificates`) — `/usr/local/share/ca-certificates/` on Debian/Ubuntu and `/etc/pki/ca-trust/source/anchors/` on RHEL/Fedora — which is where an administrator drops a root CA before running `update-ca-certificates` / `update-ca-trust`. NemoClaw deliberately does **not** read the merged `/etc/ssl/certs/ca-certificates.crt`, which also contains the distro's public roots; it imports only these bounded anchor sources so it never bakes broad, unrelated OS trust into the image. This host-store detection is a last-resort fallback, tried only after the environment variables above. To scan a non-standard anchor location, set `NEMOCLAW_CORPORATE_CA_ANCHOR_DIRS` to a path-list of directories; set it to an empty value to disable host-store scanning.

Resolution order:

1. Explicit `NEMOCLAW_CORPORATE_CA_BUNDLE` (fails onboarding loudly when set but invalid, or when it points at a merged OS trust store such as `/etc/ssl/certs/ca-certificates.crt` — export only your corporate root instead).
2. Conventional CA variables `REQUESTS_CA_BUNDLE`, `CURL_CA_BUNDLE`, then `SSL_CERT_FILE` (each **skipped with a `WARNING` log** when it is set but points at a missing or invalid file — the import is non-fatal, but the warning tells you it was skipped). A conventional variable that points at a merged OS trust store (for example the common `SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt`) is also skipped with a `WARNING`, so a default system bundle is never baked in wholesale — the host-anchor scan below still finds a locally-installed corporate root.
3. Host administrator anchor directories (an empty or absent directory is skipped silently; a directory that holds candidate files but no valid CA, or that exceeds the size/count caps, is skipped with a `WARNING` log).

When a fallback or host-store source is baked, onboarding logs which source and path it used (`baking corporate proxy CA from …`). If you set a conventional CA variable but the import does not happen, check the onboard build logs: a variable that points at a missing or invalid file is skipped with a `WARNING: … was skipped for corporate CA import` line, and an anchor directory that holds only invalid certificates logs a similar warning. Absence of the `baking …` line means no source validated. Use `NEMOCLAW_CORPORATE_CA_BUNDLE` for explicit, fail-loud behavior. To import a corporate root that is not installed in an anchor directory, export just your corporate root (and any intermediates) into a small PEM file and point `NEMOCLAW_CORPORATE_CA_BUNDLE` at it.

`/etc/ssl/certs/` contract: NemoClaw satisfies the #6210 host trust-store acceptance path by reading the administrator anchor **source** directories above, not the merged `/etc/ssl/certs/ca-certificates.crt` view. This is intentional — the merged file interleaves your corporate root with the distro's public root bundle, and importing it wholesale would widen sandbox trust far beyond the one corporate proxy CA. A corporate root installed via `update-ca-certificates` / `update-ca-trust` already lives in an anchor source directory, so it is detected. If no anchor source validates but NemoClaw sees direct regular CA certificate files in the literal `/etc/ssl/certs/` output directory, it imports only those validated standalone CA files while still excluding the merged `ca-certificates.crt` bundle and symlink fan-out. Normal leaf certificates in that directory, such as Ubuntu's `ssl-cert-snakeoil.pem`, are ignored. A root present *only* as a hand-edited entry in the merged file is not imported, and must be pointed at explicitly via `NEMOCLAW_CORPORATE_CA_BUNDLE`.

Custom Dockerfile contract: the managed NemoClaw sandbox Dockerfiles handle the corporate CA automatically — onboarding bakes the validated bundle into `ARG NEMOCLAW_CORPORATE_CA_B64`, and the image decodes it into the root-owned, read-only file `/usr/local/share/nemoclaw/corporate-ca.pem`. If you build the sandbox from a **custom Dockerfile**, the fallback and host-store sources are a silent no-op unless that Dockerfile declares `ARG NEMOCLAW_CORPORATE_CA_B64` and decodes it into `/usr/local/share/nemoclaw/corporate-ca.pem` the same way. The explicit `NEMOCLAW_CORPORATE_CA_BUNDLE` is the exception — it fails onboarding loudly (rather than no-op) when the managed ARG is absent, so you find out immediately. Either add the ARG and decode step to your Dockerfile, or keep using a managed Dockerfile, to import a corporate CA through automatic detection.

Every imported source must be a regular (non-symlink), readable PEM file that is **not group- or world-writable** (a trust anchor any other user could rewrite is rejected), non-empty and within the size cap, and in which **every** certificate block parses as an X.509 CA certificate (`basicConstraints CA:TRUE`). The imported trust is capped at a small corporate chain (not a full OS trust store) — a source that would exceed the cap is rejected or skipped rather than truncated. To disable the import entirely, set `NEMOCLAW_CORPORATE_CA_IMPORT=0`.

### A request inside the sandbox fails with `CONNECT tunnel failed, response 403`

Sandbox outbound network access is denied by default and enforced by the OpenShell proxy.
Expand Down
Loading
Loading