Backends de bac à sable
Vue d’ensemble des backends
Section intitulée “Vue d’ensemble des backends”| Backend | Valeur | Plateforme | Disponibilité |
|---|---|---|---|
| VM cloisonnée | microvm |
macOS, Linux, Windows (hyperviseur microVM) | Conditionné par la sonde de l’environnement d’exécution microVM; s’applique aux terminaux interactifs — le shell s’exécute dans un rig, et non sur l’hôte |
| Natif | native |
macOS (Seatbelt), Linux et WSL2 (bubblewrap) | Sondé au démarrage; Linux refuse une exécution qui exige des refus d’écriture par glob de nom de fichier, que bubblewrap ne peut pas appliquer |
| Aucun | none |
Tous | La valeur par défaut de l’analyse, la valeur par défaut du terminal et la solution de repli lorsqu’aucun backend n’est disponible ou que --sandbox off est défini |
SandboxBackend.fromName renvoie none pour une valeur stockée nulle ou non reconnue. Une valeur "docker" stockée correspond à native.
microvm est le seul backend doté d’une frontière de noyau — la charge de travail ne s’exécute véritablement pas sur l’hôte. Il n’est jamais une solution de repli silencieuse, dans un sens comme dans l’autre : le demander explicitement sur un hôte incapable de démarrer une VM échoue bruyamment (« j’ai demandé une VM et j’ai obtenu mon ordinateur portable » est la seule dégradation que l’enceinte ne peut pas se permettre), et seul un défaut non spécifié se rabat sur native, avec une ligne de journal qui le dit. Le backend réel de la session est signalé au client et accompagné d’une puce, de sorte qu’un terminal ne peut jamais prétendre être cloisonné alors qu’il s’exécute sur l’hôte. Le cycle de vie, les images et la sortie réseau de la VM elle-même sont traités dans la référence sur les rigs.
Windows n’a aucun bac à sable natif. NativeSandboxAdapter.probe renvoie available: false sur tout hôte qui n’est pas macOS ou Linux/WSL2. Le lancement d’agents sous Windows utilise donc none. Le backend microvm est distinct : il est conditionné par la sonde de l’environnement d’exécution microVM et s’applique aux terminaux interactifs et aux rigs, et non à l’enveloppement de bash sur l’hôte.
Résultats de la sonde
Section intitulée “Résultats de la sonde”C’est la sonde qui conditionne l’application. Elle s’exécute une seule fois, au démarrage du serveur.
| Hôte | available |
Note / indice |
|---|---|---|
| macOS | true |
sandbox-exec (Seatbelt) — isolation par espace de noms, sans frontière de noyau |
Linux ou WSL2 avec bwrap et socat |
true |
bubblewrap — isolation par espace de noms, sans frontière de noyau |
| Linux ou WSL2 auquel il manque l’un des deux outils | false |
requiresInstall: true, avec un indice d’installation nommant les paquets manquants |
| Toute autre plateforme | false |
Le bac à sable natif n’est pas offert sur cette plateforme |
Le serveur consigne le résultat sur une seule ligne de démarrage : agent sandbox ON suivi de la note, no OS-native agent sandbox on this host suivi de l’indice, ou agent sandbox DISABLED by --sandbox off. GET /healthz ne comporte aucun champ de bac à sable.
--sandbox / CC_SERVER_SANDBOX accepte on (par défaut) ou off. Il s’agit d’un retrait, et non d’une activation : on signifie « envelopper lorsque l’hôte offre un backend », jamais « en exiger un ».
Backend natif
Section intitulée “Backend natif”macOS : Seatbelt
Section intitulée “macOS : Seatbelt”Utilise le mécanisme de bac à sable Seatbelt d’Apple (le même système que celui employé par macOS App Sandbox).
Le profil généré est permissif par défaut ((allow default)) et y découpe des refus, parce qu’un profil entièrement fermé par défaut rend un shell interactif inutilisable — les appels dyld, XPC et Mach à énumérer sont trop nombreux. La conséquence pratique est qu’un agent peut encore lire la majeure partie de l’hôte; vos copies de travail enregistrées sont protégées par des refus explicites d’écriture et de renommage, et non par l’invisibilité.
- Lectures du système de fichiers : refusées pour les chemins secrets (
~/.ssh,~/.aws,~/.gnupg,~/.config/gh,~/Library/Keychainset le reste de l’ensemble de refus de lecture) - Écritures du système de fichiers : réinitialisées en refus, puis autorisations explicites par sous-chemin, les chemins à refus obligatoire (fichiers rc du shell,
.git/hooks, configuration de Claude, copies de travail protégées) étant bloqués même à l’intérieur d’une racine accessible en écriture.file-write-unlinkest refusé sur chaque chemin refusé et sur ses ancêtres, de sorte qu’un renommage ne peut pas contourner un refus d’écriture - Processus : refus de
process-execpour les binaires toujours dangereux, plus un blocage de l’exécution de quoi que ce soit depuis un répertoire accessible en écriture - Réseau : limité aux ports du proxy intraprocessus plus le DNS — le bouclage n’est pas autorisé de façon générale et les sockets Unix ne sont pas autorisés. Les proxys appliquent la liste d’autorisation de domaines par session (voir Sortie réseau)
- Configuration : les profils sont générés à chaque lancement à partir du
SandboxSpec
Exigences :
sandbox-exec(/usr/bin/sandbox-exec), présent dans toute installation de macOS — aucun outil supplémentaire requis
Linux : bubblewrap
Section intitulée “Linux : bubblewrap”Utilise bubblewrap (bwrap) pour créer des espaces de noms de montage et de PID.
- Système de fichiers : crée un espace de noms de montage où seuls les chemins liés sont visibles
- Réseau : s’exécute dans un espace de noms réseau non partagé; le trafic atteint les proxys de l’hôte par des ponts de sockets Unix
socat - Processus : isolation par espace de noms de PID
Exigences :
bubblewrapetsocatinstallés (sudo apt-get install bubblewrap socatsur Debian/Ubuntu)- Prise en charge des espaces de noms du noyau (standard sous Linux moderne)
Bubblewrap peut masquer un chemin existant, mais ne peut pas interdire un nouveau fichier .env, *.key ou *.pem à l’intérieur d’une liaison accessible en écriture. La politique de lancement standard exige ces refus par glob de nom de fichier, de sorte que le lancement natif d’agents échoue en mode fermé sous Linux/WSL2 même lorsque la sonde trouve bubblewrap. Il ne s’exécute pas avec une politique silencieusement affaiblie. Un backend doté de règles de nom de fichier au moment de la création est nécessaire pour rétablir le lancement natif sous Linux. La désactivation de l’isolation est un retrait explicite sans confinement, et non un contournement équivalent.
Backend none
Section intitulée “Backend none”Aucune isolation. Le processus s’exécute directement sur l’hôte, avec l’accès au système de fichiers, au réseau et aux processus de celui-ci. ACP et l’outil bash du harnais reçoivent tout de même l’assainissement de l’environnement et la politique de commandes; Claude Code, par l’intermédiaire de NoSandboxAdapter, hérite de l’environnement de l’hôte. C’est sur ce backend que se rabat le lancement d’agents sur un hôte sans backend disponible ou avec --sandbox off, et c’est la valeur par défaut du terminal lorsqu’un client n’en nomme aucun.
Terminal hébergé sur le serveur
Section intitulée “Terminal hébergé sur le serveur”Le terminal est isolé selon ses propres règles, et non par la sonde de lancement. Le defaultBackend de TerminalSessionService est none et cc_server ne le remplace pas, de sorte qu’une session de terminal exécute le shell de l’hôte à moins qu’un client ne demande explicitement native — le panneau de terminal de l’application de bureau ne le fait pas.
Lorsque native est demandé, le shell est enveloppé par SandboxManager sous un profil de terminal fixe : $HOME et le répertoire de travail de la session sont accessibles en écriture, le réseau est ouvert et la lecture de ~/.ssh, ~/.aws, ~/.gnupg, ~/.config/gh et ~/Library/Keychains est refusée. Le jeton de forge en lecture seule et la passerelle de poussée ne s’appliquent pas — ils relèvent du lancement. Si l’enveloppement n’est pas pris en charge, la session échoue plutôt que d’afficher une puce « natif » sur un PTY de shell hôte.
Sortie réseau
Section intitulée “Sortie réseau”Lorsqu’un bac à sable est lancé, l’accès réseau sortant est appliqué par des proxys intraprocessus, et non par des règles de pare-feu du noyau. Sur un hôte sans backend disponible, rien de tout cela ne s’applique et un processus lancé atteint le réseau exactement comme le ferait l’utilisateur du serveur.
- L’environnement d’exécution du bac à sable exécute un proxy HTTP/HTTPS et un proxy SOCKS5 sur
127.0.0.1à l’intérieur du processuscc_server, une paire par session restreinte (http_proxy.dart,socks_proxy.dart). Les exécutions simultanées ne partagent pas une paire. - Les processus isolés reçoivent les variables d’environnement de proxy (
HTTP_PROXY/HTTPS_PROXY→ le proxy HTTP,ALL_PROXY→ le proxy SOCKS;GIT_SSH_COMMANDachemine git par SSH à travers le proxy SOCKS). Sous Linux, l’espace de noms réseau n’est pas partagé, de sorte que les proxys sont la seule sortie possible; sous macOS, le bac à sable partage le bouclage de l’hôte et leur parle directement. - L’hôte cible de chaque connexion est comparé à la liste d’autorisation de domaines de la session; tout le reste est refusé. Deux formes de caractères génériques, chacune avec exactement un
*: un*.example.comen tête correspond à n’importe quel sous-domaine (y comprisa.b.example.com) mais pas au domaine racine lui-même; unbedrock.*.amazonaws.comà étiquette intermédiaire correspond à exactement une étiquette (bedrock.us-east-1.amazonaws.com, et nonbedrock.evil.attacker.amazonaws.com). - La liste d’autorisation est résolue par session à partir de la base de référence établie avec soin (
kBaselineAllowedDomains: fournisseurs de LLM, hébergement Git, registres de paquets), plus les domaines GitHub (kGithubDomains), plusSandboxSpec.egressAllowlist. Le chemin de lancement ne transmet jamais d’entréesegressAllowlistsupplémentaires, de sorte qu’en pratique chaque exécution obtient la base de référence plus GitHub. - Une liste de refus fixe (
kBaselineDeniedDomains: points de terminaison de métadonnées infonuagiques, collecteurs de télémétrie) l’emporte sur toutes les autorisations. networkEnabled: falsedémarre tout de même les proxys par session, mais la liste d’autorisation est vide, de sorte que toute connexion sortante est refusée. Le lancement le règle au démarrage de l’exécution à partir de la règle Accéder au réseau : un refus désactive le réseau, autoriser et demander d’abord le laissent activé.
SandboxSpec
Section intitulée “SandboxSpec”La spécification transmise à SandboxPort.launch :
| Champ | Type | Description |
|---|---|---|
sessionId |
String |
Identifiant de session stable (généralement l’id de l’espace) |
workspaceId |
String |
Id de l’espace de travail propriétaire |
agentId |
String? |
Agent actuellement lié au bac à sable, s’il y en a un |
bindMounts |
List<SandboxBindMount> |
Montages hôte→invité; le bac à sable ne voit que les chemins de l’hôte énumérés ici |
networkEnabled |
bool (valeur par défaut true) |
Réglé au lancement à partir de la règle de sortie réseau (désactivé seulement si elle aboutit à un refus). Lorsqu’il est désactivé, les proxys par session démarrent quand même, mais la liste d’autorisation est vide, de sorte que toute connexion sortante est refusée |
egressAllowlist |
List<String> (valeur par défaut []) |
Domaines de sortie supplémentaires autorisés; les caractères génériques sont pris en charge (*.example.com, plus une forme intermédiaire d’une seule étiquette). Le lancement ne remplit jamais ce champ, de sorte qu’une exécution enveloppée obtient la base de référence établie avec soin plus les domaines GitHub |
guestWorkdir |
String? |
Répertoire de travail par défaut à l’intérieur du bac à sable; chaque appel exec peut le remplacer |
mode |
Mode (valeur par défaut chat) |
Découpe les règles d’écriture du système de fichiers : chat garde les montages par liaison accessibles en écriture; review, plan et orchestrate sont en lecture seule |
protectedPaths |
List<String> (valeur par défaut []) |
Chemins de l’hôte qui ne doivent jamais être accessibles en écriture à l’intérieur du bac à sable, dans quelque mode que ce soit |
runnerStateDirs |
List<String> (valeur par défaut []) |
Répertoires de l’hôte où l’exécuteur conserve son propre état, accessibles en écriture dans tous les modes (un CLAUDE_CONFIG_DIR géré par Control Center est le cas actuel) |
execGrantRoots |
List<String> (valeur par défaut []) |
Arborescences approuvées par l’opérateur qui rouvrent le blocage d’exécution dans les répertoires accessibles en écriture sous macOS. Linux les ignore — bwrap n’a aucun blocage d’exécution de $HOME à rouvrir |
protectedPaths contient les copies de travail d’origine des dépôts enregistrés, résolues à chaque lancement à partir des dépôts de l’espace de travail. Les agents travaillent exclusivement dans des arbres de travail en copie sur écriture propres à chaque conversation, de sorte que les originaux ne doivent jamais être accessibles en écriture depuis l’intérieur du bac à sable — sous macOS, l’autorisation générale d’écriture dans $HOME accordée par Seatbelt les laisserait autrement modifiables par bash. Ils rejoignent l’ensemble de refus d’écriture des secrets dans tous les modes, chat compris.
Chaque chemin de refus de lecture et de refus d’écriture est émis à la fois sous sa forme littérale et sous sa forme résolue par lien symbolique. Le noyau compare une règle de refus au chemin résolu, de sorte qu’une règle écrite pour un chemin symbolique ne se déclenche jamais — et sous macOS, c’est le cas courant plutôt que l’exception, puisque /tmp se résout en /private/tmp et /var/folders/… en /private/var/folders/…. Les entrées contenant * ou ? sont traitées comme des globs et laissées telles quelles; un chemin qui ne se résout pas est conservé tel qu’écrit.
SandboxBindMount
Section intitulée “SandboxBindMount”| Champ | Type | Description |
|---|---|---|
hostPath |
String |
Chemin absolu sur l’hôte |
guestPath |
String |
Chemin à l’intérieur du bac à sable (avec le bac à sable natif, il est égal à hostPath; conservé pour la symétrie des adaptateurs) |
readOnly |
bool (valeur par défaut false) |
Monte en lecture seule lorsque vrai |
SandboxHandle
Section intitulée “SandboxHandle”Renvoyé par SandboxPort.launch :
| Champ | Type | Description |
|---|---|---|
sessionId |
String |
Identifiant de session |
backend |
SandboxBackend |
Le backend en cours d’exécution |
state |
SandboxState |
État du cycle de vie |
error |
Object? |
Défini lorsque state vaut error |
details |
Map<String, Object?> |
Données de suivi internes à l’adaptateur (répertoire de travail, PID, chemin du profil, etc.) |
SandboxState
Section intitulée “SandboxState”| État | Description |
|---|---|
created |
Spécification créée, mais la VM n’a pas encore démarré |
warm |
En cours d’exécution et prêt à exécuter des commandes |
active |
En train d’exécuter une commande |
suspended |
En pause ou avec point de contrôle écrit sur disque pour économiser la RAM |
destroyed |
Démoli; la référence n’est plus valide |
error |
Échec du lancement — voir SandboxHandle.error |
Événements du bac à sable
Section intitulée “Événements du bac à sable”| Type d’événement | Description |
|---|---|
stdout |
Sortie standard du bac à sable |
stderr |
Erreur standard du bac à sable |
exit |
Le processus du bac à sable s’est terminé (porte exitCode) |
starting |
Le bac à sable démarre |
ready |
Le bac à sable est prêt à accepter des appels exec |
killed |
Processus tué par l’hôte (manque de mémoire, délai dépassé, arrêt manuel) |
violation |
Une politique du bac à sable a été violée (porte une SandboxViolation) |
SandboxViolation
Section intitulée “SandboxViolation”| Champ | Type | Description |
|---|---|---|
action |
String |
Le verbe refusé (p. ex. file-read*, network-outbound) |
target |
String |
Chemin ou hôte visé par l’opération refusée |
raw |
String? |
Ligne de journal brute, utile pour le débogage |
Voir aussi
Section intitulée “Voir aussi”- Bac à sable et sécurité
- Politiques de bac à sable
- Garde-fous
- CLI cc_server : l’indicateur
--sandbox