Sémantique d'exécution, contraintes et sécurité
Dernière mise à jour : 21 juillet 2026
Cette page résume comment un Script se comporte à l'exécution (ordre, transactions, erreurs, verrouillage), à quelles contraintes statiques il est soumis à l'enregistrement et son modèle de sécurité. Pour la syntaxe, consultez le Catalogue des statements et les Expressions de valeur ; pour les combinaisons concrètes, consultez le Cookbook.
Ordre et mode d'exécution
- Les
statementss'exécutent séquentiellement de haut en bas. Lorsque l'exécution atteint unReturn, elle se termine à ce point. - Sync s'exécute sur le chemin qui traite la requête ; Async s'exécute en arrière-plan. Ce n'est qu'une distinction de l'endroit où a lieu l'exécution ; dans les deux cas, le résultat est la valeur de
Return(pour la forme de la réponse de l'appel, voir Requête et réponse dans l'aperçu de Script et Modes d'exécution). - De la capacité (capability) au mode : si l'arbre des statements contient l'un de
ExternalIo(un appel externeHttp),MediaIngest(ingestion de fichier Media ;{ source, encoding }sousfields.file; commun à url et base64) ouLongRunning(un Loop volumineux, etc.), alorsexecutionModeest forcé àAsync. Ces trois-là sont des capacités distinctes et, dans les Contraintes statiques plus bas, elles comptent pour des limites différentes.
Sémantique d'exécution
Guard (conditions préalables)
Il n'existe pas de statement guard dédié. On l'exprime avec If et then:[Return]. En cas de violation de la condition, il renvoie un résultat et n'exécute pas les statements suivants (un Script sans guard est bien entendu également possible).
{ "type": "If", "condition": { "<": [ "{ /wallet/fields/balance/en-US }", "{ /payload/fields/cost }" ] },
"then": [ { "type": "Return", "value": { "ok": false, "reason": "insufficient credit" }, "statusCode": 402 } ] }Sans transaction et compensation best-effort
Un Script n'est pas une transaction. En cas d'échec, le moteur tente de compenser (compensation) le travail effectué jusque-là et renvoie la cause de l'erreur, mais avec les limites suivantes (assumées par conception).
- Annuler une suppression crée un nouveau
sys.id, de sorte que les références qui pointaient dessus se brisent (annuler une création est facile ; une modification nécessite une before-image). - Les effets externes (
Http) sont irréversibles (un appel déjà parti, ainsi que sa facturation, ne peuvent pas être annulés). - En cas de plantage du processus, un état non compensé (un orphan) peut subsister.
Si vous avez besoin d'une véritable atomicité, écrivez la compensation dans le Script vous-même ou placez les opérations irréversibles (les appels externes, etc.) tout à la fin. L'ordre le plus dangereux est celui qui « s'enchaîne jusqu'au bout mais ne peut pas être annulé, tout en paraissant sûr ».
Verrouillage optimiste
La contention d'update/patch se maîtrise avec le version de ResourceUpdate et ResourcePatch. Si l'on fournit version (une expression de valeur, Int), la mise à jour n'a lieu que si elle correspond au sys.version actuel de la cible ; une non-correspondance avorte avec une erreur de conflit de version (gérable localement avec Try/catch). Si on l'omet, c'est du last-write-wins sans vérification. En général, on lit d'abord avec ResourceRead ou ResourcePageRead et on transmet ce sys.version (voir CAS de verrouillage optimiste dans le Cookbook).
Écritures sur origin
Les écritures s'appliquent toujours sur l'origin (draft), et l'exposition en delivery (CDA/ACDA) se contrôle avec publish (le publish de ResourceCreate/ResourceUpdate/ResourcePatch, ou ResourcePublish/ResourceUnpublish).
Qu'est-ce qui constitue un échec
- Un vrai échec est une erreur d'exécution de statement : un statut final
Httpsupérieur ou égal à 400 (4xx·5xx ; pas un échec lorsqueignoreStatusCode: true) ou un dépassement de délai, un corps de réponse dépassant 10MiB, ou une opération de ressource en échec (cible inexistante, conflit de version, opération non prise en charge, etc.). Face à de tels échecs, le moteur avorte et compense, et on peut les gérer localement avecTry/catch/finally. - Un
Returnn'est pas une erreur, mais une sortie anticipée normale. Il n'est pas une cible decatch(il n'existe pas de concept de throw utilisateur). - Dans un
catch, on référence{ message, statement }via/error.
Pas d'agrégation côté serveur
Il n'existe pas d'opérations serveur dédiées à count, sum ou group-by. Le calcul se fait en parcourant avec ResourcePageRead et en utilisant SetVar/JsonLogic ; on est donc lié à la taille du fetch et à maxIterations (inadapté pour agréger des millions d'enregistrements).
Pas d'attente ni de délai
Un Script n'a pas de statement Delay. Un Script s'exécute une seule fois puis se termine, que ce soit sur le chemin de la requête (Sync) ou en arrière-plan (Async), et il n'attend ni ne sonde en interne la fin d'un job externe (le résultat Async est distinct : l'appelant sonde avec le requestId reçu dans le 202 pour obtenir la valeur de Return).
Contraintes statiques (validées à l'enregistrement)
Les points suivants sont vérifiés au moment où l'on enregistre un Script (création/modification). En cas de violation, l'enregistrement est refusé (échec au moment de l'enregistrement, pas à l'exécution).
| Contrainte | Valeur par défaut |
|---|---|
S'il y a des I/O externes, executionMode doit être Async | Sans objet |
Dans le body d'un Loop, les appels externes Http et l'ingestion de fichier Media sont interdits | Sans objet |
Maximum d'appels externes Http par définition | 3 (maxExternalIo) |
Maximum de SetVar par définition (imbriqués inclus) | 5 (maxSetVar) |
| Maximum total de statements par définition (imbriqués inclus) | 15 (maxStatements) |
Plafond de Http.retry | 2 (maxHttpRetry) |
Ces limites peuvent être ajustées via la configuration du serveur (weegloo.core.script.*) ; les valeurs ci-dessus sont les valeurs par défaut.
L'ingestion de fichier Media relève de la capacité
MediaIngestet, contrairement à un appel externeHttp(ExternalIo), ne compte pas dans le plafond demaxExternalIo(3). En revanche, l'obligation d'Asyncet l'interdiction dans le body d'unLoops'appliquent exactement comme pourHttp.
Budget de temps (à l'exécution)
| Mode | Budget par défaut |
|---|---|
| Sync | 10 secondes (syncTimeoutMs) |
| Async | 60 secondes (asyncTimeoutMs) |
Limites de quantité par plan
Script est une ressource Billable, et son nombre par Organization est limité selon le plan.
| Plan | Nombre de Script |
|---|---|
| Free | 3 |
| Basic | 10 |
| Pro | 50 |
| Enterprise | Illimité |
Lorsque la limite est atteinte, la création d'un nouveau Script est refusée (même voie que pour les autres ressources Billable).
Modèle de sécurité
En-têtes secret
Un élément de Http.headers avec secret:true est réservé à CMA (l'administrateur) : il n'est pas exposé à l'utilisateur final (ServiceUser) et n'est déchiffré qu'au tout dernier moment avant la transmission. Placez ici les secrets comme une clé d'API LLM (même lorsqu'il est empaqueté dans un App Bundle, la valeur secret est masquée et ne sort jamais du Space d'origine).
Identité d'exécution et autorisation
- Identité d'exécution : pendant l'exécution, toute opération de ressource est effectuée sous l'identité de l'utilisateur qui a appelé
/execute. LecreatedBy/updatedByde toute ressource créée ou modifiée est l'appelant, et une portéecreatedBy: ":self"se résout elle aussi par rapport à l'appelant. - Il y a deux limites d'autorisation, et à l'exécution, le moteur ne revérifie pas les permissions de ressource à chaque statement.
- Au moment de la rédaction (enregistrement) : lors de l'enregistrement d'un Script, on vérifie si l'auteur possède réellement les permissions de ressource et d'action qu'utilisent ses statements. S'il en manque ne serait-ce qu'une, l'enregistrement est refusé (
WGL403015). Autrement dit, un Script contenant une opération non autorisée n'est jamais enregistré au départ. - Au moment de l'appel (
/execute) : on ne vérifie que la permission Execute de Script de l'appelant. Sans elle, le résultat est403. Une fois qu'elle est validée, les permissions de ressource par statement ne sont pas revérifiées à l'exécution ; l'exécution se poursuit. C'est le même principe que le droit d'exécuter une fonction en programmation. Si l'on a le droit d'exécuter la fonction, on ne redemande pas la permission de chaque opération individuelle qu'elle contient.
- Au moment de la rédaction (enregistrement) : lors de l'enregistrement d'un Script, on vérifie si l'auteur possède réellement les permissions de ressource et d'action qu'utilisent ses statements. S'il en manque ne serait-ce qu'une, l'enregistrement est refusé (
- Portée de propriété : dans un filtre
where,createdBy: ":self"signifie « uniquement ce qu'a créé l'appelant actuel » (par exemple, ne consulter que son propre portefeuille). - Permissions déléguées (prudence à la rédaction) : en combinant les deux limites ci-dessus, exécuter un Script revient à agir avec les permissions de l'auteur déléguées. L'appelant n'a besoin que de Execute, et les statements à l'intérieur du Script s'exécutent tels quels dans le périmètre pour lequel l'auteur a été autorisé au moment de l'enregistrement. Par conséquent, une opération de ressource que l'appelant ne pourrait pas effectuer lui-même peut tout de même se produire à travers le Script. Comme les permissions accordées à l'auteur constituent la portée effective de ce Script, il convient de définir avec soin les opérations que l'on place dans un Script.
Liste de contrôle récapitulative
Avant d'enregistrer, vérifiez les points suivants.
- S'il y a un appel externe (
Http) ou une ingestion de fichier Media,executionModevaut"Async". - Aucun appel externe n'a été placé dans le body d'un
Loop. - Il y a au maximum 3 appels externes, 5
SetVaret 15 statements au total. - Les valeurs secret ont été placées uniquement via
secret:truedansHttp.headers. - Les opérations irréversibles (les appels externes) ont été placées le plus tard possible.
- Si la contention d'update/patch est une préoccupation, on utilise le
versiondeResourceUpdateouResourcePatch. - Pour renvoyer un résultat,
Return.valuea été spécifié.
Documents connexes
- Expressions de valeur : règles de valeurs et de conditions.
- Catalogue des statements : les champs et résultats de chaque statement.
- Cookbook : une collection d'exemples complets.
- Ressource Script et endpoints : la structure de la ressource
Scriptet les endpoints HTTP comme/execute. - Aperçu de Script : la structure de niveau supérieur et les modes d'exécution.
