fix(pi): forward SSL_CERT_FILE into the sandbox so provider TLS works in Docker #87
No reviewers
Labels
No labels
epic
in-review
ready-for-agent
ready-for-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
weiwen/evie!87
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/evie-sandbox-cert-fix"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Root cause
Sandboxed pi sessions could not make TLS calls to the model provider, so every Telegram turn crashed with
pi provider error: Connection error.after a ~20s hang.evie's bwrap sandbox does
--clearenvand then re-adds only an explicit base env allowlist (PATH,EVIE_CHAT_ID,EVIE_SOCKET), which never included a CA-certificate path. Under the old NixOS host, pi's TLS client happened to find a bundle at the default filesystem path the host provided. The nix-built Docker image has no/etc/ssl/certs/ca-certificates.crt(onlyca-bundle.crt), the sandbox binds/nixbut not/etc, and--clearenvwipes the daemon'sSSL_CERT_FILE. So inside the sandbox pi had no discoverable CA bundle.Proven in the container: a cleared-env
curl https://opencode.ai/returnshttp=000; the same env plusSSL_CERT_FILE=<nix ca-bundle>returnshttp=200. The bundle IS readable inside the sandbox (the wholesale/nixro-bind covers the nss-cacert store path); pi was simply never told where it is. The sudo/HTTP path is unaffected because it inherits the daemon's full environment.The fix
sandbox_setenv_argsnow takes acert_envslice, filled from the daemon environment byca_cert_env()/ca_cert_env_from():SSL_CERT_FILEandNIX_SSL_CERT_FILE(honoured by nix-built TLS clients), each forwarded only when set and non-empty. Both sandboxed paths (interactive pi and sandboxed scripts) pass it, reusing the existingpush_setenvemission point.When the daemon has neither, nothing is forwarded, so hosts that provide a working default cert path keep their current behaviour. These are paths to public root certificates, not secrets, so they are not subject to the
RESERVED_SANDBOX_ENV/DAEMON_ONLY_SECRETSguards; those guards are untouched for everything else.Test
New
sandbox_setenv_args_forwards_the_ca_bundle_path_only_when_the_daemon_has_one: asserts--setenv SSL_CERT_FILE <value>appears on the sandboxed path when the daemon has it, thatNIX_SSL_CERT_FILEforwards on its own, that an empty daemon value is not injected, and that nothing is emitted when both are unset. All existing sandbox-env tests (reserved-name drop, daemon-only-secret drop, network toggle) stay green.just checkpasses.Follow-up (do not do here)
A temporary per-user
SSL_CERT_FILEhotfix in[user.env]is currently live in production and is keeping evie up. Once this merges and the image is rebuilt, those per-user cert lines can be removed; this code fix supersedes them. Not attempted in this PR.The bwrap sandbox does --clearenv and re-adds only an explicit base env allowlist, which never included a CA-certificate path. On a host whose default cert path exists that went unnoticed; in the nix-built Docker image there is no /etc/ssl/certs/ca-certificates.crt and the sandbox binds /nix but not /etc, so pi had no discoverable CA bundle and every provider call failed the TLS handshake ("pi provider error: Connection error."). The bundle itself is readable inside the sandbox via the wholesale /nix ro-bind; pi was simply never told where it is. Forward SSL_CERT_FILE and NIX_SSL_CERT_FILE from the daemon environment into the sandbox base allowlist, but only when set and non-empty, so hosts that provide a working default path behave exactly as before. Both are paths to public root certificates, so they are not gated by the secret guards; those stay intact for everything else.