Écrits

La machine qui exécute les agents ne détient aucun secret

La partie du serveur exécutant le code généré par les modèles est strictement isolée de la base de données et des clés de déchiffrement. Un agent s’échappant de son conteneur ne trouverait qu’une copie de travail sans aucun identifiant sensible.

Un agent parvenant à s’échapper de son conteneur ne doit rien trouver qui vaille la peine d’être dérobé. Cela dépend de ce que la machine contient physiquement. Nous avons scindé l’architecture en deux : la moitié exécutant les agents ne possède aucun accès à la base de données et aucune clé de déchiffrement.

A locked boundary. The database and the key stand on the control side; the sandbox holds only agents and a working tree.controlsandboxdatabasekeynever crosses/workspace
Tout ce qui peut déchiffrer des données réside d’un côté. De l’autre ne se trouvent que les agents et le dossier de travail.

Deux rôles distincts pour un cloisonnement étanche

La partie authentification gère la base de données (comptes, canvas, jetons chiffrés) sur un réseau privé sans port public. La partie exécution fait tourner du code généré par des modèles et doit rester isolée.

Toutes les vérifications d’accès sont isolées dans des fonctions pures ne lisant ni base de données ni horloge système :

export function checkFrame(access: ConnectionAccess, frame: ClientMsg["type"]): AccessCheck

Réduction des privilèges aux interfaces

Les méthodes exposées à la machine d’exécution sont strictement réduites :

L’obtention de l’identité renvoie uniquement un nom et un email, sans jamais transmettre le hachage de mot de passe Argon2id présent dans la ligne utilisateur.

La récupération des identifiants est contextualisée au canvas actif et oubliée immédiatement après l’opération de synchronisation git.

La restriction stricte des données est une propriété de sécurité fondamentale.

Architecture par rôles

Plutôt que deux binaires divergents, l’application utilise un binaire unique paramétré par des rôles vérifiés à la compilation et aux tests :

export const ROLES = ["all", "control", "sandbox"] as const;

export function needsDatabase(role: Role): boolean {
  return role !== "sandbox";
}

export function servesBrowsers(role: Role): boolean {
  return role !== "sandbox";
}

Le rôle sandbox fonctionne sans base de données et refuse toute connexion directe depuis un navigateur, n’acceptant que les connexions relayées par le plan de contrôle.

L’isolation des machines est expliquée dans la machine cloud où tournent les agents, et nos retours d’expérience dans résultats des tests en sandbox cloud.

Réponses directes

Où sont stockés mes identifiants GitHub lorsqu’un agent les utilise ?

Chiffrés, côté plan de contrôle. La machine exécutant les agents ne dispose ni de base de données ni de clé de déchiffrement.

À quoi peut accéder un agent qui s’échapperait de son conteneur ?

Uniquement au dossier de travail du projet et aux connexions réseau autorisées. Aucun accès à la table des comptes ou aux clés maîtresses.

Cette approche est-elle plus sûre qu’un conteneur renforcé ?

Elle est complémentaire : le durcissement limite le risque d’évasion, tandis que l’isolation des secrets supprime tout intérêt à une évasion en ne laissant rien de sensible sur la machine.