ó
    |¤j›  ã                  ó´   • % S r SSKJr  SSKrSSKrSSKrSSKJr  SrSr	SS jr
SS jrSqS	\S
'   SS jrSS jrSS jrSS jr S       SS jjrSS jrg)uŒ  Optional OS-level sandbox for shell command execution (roadmap P0-L3).

Defense-in-depth layered on top of the permission engine and the
dangerous-command blocklist. When enabled *and* a sandbox backend is
present, ``run_command`` executes commands inside an OS sandbox that
confines filesystem writes to the current workspace.

Design constraints (see the roadmap):

* **Opt-in** â€” disabled by default (``sandbox = false`` in config). Local
  users already get the permission prompts + blocklist; the sandbox is an
  extra layer for ``auto_approve`` / untrusted-skill scenarios.
* **Graceful degradation** â€” if no backend is detected the command runs
  normally under the existing permission layer. The sandbox never blocks
  startup and never raises out of ``run_command``.
* **Best-effort boundary** â€” this raises the cost of a destructive or
  runaway command; it is *not* a hardened security boundary. Treat it as
  confinement, not isolation.

Backends:

* macOS: Seatbelt via ``sandbox-exec`` (built into macOS). The profile
  keeps the default-allow policy but denies filesystem writes outside the
  workspace and temp areas, so process execution, reads, and networking are
  unaffected and normal dev commands keep working.
* Linux: bubblewrap (``bwrap``) when installed. bwrap confines by
  remapping the filesystem, so it is more restrictive; commands that write
  outside the workspace/temp will fail.
é    )ÚannotationsN)ÚOptionalÚseatbeltÚbwrapc                 ó   • [         R                  S:X  a#  [        R                  " S5      (       a  [        $ S$ [         R                  R                  S5      (       a#  [        R                  " S5      (       a  [        $ S$ g)uô   Return the available sandbox backend name, or ``None``.

macOS prefers ``sandbox-exec`` (Seatbelt); Linux prefers ``bwrap``.
Windows has no supported backend. Detection only checks for the tool's
presence on PATH â€” it never starts a sandbox.
Údarwinúsandbox-execNÚlinuxr   )ÚsysÚplatformÚshutilÚwhichÚSEATBELTÚ
startswithÚBWRAP© ó    Ú¤C:\Users\johnn\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.13_qbz5n2kfra8p0\LocalCache\local-packages\Python313\site-packages\dashscope/acli/sandbox.pyÚdetect_backendr   ,   sZ   € ô ‡|�|�xÓÜ!Ÿ<š<¨×7Ñ7ŒxÐA¸TÐAÜ
‡|�|×Ñ˜w×'Ñ'ÜŸš W×-Ñ-ŒuÐ7°4Ð7Ør   c                 ó   • [        5       SL$ )z8True when a sandbox backend is detected on this machine.N)r   r   r   r   Ú	availabler   :   s   € äÓ 4Ð'Ð'r   úOptional[bool]Ú_enabled_overridec                ó   • U q g)zCOverride sandbox enablement; pass ``None`` to use the config value.N)r   )Úvalues    r   Úset_enabledr   D   s
   € ð Ñr   c                 ó¢   • [         b  [        [         5      $  SSKJn   [        U R	                  5       R
                  5      $ ! [         a     gf = f)zçWhether sandboxing is enabled (config-driven, overridable).

Reads ``sandbox`` from the loaded config on each call so config
changes take effect; degrades to ``False`` on any error so the
sandbox can never break command execution.
r   ©ÚConfigF)r   ÚboolÚdashscope.acli.configr   ÚloadÚsandboxÚ	Exceptionr   s    r   Ú
is_enabledr%   J   sG   € ô Ñ$ÜÔ%Ó&Ð&ðÝ0ä�F—K‘K“M×)Ñ)Ó*Ð*øÜó Ùðús   ˜(A Á
AÁAc           
     ó`   • U R                  SS5      nSR                  SSSSU S3S	S
SS/5      $ )a6  Build a macOS Seatbelt profile confining writes to the workspace.

The base policy stays default-allow; only filesystem writes are
denied, then re-allowed for the workspace and standard temp/cache
locations. Reads, process execution, and networking are untouched so
ordinary development commands keep working.
Ú"z\"Ú
z(version 1)z(allow default)z(deny file-write*)z(allow file-write* (subpath "z"))z,(allow file-write* (subpath "/private/tmp"))z$(allow file-write* (subpath "/tmp"))z4(allow file-write* (subpath "/private/var/folders"))z)(allow file-write* (literal "/dev/null")))ÚreplaceÚjoin)ÚcwdÚsafe_cwds     r   Úseatbelt_profiler-   [   sK   € ð �{‰{˜3 Ó&€HØ�9‰9àØØ Ø+¨H¨:°SÐ9Ø:Ø2ØBØ7ð		
óð r   c                ó*   • SSSSSUUSSSSS	S
SUSSU /$ )u  Build a ``bwrap`` argv that runs *command* with a read-only root.

The whole filesystem is bound read-only, then the workspace and a
fresh ``/tmp`` are made writable. Commands that need to write elsewhere
(e.g. package caches) will fail â€” this is the intended confinement.
r   z	--ro-bindÚ/z--bindz--tmpfsú/tmpz--procz/procz--devz/devz--chdirú/bin/shú-cr   )Úcommandr+   s     r   Ú
bwrap_argvr4   r   sD   € ð 	ØØØØØØØØØØØØØØØØØð%ð r   c                óŠ   • U=(       d
    [        5       nU[        :X  a  SS[        U5      SSU /$ U[        :X  a  [	        X5      $ g)uÙ   Return an argv to run *command* inside the sandbox, or ``None``.

``None`` means "no sandbox available â€” run the command normally".
``backend`` may be passed explicitly (mainly for tests); otherwise it
is detected.
r	   z-pr1   r2   N)r   r   r-   r   r4   )r3   r+   Úbackends      r   Ú
build_argvr7   �   sR   € ð ×)œÓ)€GØ”(ÓàØÜ˜SÓ!ØØØð
ð 	
ð ”%ÓÜ˜'Ó'Ð'Ør   c                óä   •  [         R                  R                  U 5      nUSS4 H1  nX#:X  d)  UR                  U[         R                  -   5      (       d  M1    g   g! [        [        4 a     gf = f)z‚True when *path* is inside the writable workspace or temp areas.

Informational helper (e.g. for messages); not a security check.
Fr0   z/private/tmpT)ÚosÚpathÚabspathÚOSErrorÚ
ValueErrorr   Úsep)r:   r+   Úabs_pathÚbases       r   Úis_sandboxed_pathrA   ©   sk   € ð
Ü—7‘7—?‘? 4Ó(ˆð �f˜nÓ-ˆØÓ˜x×2Ñ2°4¼"¿&¹&±=×AÓAÙñ .ð øô ”ZÐ ó Ùðús   ‚A ÁA/Á.A/)ÚreturnúOptional[str])rB   r    )r   r   rB   ÚNone)r+   ÚstrrB   rE   )r3   rE   r+   rE   rB   z	list[str])N)r3   rE   r+   rE   r6   rC   rB   zOptional[list[str]])r:   rE   r+   rE   rB   r    )Ú__doc__Ú
__future__r   r9   r   r   Útypingr   r   r   r   r   r   Ú__annotations__r   r%   r-   r4   r7   rA   r   r   r   Ú<module>rJ      s†   ðòõ< #ã 	Û Û 
Ý ð €Ø€ôô(ð %)Ð �>Ó (ôôô"ô.ð@ "ðØðà	ðð ðð õ	õ4r   