fix(lark): keep CLI lock directory writable in sandboxes - #4701
fix(lark): keep CLI lock directory writable in sandboxes#4701Creeper998 wants to merge 1 commit into
Conversation
willem-bd
left a comment
There was a problem hiding this comment.
Reviewed the lock-directory fix end to end across AIO local sandbox, remote Pattern A (init container), and broker Pattern B (sidecar). The credential-tree, mount, allowlist, MAX_EXTRA_MOUNTS, and Gateway/provisioner contract changes are all consistent; config stays read-only while the empty config/locks subdir is over-mounted writable, and the sandbox trust-boundary docs in README.md / backend/AGENTS.md are updated to match. Test coverage spans all three modes.
One test-robustness suggestion inline (the nested over-mount order isn't asserted). Otherwise this looks good.
| assert provisioner_module.LARK_BROKER_SIDECAR_CONFIG_PATH in sidecar_paths | ||
| assert provisioner_module.LARK_BROKER_SIDECAR_LOCKS_PATH in sidecar_paths | ||
| assert provisioner_module.LARK_BROKER_SIDECAR_DATA_PATH in sidecar_paths | ||
| sidecar_mounts = {m.mount_path: m for m in sidecar.volume_mounts} |
There was a problem hiding this comment.
Suggestion (test robustness): this dict comprehension (and the matching sandbox_mounts = {m.mount_path: m ...} in test_runtime_extra_mount_dropped_when_init_container_enabled) discards the volume_mounts list order.
The nested over-mount design — writable config/locks layered on top of read-only config — relies on the parent appearing before the child in the volumeMounts list that kubelet/Docker receive. That ordering comes from the explicit tuple in _build_lark_cli_broker_sidecars (config, locks, data) and from _get_lark_cli_runtime_mounts on the Gateway side. Most runtimes sort mounts by path depth, so this is defense-in-depth rather than a live bug, but the current read-only assertions would still pass if someone reordered the tuple and silently broke the over-mount at runtime.
A cheap order assertion here would document the invariant and catch that, e.g.:
mount_order = [m.mount_path for m in sidecar.volume_mounts]
assert mount_order.index(provisioner_module.LARK_BROKER_SIDECAR_CONFIG_PATH) \
< mount_order.index(provisioner_module.LARK_BROKER_SIDECAR_LOCKS_PATH)
Fixes #4700
Why
The managed Lark/Feishu integration fails inside sandboxes when
lark-clicreates itsconfig/lockscoordination directory. DeerFlow deliberately mounts the credential-bearing config root read-only, so API commands currently stop with a read-only filesystem error even after a successful connection.This keeps the app secret protected from sandbox writes while restoring the CLI command surface.
What changed
config/locksdirectory with owner-only permissions./mnt/integrations/lark-cli/configread-only and over-mount only itslockschild writable.Surface area
frontend/backend/applanggraph.json, or prompt changedocker/or sandboxed executionskills/backend/pyproject.tomlorfrontend/package.jsonScreenshots / Recording
Not applicable; there is no UI change.
Bug fix verification
backend/tests/test_aio_sandbox_provider.py,backend/tests/test_lark_cli_integration.py,backend/tests/test_provisioner_mount_contract.py, andbackend/tests/test_provisioner_pvc_volumes.py.upstream/mainbecause the lock directory/mount and Provisioner contract did not exist, then passed after the implementation.Validation
pytest tests/test_aio_sandbox_provider.py tests/test_lark_cli_integration.py tests/test_provisioner_mount_contract.py tests/test_provisioner_pvc_volumes.py tests/test_lark_broker.py -q— 191 passed.python -m py_compile docker/provisioner/app.py— passed.example.comand GitHub) as private addresses under the SSRF guard; none touches the Lark/sandbox code changed here.AI assistance
Tool(s) used: Codex
How you used it: Diagnosed the runtime failure, wrote red-first regression tests, implemented the local/Provisioner/broker fix, reviewed the diff, and ran the validation above.