Isolation d’un profil par tâche pour un agent
Attribuez un profil par tâche d’agent, prouvez la séparation du stockage et comprenez les limites d’une identité réseau partagée.
BotBrowser Team
Vous voulez la documentation structurée pour Identité ?
Cet article fait partie de la bibliothèque éditoriale. Pour les étapes de configuration, la référence et les mises à jour continues, passez directement à la section docs.
Un agent qui traite plusieurs tâches a besoin d’une attribution explicite de profil avant chaque démarrage de navigateur. BotBrowser peut démarrer avec un profil fourni par l’opérateur et exposer le résultat de la page, mais il ne planifie pas les tâches, ne choisit pas l’attribution et ne garantit pas le classement d’une session par un détecteur. L’opérateur possède le lien entre taskId et profileId.
TL;DR
- Créez l’attribution tâche-profil avant le lancement ; un nouvel essai ne doit pas hériter silencieusement du profil précédent.
- Donnez à chaque profil sa propre partition de stockage et une politique réseau approuvée. Un profil partagé peut transporter cookies, stockage local, permissions et la même route configurée vers la tâche suivante.
- Utilisez le fixture exécutable pour prouver la séparation avec deux répertoires persistants, puis exécutez volontairement la variante à répertoire partagé.
- Un fixture réussi prouve ce que la page peut lire. Il ne prouve ni le verdict d’un détecteur, ni le processus qui a lancé le navigateur, ni le respect des limites d’une plateforme tierce.
Sommaire
- Pourquoi une boucle d’agent a besoin d’une frontière de profil
- Attribuer le profil avant le lancement
- Exécuter un fixture de séparation du stockage
- Vérifier l’identité réseau séparément
- Fermer, réessayer et auditer chaque attribution
- Interprétation et limites
- Conclusion pratique
Pourquoi une boucle d’agent a besoin d’une frontière de profil
Une boucle d’agent transforme un workflow de navigateur en une suite de travaux indépendants. La tâche A peut s’authentifier sur un tenant de test autorisé, tandis que la tâche B doit commencer sans état de ce tenant. Si les deux lancements utilisent un profil persistant, la seconde tâche peut hériter de cookies, du stockage local, de permissions, du cache et d’autres états avant sa première action.
Playwright décrit un BrowserContext comme une session isolée avec ses propres cookies et son stockage. Cette frontière est utile, mais elle ne remplace pas le choix d’un profil BotBrowser. Un profil est une entrée de lancement et peut porter une configuration qui dépasse le stockage de page. Le guide de gestion des profils traite de propriété, de versions, de rétention et de cycle de vie ; un ordonnanceur d’agent applique ces principes lors de l’attribution des profils aux tâches.
L’article voisin sur l’isolation de navigateur multi-compte vise les workflows humains qui séparent les comptes. Une boucle d’agent ajoute le problème de l’attribution : chaque tâche, nouvel essai et redémarrage de worker doit recevoir un profil choisi. Le guide du navigateur headless pour agents IA traite du passage agent-navigateur et des preuves de processus, pas de la séparation d’identité entre deux exécutions.
Attribuer le profil avant le lancement
Conservez un enregistrement d’attribution que le lanceur peut valider sans ouvrir le paquet protégé. Il contient l’identifiant de tâche, l’identifiant du profil, le répertoire de stockage, la référence de politique réseau, le responsable et l’état :
{
"taskId": "tenant-a-checkout-042",
"profileId": "profile-us-east-07",
"storageDir": "/var/lib/agent-sessions/profile-us-east-07",
"networkPolicyRef": "egress-us-east-07",
"state": "approved"
}
Résolvez cet enregistrement avant chromium.launchPersistentContext() ou le lanceur BotBrowser équivalent. Refusez une attribution absente, retirée ou déjà louée. Un nouvel essai doit référencer son propre événement d’attribution, et non réutiliser le répertoire laissé par le worker.
Avec Playwright, un contexte persistant donne à un processus de navigateur un répertoire de données. Pour un lancement BotBrowser, l’opérateur fournit aussi l’argument de profil et les paramètres réseau approuvés. Gardez ces valeurs ensemble et ne journalisez que des identifiants stables, jamais le contenu du profil ou les secrets de proxy.
L’attribution du profil est un contrôle opérationnel, pas une promesse sur la décision d’un site. Elle rend la frontière prévue vérifiable. Elle ne rend pas deux comptes sans lien acceptables, ne permet pas d’ignorer une limite de plateforme et ne garantit pas l’acceptation de la session par un tiers.
Exécuter un fixture de séparation du stockage
Le fixture Node.js suivant utilise Chromium fourni par Playwright et un serveur HTTP local. Il écrit un cookie et une valeur localStorage inoffensifs dans la tâche A, lit ces valeurs dans la tâche B et indique si la seconde tâche les a hérités. La première exécution donne un répertoire différent à chaque tâche ; la seconde réutilise volontairement un répertoire pour rendre la fuite visible.
// save as profile-isolation-fixture.mjs
import { chromium } from 'playwright';
import { createServer } from 'node:http';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
const server = createServer((request, response) => {
response.setHeader('Content-Type', 'text/html');
response.end('<!doctype html><title>profile fixture</title><p data-fixture="profile-isolation">owned fixture</p>');
});
await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
const port = server.address().port;
const origin = `http://127.0.0.1:${port}`;
async function runTask(taskId, storageDir, writeState) {
const context = await chromium.launchPersistentContext(storageDir, { headless: true });
const page = await context.newPage();
await page.goto(origin);
if (writeState) {
await page.context().addCookies([{ name: 'task_marker', value: taskId, url: origin }]);
await page.evaluate(value => localStorage.setItem('task_marker', value), taskId);
}
const observed = {
cookie: (await context.cookies()).find(cookie => cookie.name === 'task_marker')?.value ?? null,
localStorage: await page.evaluate(() => localStorage.getItem('task_marker')),
};
await context.close();
return observed;
}
const root = await mkdtemp(join(tmpdir(), 'agent-profile-fixture-'));
const separateA = await runTask('task-a', join(root, 'profile-a'), true);
const separateB = await runTask('task-b', join(root, 'profile-b'), false);
console.log(JSON.stringify({ case: 'separate', taskA: separateA, taskB: separateB }));
const sharedA = await runTask('task-a', join(root, 'shared-profile'), true);
const sharedB = await runTask('task-b', join(root, 'shared-profile'), false);
console.log(JSON.stringify({ case: 'shared', taskA: sharedA, taskB: sharedB }));
await rm(root, { recursive: true, force: true });
server.close();
Lancez node profile-isolation-fixture.mjs. La forme attendue est :
{"case":"separate","taskA":{"cookie":"task-a","localStorage":"task-a"},"taskB":{"cookie":null,"localStorage":null}}
{"case":"shared","taskA":{"cookie":"task-a","localStorage":"task-a"},"taskB":{"cookie":"task-a","localStorage":"task-a"}}
Le cas séparé établit une frontière de stockage visible par la page : la tâche B ne lit pas le marqueur de la tâche A. Le cas partagé est le fixture d’échec ; les deux valeurs montrent que la seconde exécution a ouvert le même stockage persistant. Il s’agit d’un exemple exécutable localement, pas d’une observation d’une exécution BotBrowser.
Le fixture utilise volontairement une origine locale et des données synthétiques. Il n’enregistre pas d’identifiants, ne visite pas de service tiers et ne prétend pas qu’une page puisse inspecter chaque réglage du navigateur. Pour une vérification de production, gardez la même comparaison, utilisez un endpoint en lecture seule approuvé et conservez l’ID d’attribution avec le résultat.
Ce que le fixture vérifie et omet
Le but est de rendre visible une fuite avec des valeurs sans signification métier. Le cookie est limité à l’origine locale et localStorage est écrit par la page. Comme les valeurs sont lues après un nouveau lancement, un résultat non nul dans la tâche B provient du répertoire persistant plutôt que d’une variable du processus Node.js. Le nettoyage supprime les répertoires temporaires afin que l’exécution suivante commence dans un état connu.
Le fixture ne teste pas le cache, les service workers, les permissions, IndexedDB, les téléchargements ou les extensions. Ces surfaces peuvent compter dans une charge de production et méritent un fixture approuvé séparé lorsqu’elles font partie de la frontière d’identité. Ajoutez un marqueur nommé à la fois, notez la valeur vide attendue pour une nouvelle tâche et restez en lecture seule vis-à-vis de tout service externe.
Le fixture ne choisit pas non plus de profil BotBrowser. Un lanceur de production peut envelopper la même fonction avec un argument --bot-profile résolu et un répertoire attribué. Gardez cette enveloppe hors du code de page afin de ne pas confondre l’observation avec une preuve de la ligne de commande. La configuration Playwright de BotBrowser documente l’intégration ; la sélection du paquet et l’attribution restent celles de l’opérateur.
Rendre le résultat attendu vérifiable par machine
Ne demandez pas à une personne de comparer deux lignes JSON. Le planificateur peut échouer si une tâche neuve voit un marqueur, ou si le cas partagé ne le voit pas :
function requireValue(value, expected, label) {
if (value !== expected) throw new Error(`${label}: expected ${expected}, got ${value}`);
}
requireValue(separateB.cookie, null, 'separate cookie');
requireValue(separateB.localStorage, null, 'separate localStorage');
requireValue(sharedB.cookie, 'task-a', 'shared cookie');
requireValue(sharedB.localStorage, 'task-a', 'shared localStorage');
Gardez cette assertion près du résultat du fixture, et non dans une vérification de santé générale. Une vérification qui confirme seulement le chargement d’une page peut réussir alors que le mauvais stockage est attaché. En cas d’échec, incluez taskId, profileId, l’étiquette du chemin de stockage, la version du navigateur et le résultat du fixture dans l’enregistrement restreint. Ne placez jamais de cookie réel ou de secret proxy dans un journal partagé.
Vérifier l’identité réseau séparément
La séparation du stockage ne sépare pas automatiquement l’identité réseau. Associez chaque profil à une politique réseau et une région approuvées, puis vérifiez la route par un endpoint contrôlé par l’opérateur qui renvoie l’adresse publique et la région de la requête. Enregistrez le résultat avec profileId ; ne l’inférez pas des cookies ou d’un chargement réussi.
Si l’opérateur attribue la même référence de politique réseau à deux tâches, elles utilisent le proxy et la route configurés ; la réutilisation d’un profil ne prouve pas à elle seule qu’elles partagent la route. Le guide de configuration proxy de BotBrowser documente les entrées distinctes de lancement et de routage. C’est une vérification de configuration, pas un verdict de détecteur. Un répertoire différent ne transforme pas une route configurée en deux routes.
| Surface | Vérification | Ce que cela établit | Ce que cela n’établit pas seule |
|---|---|---|---|
| Stockage | Cookie task_marker et localStorage | L’état visible par la page est séparé | L’exécutable, le paquet de profil ou l’IP publique |
| Réseau | Endpoint d’écho de l’opérateur | La requête a utilisé la route enregistrée à ce moment | La classification d’un tiers ou la stabilité future |
| Lancement | Commande masquée et attribution | L’opérateur a fourni l’entrée de profil prévue | Que tous les signaux de page correspondent |
La documentation BotBrowser de l’empreinte par contexte décrit les entrées d’identité liées au contexte, et la documentation des profils couvre le cycle de vie et la propriété. Utilisez ces références pour définir l’attribution approuvée. Le guide du navigateur headless pour agents IA explique pourquoi résultat de page et preuve de processus doivent rester séparés ; appliquez la même distinction à la revue réseau.
La réponse de l’endpoint doit porter une heure et une référence d’attribution. L’adresse publique et la région peuvent changer après une rotation, un basculement d’infrastructure ou une nouvelle politique. Considérez le résultat comme une mesure de cette requête, et non comme une propriété permanente du profil. Si une tâche exige une région stable, le planificateur doit refuser une route hors politique avant d’ouvrir la page et fermer la session lorsque la route devient indisponible.
Ne remplacez pas le contrôle de route par une supposition côté navigateur. navigator.language, un fuseau horaire ou un résultat de permission de géolocalisation décrit un réglage ou une permission ; aucun ne désigne seul le chemin réseau public. Un endpoint contrôlé par l’organisation du planificateur peut associer la réponse à l’attribution sans demander à un tiers de classer la session. Gardez sa réponse minimale, masquez-la dans les rapports larges et conservez l’enregistrement complet pendant la durée approuvée.
Fermer, réessayer et auditer chaque attribution
L’isolation dépend du cycle de vie autant que de la commande de lancement. Fermez une tâche dans cet ordre : cessez d’accepter du travail, laissez la page atteindre un état contrôlé, collectez le résultat, fermez le contexte et marquez le sort du stockage. Le planificateur ne doit louer le worker qu’ensuite. Un processus qui écrit encore des cookies lors de la réattribution peut créer une fuite apparemment aléatoire.
Utilisez un événement d’attribution immuable par tentative. Un nouvel essai reçoit un nouvel événement avec une raison comme navigation-timeout, fixture-mismatch ou route-unavailable. Conservez l’événement précédent avec son résultat au lieu d’écraser son profileId. Cela permet de décider si l’échec appartient à l’application, au lanceur ou au paquet.
| Contrôle avant lancement | Refuser lorsque | Pourquoi |
|---|---|---|
| État du profil | Absent, retired ou non approuvé | Empêche un travail avec une identité non révisée |
| Bail du stockage | Répertoire actif pour une autre attribution | Évite les écritures concurrentes et l’état croisé |
| Politique réseau | Référence absente ou région incorrecte | Rend la propriété de route explicite |
| Couple navigateur | Version différente du registre approuvé | Évite un couple non révisé |
| Fermeture précédente | Propriétaire précédent non fermé proprement | Empêche la réutilisation d’un répertoire sale |
Quand un contrôle refuse le lancement, renvoyez une raison courte à la file et le détail au canal restreint. “Le bail de stockage est actif” est exploitable ; vider un paquet ou une ligne de commande complète dans un journal partagé ne l’est pas. La gestion des profils décrit les états de propriété et de retrait nécessaires à cet audit.
Lors de la revue, comparez trois enregistrements : événement d’attribution, résultat visible du fixture et preuve de lancement ou de route détenue par l’opérateur. Ils doivent s’accorder sur la tâche et la fenêtre temporelle, mais répondent à des questions distinctes. Un cookie identique ne prouve pas une route identique ; une route identique ne prouve pas le profil ouvert ; une ligne de commande identique ne prouve pas l’origine chargée.
Pour un worker de longue durée, programmez un redémarrage propre à une frontière définie par la politique au lieu de conserver une attribution indéfiniment. Le redémarrage ne remplace pas la séparation, mais peut révéler les problèmes de fermeture cachés dans un processus unique. Notez s’il était prévu, quel profil a été libéré et si la tâche suivante a reçu un répertoire neuf ou un répertoire persistant encore approuvé.
Le même enregistrement aide lors d’un incident. Si un tenant voit la bannière d’une tâche précédente, comparez d’abord les événements et étiquettes de stockage, puis inspectez le résultat du fixture du worker concerné. Si un seul worker affiche le marqueur, isolez son répertoire et arrêtez les nouvelles tâches pendant la vérification de fermeture. Si tous l’affichent, examinez le mappage du planificateur et le volume partagé avant de modifier le code de page.
Interprétation et limites
Considérez une comparaison propre comme un résultat d’acceptation étroit. Elle indique que ce fixture, sur cette machine, a observé les valeurs de stockage attendues et, si elle a été vérifiée séparément, qu’un endpoint contrôlé par l’opérateur a renvoyé le résultat enregistré. Elle ne dit pas qu’un site acceptera la session, qu’un navigateur est indiscernable d’un autre ou qu’un détecteur donnera un verdict précis.
Analysez un échec dans sa couche propriétaire. Un marqueur non nul dans le cas séparé pointe vers le répertoire, la fermeture ou l’attribution. Un changement réseau pointe vers la politique, le proxy ou l’interprétation de l’endpoint. Un lanceur différent est une preuve de processus ; il ne se corrige pas en demandant à l’agent d’inspecter le JavaScript de la page.
N’utilisez pas des profils par tâche pour ignorer les limites de compte ou les conditions d’une plateforme. L’isolation convient aux tenants autorisés, aux cas de test et aux frontières de confidentialité. L’opérateur reste responsable des identifiants, du consentement, de la rétention, des limites de débit et des règles du service.
FAQ
Un BrowserContext Playwright suffit-il pour deux tâches d’agent ?
Seulement si les contextes sont créés et fermés par une politique d’attribution explicite. Un contexte sépare cookies et stockage, mais ne remplace pas la décision du profil BotBrowser, de la politique réseau et du responsable de chaque tâche.
Le fixture prouve-t-il que deux profils BotBrowser ont été lancés ?
Non. Il prouve uniquement les valeurs de stockage visibles par la page locale. Confirmez l’exécutable, l’argument de profil masqué et l’enregistrement d’attribution avec la preuve de processus de l’opérateur.
Des profils séparés garantissent-ils un verdict de détecteur ?
Non. La séparation retire une classe de partage d’état accidentel. Les sites combinent de nombreux signaux, changent leurs règles et peuvent classer une session pour d’autres raisons.
Que doit faire un nouvel essai après un échec ?
Fermez l’ancien contexte, conservez son identifiant et son résultat, puis obtenez une nouvelle attribution approuvée par la politique du workflow. N’héritez pas du répertoire laissé par un worker simplement parce qu’il est disponible.
Sources
- API BrowserType de Playwright
- Contextes de navigateur Playwright
- Configuration Playwright de BotBrowser
- Gestion des profils BotBrowser
- Empreinte par contexte BotBrowser
- Configuration proxy BotBrowser
Conclusion pratique
Attribuez profileId, le stockage et la politique réseau avant chaque tâche d’agent. Prouvez la frontière avec deux répertoires et le cas d’échec volontaire du répertoire partagé, puis vérifiez le réseau par un endpoint contrôlé par l’opérateur. Gardez distinctes les observations de page, les preuves de lancement et la classification tierce. L’isolation d’un profil par tâche devient ainsi vérifiable sans promettre un verdict de détecteur ni ignorer les règles d’une plateforme.
Cet article fait partie du guide : Surfaces d’identité du navigateur : vue de cohérence pratique
Articles Connexes
Configurer browser-use avec un navigateur contrôlé
IdentitéIsolation multi-comptes du navigateur : réglages indépendants
IdentitéGestion multi-comptes des réseaux sociaux avec isolation du navigateur
DémarrageNavigateur headless pour agents IA : lancement et limites des outils
DémarrageGestion cohérente des profils de navigateur
IdentitéPartitionnement du stockage du navigateur et confidentialité
Exécutez la même vérification dans BotBrowser
Chargez un profil, gardez dans le navigateur les signaux que vous venez de lire, puis confirmez le résultat sur votre propre machine avant le déploiement.