Sémantique d'exécution, contraintes et sécurité
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 Statement et les Expressions de valeur ; pour les combinaisons concrètes, consultez le Cookbook.
Ordre d'exécution
- Les
statementss'exécutent séquentiellement de haut en bas. Lorsque l'exécution atteint unReturn, elle se termine à ce point. - L'exécution se déroule en ligne, sur le chemin qui traite la requête d'appel. La réponse de l'appel est le résultat de l'exécution (pour la forme de la réponse, voir Requête et réponse dans l'aperçu de Script), et le temps alloué à une exécution est traité plus bas dans Budget de temps.
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 Statement 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. - Les effets externes (
Http) sont irréversibles (un appel déjà parti, ainsi que sa facturation, ne peuvent pas être annulés). - Il arrive que la compensation ne s'exécute pas du tout, laissant subsister un état non compensé.
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 ResourceFind 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
Si un Statement échoue en cours d'exécution, l'exécution s'interrompt à cet endroit, à moins qu'un Try ne prenne en charge cet échec. Le moteur tente alors d'annuler le travail effectué jusque-là. Cette annulation a des limites, détaillées dans Sans transaction et compensation best-effort.
Si le Statement en échec se trouve dans un Try, cet échec peut être traité dans catch. Dans un catch, on référence le contenu de l'échec ({ message }) via /error. Le Statement où l'échec s'est produit n'y figure pas.
Les cas suivants sont traités comme des échecs.
- Une opération de ressource échoue (cible inexistante, version non concordante, opération non prise en charge, etc.)
Httpéchoue (voir Les deux façons dont Http échoue)- La transformation d'un fichier Media échoue (voir Quand la transformation de fichier échoue)
- Une limite vérifiée à l'exécution, fixée pour chaque Statement, est dépassée (par exemple, les Limites de longueur des valeurs)
Un Return n'est pas un échec. Il termine normalement l'exécution de façon anticipée : il ne passe donc pas dans catch.
Les deux façons dont Http échoue
Un échec de Http se répartit en deux cas, selon qu'il est traité ou non comme une réponse de status. Cette différence détermine si retry et ignoreStatusCode s'appliquent.
| Catégorie | Traité comme une réponse de status | Échec immédiat |
|---|---|---|
| Cas concernés | L'API cible répond avec un status supérieur ou égal à 400, le délai est dépassé (status 504), la connexion à l'API cible a échoué ou la réponse n'a pas pu être lue (status 502), le corps de réponse dépasse 10MiB (status 502) | responseType vaut "Json" mais le corps d'une réponse de succès n'est pas du JSON, le fichier à envoyer dépasse la limite de téléchargement, l'URL du fichier répond avec un status autre que 2xx ou la connexion à l'URL du fichier est impossible, la valeur d'une part a un format invalide |
retry | Réessaie le nombre de fois indiqué | Ne réessaie pas |
ignoreStatusCode: true | Ne le considère pas comme un échec et lie { status, body } comme résultat | Ne s'applique pas ; traité comme un échec |
Try/catch | Peut être traité dans catch | Peut être traité dans catch |
Les conditions d'échec pendant l'envoi de fichier sont détaillées dans Envoyer un fichier comme corps.
L'agrégation côté serveur se limite au décompte
Le décompte, c'est ResourceCount qui l'effectue côté serveur. Comme il ne va pas lire les éléments, il n'est pas soumis au plafond du nombre d'éléments traités.
Pour sum et group-by, il n'existe pas d'opération serveur dédiée. Une telle agrégation doit se calculer soi-même en parcourant avec ResourceForEach et en utilisant SetVar et JsonLogic ; on est donc lié au plafond du nombre d'éléments traités (inadapté pour agréger des millions d'enregistrements). Si seul le décompte est nécessaire, on ne parcourt pas : on utilise ResourceCount.
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, et il n'attend ni ne sonde en interne la fin d'un job externe.
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). Quelle violation entraîne quel code de refus est traité dans Erreurs.
| Contrainte | Valeur |
|---|---|
Maximum d'appels externes par définition (Http, EmailSend) | Selon le plan (voir Tarifs) |
Maximum d'éléments traités par ResourceForEach (en l'absence de limit déclaré, parcourt jusqu'à cette valeur ; échec s'il reste des correspondances à ce plafond) | 10 000 |
Maximum de SetVar par définition (imbriqués inclus) | 10 |
Maximum de Cache par définition (imbriqués inclus, toutes opérations confondues) | 5. Au-delà, enregistrement refusé |
Un Cache dans le bloc d'un Loop ou d'un ResourceForEach | Enregistrement refusé |
Cache.key | Littéral uniquement, 128 caractères au maximum. Une expression de valeur fait refuser l'enregistrement |
Cache.ttl | Entre 1 et 30 secondes ; en son absence, 5 secondes. Hors de cet intervalle, enregistrement refusé |
| Maximum total de Statement par définition (imbriqués inclus) | Selon le plan (voir Tarifs) |
Plafond de Http.retry | 2 |
Champs de corps de requête d'un Http (body, urlBody, multipartBody) | Un seul des trois. En indiquer deux ou plus fait refuser l'enregistrement |
Nombre de parts de Http.multipartBody | Au moins 1. Vide, l'enregistrement est refusé |
value et url d'une part de multipartBody | Exactement l'un des deux. Indiquer les deux ou aucun fait refuser l'enregistrement |
fileName d'une part de multipartBody | Uniquement sur une part qui indique url. L'indiquer sans url fait refuser l'enregistrement |
Longueur de Regex.pattern | 128 caractères |
Maximum de secrets par définition | 20 |
key de secrets | 1 à 64 caractères, lettres latines, chiffres, _ et - uniquement. Deux key identiques font refuser l'enregistrement |
value de secrets | 1 à 4 096 caractères. En dehors de cet intervalle, enregistrement refusé |
Référence { /secrets… } | Exactement /secrets/<key déclaré>. Sinon, enregistrement refusé |
| Statement qui crée ou supprime un ServiceUser | Enregistrement refusé. Seuls les trois Statement de lecture ainsi que ResourceUpdate et ResourcePatch acceptent cette ressource |
Si anonymousCallEnabled vaut true, le createdBy: ":self" de where | Enregistrement refusé |
transformations d'une instruction d'ingestion Media (Transformation de fichier) | Tableau uniquement. Le type de chaque élément est PdfWatermark, et color est au format #RRGGBB. Pour text, toute la chaîne écrite (chemins des { /pointer } compris) doit tenir sur une seule ligne de caractères autorisés. Sinon, enregistrement refusé |
Longueur du text littéral de PdfWatermark | 1 à 64 caractères. En dehors de cet intervalle, enregistrement refusé. Un text contenant un { /pointer } n'est pas vérifié à l'enregistrement, mais à l'exécution, sur la valeur résolue |
Les limites fixes du tableau ci-dessus sont des valeurs fixées par la plateforme : elles sont identiques quel que soit le plan. En revanche, le nombre total de Statement et le nombre d'appels externes par définition sont des limites propres au plan. Comme ces deux-là ne sont pas des erreurs de validation mais des limites de plan, un dépassement fait refuser l'enregistrement ou la modification pour dépassement de la limite du plan (une même définition est admise sur un plan supérieur) et se débloque par une montée en gamme de plan. Les valeurs par plan figurent dans Tarifs.
L'ingestion de fichier Media, contrairement aux appels externes comme
HttpetEmailSend, ne compte pas dans le plafond d'appels externes par définition.
ResourceForEachétant un Statement composite qui possède des enfants, il ne compte pas lui-même dans le nombre d'appels externes. Ce sont les Statement d'appel externe (Http,EmailSend) à l'intérieur deonEachqui sont comptés (comptés pour 1 statiquement, mais réellement exécutés à chaque élément lors du parcours).onEachpeut contenir des appels externes ou l'ingestion de fichier Media, tout comme le body d'unLoop. Le nombre de tours qu'une itération effectue réellement n'entre pas dans ce comptage : il entre en revanche, sous forme de multiplication, dans le Budget de temps ci-dessous.
Limites de longueur des valeurs (à l'exécution)
Les Statement de signature et de traitement de texte, ainsi que Cache, ont une limite sur la taille des valeurs qu'ils manipulent. Il s'agit de la longueur de la valeur résolue de l'expression, et non de la longueur de l'expression (les seize caractères de { /rawPayload } peuvent désigner plusieurs dizaines de KB) : la vérification a donc lieu pendant l'exécution et non à l'enregistrement.
| Cible | Limite | En cas de dépassement |
|---|---|---|
Le value de Signature | 65 536 caractères | Ce Statement échoue (status 422) |
Le value de Hash | 128 caractères | Ce Statement échoue (status 422) |
Le value de Regex | 10 240 caractères (10KiB) | Ce Statement échoue (status 400) |
Le value de Cache | 10 240 octets (10KiB) | Ce Statement échoue (status 422) |
- Tous quatre se comportent comme les autres échecs d'exécution : ils se traitent localement avec
Try/catch. - La limite de
Signatureest calée sur la taille des corps que les fournisseurs envoient réellement (un événement de paiement fait quelques KB, un webhook de commande atteint plusieurs dizaines de KB). Celle deHashest bien plus étroite, car c'est l'emplacement où l'on concatène quelques champs. - Les 128 caractères de
Regex.patternrelèvent de la vérification à l'enregistrement des contraintes statiques ci-dessus. Cette longueur n'est pas un dispositif contre l'emballement ((a+)+$est dangereux avec six caractères seulement). Ce qui empêche l'emballement, c'est la règle qui n'autorise le motif qu'en littéral et le budget de temps ci-dessous ; la longueur ne promet rien de plus qu'une taille qu'un humain peut lire et relire.
Budget de temps (à l'exécution)
Le temps alloué à une exécution est de 180 secondes au maximum. Le temps réellement alloué dépend de la définition du Script (et aussi du plan lorsqu'il envoie des fichiers) : c'est la base de 30 secondes à laquelle s'ajoute le temps que les appels externes peuvent utiliser.
Ce budget s'applique à l'exécution entière. Indépendamment de cela, une requête Http doit se terminer dans le timeoutMs de cette requête.
Base de 30 secondes
Toutes les opérations qui ne sont pas des appels externes, comme la lecture et l'écriture de ressources ou la réception et le traitement d'un fichier Media, sont traitées dans ces 30 secondes. Un Script sans appel externe se voit allouer 30 secondes.
Temps ajouté par Statement
Les temps des Statement placés en séquence s'additionnent tous.
| Statement | Temps ajouté |
|---|---|
Http | timeoutMs (30 secondes s'il n'est pas indiqué). Si des fichiers sont envoyés, on ajoute pour chaque fichier le temps de téléchargement (tableau ci-dessous), et si retry est indiqué, on multiplie le tout par le nombre de tentatives (1 + retry) |
EmailSend | timeoutMs (10 secondes s'il n'est pas indiqué). Comme il ne réessaie pas, on ne l'ajoute qu'une seule fois |
If | Le temps de la plus longue des deux branches then et else |
Parallel | Le temps de la plus longue des branches |
Try | La somme des temps de body, catch et finally |
Loop | Le temps de body multiplié par maxIterations (10 000 s'il n'est pas indiqué) |
ResourceForEach | Le temps de onEach multiplié par limit (10 000 s'il n'est pas indiqué) |
| Les autres Statement (ceux qui ne contiennent pas d'autre Statement) | Rien n'est ajouté. Ils sont traités dans la base de 30 secondes |
S'il n'y a pas d'appel externe dans une itération, le temps ajouté reste 0 même multiplié par le nombre d'itérations. Une telle itération doit donc se terminer dans la base de 30 secondes.
Temps de téléchargement par fichier
| Plan | Temps de téléchargement |
|---|---|
| Free | Environ 5,2 secondes |
| Basic | Environ 10,5 secondes |
| Pro | Environ 10,5 secondes |
| Enterprise | Environ 107,4 secondes |
Cette valeur correspond au temps nécessaire pour recevoir, à 10 000 000 octets par seconde, la quantité fixée par la limite de téléchargement du plan.
Exemple de calcul
Sur le plan Pro, un Script qui appelle une fois un Http (timeoutMs de 30 secondes, retry de 1) envoyant deux photos se calcule comme suit.
Http: (30 secondes + 10,5 secondes × 2) × 2 = environ 102 secondes- Exécution entière : 30 secondes + 102 secondes = environ 132 secondes
Comme 132 secondes restent sous les 180 secondes, ce Script se voit allouer 132 secondes.
Au-delà de 180 secondes
Même si la valeur calculée dépasse 180 secondes, le Script est enregistré et exécuté. Toutefois, lorsque l'exécution atteint 180 secondes, elle s'interrompt à ce moment-là.
Limites de quantité par plan
Le nombre de Script par Organization est limité selon le plan.
| Plan | Nombre de Script |
|---|---|
| Free | 10 |
| Basic | 30 |
| Pro | 100 |
| Enterprise | Illimité |
Indépendamment de cela, le nombre de Statement et le nombre d'appels externes (Http, EmailSend) qu'une définition de Script peut contenir sont eux aussi limités selon le plan. Lors de l'enregistrement ou de la modification d'une définition, un dépassement de la limite de ce plan est refusé ; pour les valeurs précises, consultez Tarifs.
Lorsque la limite est atteinte, la création d'un nouveau Script est refusée.
Taille de téléchargement de fichier Http
Lorsque Http récupère depuis une URL un fichier à envoyer comme corps de requête (urlBody, part url de multipartBody), la taille pouvant être reçue par URL de fichier est limitée selon le plan. C'est le plan de l'Organization à laquelle appartient le Space propriétaire de ce Script qui s'applique.
| Plan | Taille maximale par URL de fichier |
|---|---|
| Free | 50MiB |
| Basic | 100MiB |
| Pro | 100MiB |
| Enterprise | 1GiB |
- La limite s'applique séparément à chaque URL. S'il y a plusieurs parts
url, chaque fichier doit respecter cette limite. - Si l'on tente d'envoyer un fichier qui dépasse la limite, ce
Httpéchoue (voir Les deux façons dont Http échoue). - Cette limite sert aussi de base au temps de téléchargement ajouté au Budget de temps.
Modèle de sécurité
secrets
Les valeurs secrètes comme une clé d'API externe, la clé secrète d'un prestataire de paiement (PG), une clé de signature de webhook ou une valeur d'authentification Basic … calculée à l'avance ne s'écrivent pas telles quelles dans un Statement. On les déclare dans les secrets de la définition, et un Statement les lit via { /secrets/<key> }. Les clés de test publiées se placent au même endroit. Ainsi, au passage à la clé réelle, on laisse les Statement tels quels et il suffit de changer la valeur dans secrets.
"secrets": [
{ "key": "LLM_API_KEY", "value": "sk-...", "description": "Clé d'API pour les appels LLM" },
{ "key": "WEBHOOK_SIGNING_SECRET", "value": "whsec_...", "description": "" }
],
"statements": [
{ "type": "Http", "method": "POST", "url": "https://api.openai.com/v1/chat/completions",
"headers": [ { "key": "Authorization", "value": "Bearer { /secrets/LLM_API_KEY }" } ],
"body": { /* ... */ }, "name": "llm" }
]| Champ | Obligatoire | Règle |
|---|---|---|
key | Obligatoire | De 1 à 64 caractères, uniquement des lettres latines, des chiffres, _ et -. Il doit être unique au sein d'un même Script. |
value | Obligatoire | Une chaîne de 1 à 4 096 caractères. C'est une valeur statique qui n'est pas interprétée comme un modèle : un { /… } placé à l'intérieur est utilisé tel quel, caractère pour caractère. |
description | Obligatoire | La description de l'usage, de 0 à 128 caractères. La chaîne vide "" est également acceptée. |
- Stockage : WEEGLOO chiffre le
valueet le stocke en toute sécurité. Un Statement lit la valeur d'origine via{ /secrets/<key> }. - Consultation : dans les réponses d'API qui renvoient le Script (consultation, création, modification), le
valueest renvoyé avec sa valeur d'origine. La valeur est visible pour les rôles capables de lire ce Script : restreignez donc la permission de lecture. Un membre (ServiceUser) ne peut pas lire la définition d'un Script (la consultation et la rédaction sont réservées à CMA, et ACMA n'a pas d'API Script). - Modification : la modification complète (PUT) remplace la définition entière. Si on l'envoie sans
secrets, les valeurs secrètes déclarées sont supprimées, et si un Statement y fait encore référence via{ /secrets/… }, l'enregistrement est refusé. Envoyez doncsecretsà chaque modification. Il suffit de renvoyer telles quelles les valeurs de la réponse de consultation. - La valeur pendant l'exécution : c'est le Statement qui décide de ce que devient la valeur lue. Renvoyée par
Return, elle reste dans la réponse d'exécution et dans le ScriptLog ; placée dansSetVar,Cacheou un Content, elle y reste avec sa valeur d'origine. N'envoyez une valeur secrète qu'à l'API externe qui en a besoin. - App Bundle : lorsqu'un Script est empaqueté dans un App Bundle, le
valuedesecretsest masqué en******, tandis quekeyetdescriptionsont inclus tels quels. Un Script créé en installant cet App Bundle a ses valeurs secrètes à******: c'est à celui qui l'installe d'y saisir les valeurs réelles pour que les Statement qui les lisent fonctionnent. Les valeurs écrites hors desecrets(les en-têtes deHttp, lesecretdeSignature, etc.) ne sont pas masquées et sont incluses telles quelles.
Un Script peut contenir jusqu'à 20 secrets. Les règles de pointer sont traitées dans /secrets des Expressions de valeur.
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. L'appel anonyme fait exception. Une exécution arrivée par/execute/anonymousn'a pas d'appelant : les deux se résolvent donc par rapport à l'auteur (voir Appel anonyme). - 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 Statement. S'il en manque ne serait-ce qu'une, l'enregistrement est refusé. Autrement dit, un Script contenant une opération non autorisée n'est jamais enregistré au départ. Tout Statement qui désigne une ressource subit cette vérification, qu'il s'agisse d'un leaf ou d'un
ResourceForEachqui possède un bloc. Une définition déjà enregistrée est revérifiée lors de sa modification : après une révocation de permission, il n'est donc plus possible de la corriger et de l'enregistrer.- L'annuaire des membres (ServiceUser) est vérifié sur l'axe des paramètres et non sur les mappages de permissions. Pour écrire
resource: "ServiceUser"dans les trois Statement de lecture ainsi que dansResourceUpdateetResourcePatch, lesettingsdu SpaceRole de l'auteur doit contenirSETTING_SERVICE_LOGIN(ouSETTING_ALL) (voir le settings de SpaceRole). C'est que l'annuaire des membres est, sur tous les autres chemins également, une ressource que gouvernent les paramètres du Space. - Aucun rôle ne permet d'enregistrer un Statement qui crée ou supprime un membre. Comme un Script ne peut ni créer ni supprimer un membre, le refus n'est pas un manque de permission (
403) mais un Statement mal écrit (400). Ce n'est donc pas une lacune qu'on pourrait combler en ajoutant une permission. Les seules modifications autorisées sont leroleOverrideet leenableLogindeResourceUpdateetResourcePatch(voir Manipuler l'annuaire des membres).
- L'annuaire des membres (ServiceUser) est vérifié sur l'axe des paramètres et non sur les mappages de permissions. Pour écrire
- 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. Le chemin d'appel anonyme n'a pas cette vérification. C'est qu'il n'y a pas d'appelant à vérifier : ouvrir ce chemin équivaut donc à publier un Script sans authentification.
- 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 Statement. S'il en manque ne serait-ce qu'une, l'enregistrement est refusé. Autrement dit, un Script contenant une opération non autorisée n'est jamais enregistré au départ. Tout Statement qui désigne une ressource subit cette vérification, qu'il s'agisse d'un leaf ou d'un
- Blocage de l'appel direct (
directCallEnabled) : si ledirectCallEnabledd'un Script vautfalse, l'appel direct à/executelui-même est refusé. Cette barrière s'applique une fois la vérification de la permission Execute franchie, si bien que le blocage a lieu même lorsque l'on possède la permission Execute. Un appelant qui n'a pas cette permission reçoit un403avant d'atteindre cette barrière. Cette barrière n'existant que sur cet endpoint, l'action de liaison (script) d'un Webhook et un Scheduler l'exécutent tel quel. La valeur par défaut esttrue(appel direct autorisé). - Appel anonyme (
anonymousCallEnabled) : la valeur par défaut estfalse. En la passant àtrue, ce Script et lui seul s'exécute aussi par un chemin dédié sans authentification (/execute/anonymous), et l'identité d'exécution est alors non pas l'appelant mais l'auteur. Des deux limites ci-dessus, la vérification au moment de l'appel (la permission Execute) est absente de ce chemin : l'authentification effective est donc assurée par le Script lui-même (la vérification de signature de la requête reçue). Les conditions pour l'activer et les règles d'enregistrement sont traitées dans Appel anonyme. - 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). Ce filtre est inutilisable dans un Script qui autorise l'appel anonyme. Faute d'appelant, il se résout sur l'auteur, si bien que le sens même de portée de propriété ne tient plus. - 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 Statement à 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.
- Si l'appel anonyme (
anonymousCallEnabled) est activé,wherene contient pascreatedBy: ":self"et le Statement qui vérifie la requête reçue (Signature, etc.) est placé tout au début. - Le nombre d'appels externes (
Http,EmailSend) et le nombre total de Statement restent dans la limite du plan, il y a au maximum 10SetVaret au maximum 5Cache. - Si l'on a utilisé
Cache, lekeya été écrit en littéral et le Statement n'a été placé ni dans unLoopni dans unResourceForEach. - Si l'on parcourt un grand ensemble avec
ResourceForEach, on a déclaré unlimitou vérifié que la taille permet d'aller au bout. - Si l'on a placé une itération (
Loop,ResourceForEach), on a vérifié qu'elle entre sous forme de multiplication dans le Budget de temps (sans appel externe, la limite est le budget de base de 30 secondes). - Les valeurs secrètes comme une clé d'API externe ou une clé de signature ont été déclarées dans
secretset lues via{ /secrets/<key> }. Aucune valeur secrète n'est écrite telle quelle dans un Statement. - Si l'on enregistre par une modification complète (PUT),
secretsa été envoyé en même temps. - Le message utilisé pour la vérification de signature a été pris sur
{ /rawPayload }et non sur/payload. - S'il y a un Statement qui manipule un membre (ServiceUser), l'auteur possède
SETTING_SERVICE_LOGINet aucun Statement ne crée ni ne supprime cette ressource. - Les opérations irréversibles (les appels externes) ont été placées le plus tard possible.
- Si l'on envoie un fichier avec
Http, un seul champ de corps de requête (body,urlBody,multipartBody) a été indiqué, et l'on a vérifié que chaque fichier respecte la limite de téléchargement par plan. - Si la contention d'update/patch est une préoccupation, on utilise le
versiondeResourceUpdateouResourcePatch. - Pour renvoyer un résultat,
Return.valuea été spécifié.
Erreurs
Ce sont les codes qui surviennent lorsque l'enregistrement est refusé parce que la forme de la définition enfreint une contrainte statique. Les codes qui sanctionnent une infraction aux règles des expressions de valeur figurent dans Erreurs des Expressions de valeur, et les codes qui surviennent lors de l'appel ou de la suppression dans Erreurs de Ressource Script et endpoints. Pour les codes communs à toutes les ressources, consultez Erreurs communes.
| Code | Condition |
|---|---|
WGL400066 | Une définition contient plus de cinq Statement Cache. |
WGL400068 | Un Statement Cache a été placé dans le bloc d'un Loop ou d'un ResourceForEach. |
WGL400067 | Le key d'un Statement Cache porte une référence { /pointer } au lieu d'un littéral. |
WGL400065 | Le ttl d'un Statement Cache sort de l'intervalle autorisé. |
WGL400063 | Un Statement Cache porte un champ qui ne correspond pas à son action (un ttl sur Get, un defaultValue sur Set). |
WGL400060 | Le resource d'un ResourceCreate, d'un ResourceDelete ou d'un Statement de publication ou d'archivage porte "ServiceUser". L'annuaire des membres n'est accepté que par les trois Statement de consultation ainsi que ResourceUpdate et ResourcePatch. |
WGL400077 | Le resource d'un ResourceCount porte une ressource qui ne peut pas être comptée. Les Media et l'annuaire des membres (ServiceUser) ne se comptent pas. |
WGL400037 | Un EmailSend porte à la fois to et toServiceUser, ou les laisse tous deux vides. On en écrit exactement un. |
WGL400054 | Le total des destinataires d'un EmailSend (to 1 personne + cc + bcc) dépasse 50. |
WGL400039 | Le timeoutMs d'un EmailSend dépasse le plafond. |
WGL400101 | Un EmailSend porte à la fois body et templateBody, ou les laisse tous deux vides. On en écrit exactement un. |
WGL400102 | Le templateBody.source d'un EmailSend n'est pas un pointeur unique désignant un Content lu par un ResourceRead ou un ResourceFind de ce Script. La présence de tout autre caractère avant ou après le pointeur entraîne aussi le refus. |
WGL400061 | Dans un Script qui autorise l'appel anonyme (anonymousCallEnabled), le where d'un Statement de lecture porte createdBy: ":self". |
WGL400023 | Une définition contient plus de dix Statement SetVar. |
WGL400026 | Le retry d'un Statement Http dépasse la limite supérieure de 2. |
WGL400087 | Un Http porte deux champs de corps de requête ou plus (body, urlBody, multipartBody). |
WGL400088 | Le multipartBody d'un Http ne contient aucune part. |
WGL400089 | Une part de multipartBody porte à la fois value et url, ou ne porte ni l'un ni l'autre. |
WGL400090 | Une part de multipartBody porte un fileName sans url. |
WGL400036 | Un ResourceForEach dépasse la limite supérieure du nombre d'éléments traitables. |
WGL400094 | Plusieurs entrées de secrets utilisent le même key. |
WGL400095 | Une définition contient plus de 20 secrets. |
WGL400086 | Le value d'une entrée de secrets sort de l'intervalle de 1 à 4 096 caractères. L'erreur ne contient pas le value. |
WGL400086 | Le text d'un PdfWatermark sans { /pointer } sort de l'intervalle de 1 à 64 caractères. |
WGL400096 | Les transformations d'une instruction d'ingestion Media ne sont pas un tableau, le type d'un élément n'est pas PdfWatermark, un PdfWatermark n'a pas de text ou son text est un objet ou un tableau, color n'est pas au format #RRGGBB, ou le text tel qu'il est écrit contient un caractère non autorisé ou un saut de ligne. |
WGL429005 | Le nombre total de Statement d'une définition dépasse la limite du plan. |
WGL429006 | Le nombre d'appels externes (Http, EmailSend) d'une définition dépasse la limite du plan. |
WGL403015 | L'auteur ne possède pas les permissions de ressource et d'action qu'utilisent les Statement de la définition. Même lorsque la permission existe, l'enregistrement est refusé si l'autorisation porte un filtre contentType, createdBy ou tag. L'autorisation doit être inconditionnelle. La seule exception est le Create de Content : dans ce cas, une autorisation limitée à une portée contentType est également acceptée, et cette portée est comparée au contentType indiqué dans le Statement (le Create de Media ne bénéficie pas de cette exception). Ce code survient aussi lorsque le resource d'un Statement de lecture porte "ServiceUser" alors que l'auteur n'a pas SETTING_SERVICE_LOGIN. |
Documents connexes
- Expressions de valeur : règles de valeurs et de conditions.
- Catalogue des Statement : 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 le temps alloué à une exécution.
