Les Workers et Pages de Cloudflare n'ont aucun contrôle d'accès par ressource — et il n'existe pas de véritable solution de contournement
Un récit de première main sur le fait de frapper la faille structurelle RBAC de Cloudflare : il n'y a aucun moyen de limiter un rôle de membre ou un jeton API à un seul Worker ou projet Pages. Cet article documente précisément le problème, ce que la communauté fait pour le contourner, pourquoi ces contournements sont insuffisants, et ce que Cloudflare doit construire.

Cloudflare Workers et Pages sont des produits puissants et vraiment impressionnants. Mais en travaillant sur la mise en œuvre de contrôles d'accès au moindre privilège pour un compte de production exécutant plusieurs projets Workers et Pages, je me suis heurté à un obstacle majeur : il n'existe aucun moyen dans Cloudflare de limiter un rôle de membre ou un jeton API à un seul Worker ou à un seul projet Pages. Ni par le biais de la limitation par domaine. Ni par les permissions du jeton. Ni par aucune combinaison de paramètres dans le tableau de bord. Cela n'existe tout simplement pas.
Ce post documente précisément l'écart, tel que je l'ai rencontré — ce que j'ai essayé, ce que la communauté fait pour le contourner, pourquoi ces solutions de contournement ne résolvent pas complètement le problème, et ce que Cloudflare devrait construire pour le résoudre. Je l'écris en tant que développeur qui a rencontré ce problème en production, et non en tant que chercheur en sécurité construisant un scénario théorique.
Ce n'est pas un cas particulier de niche. Toute équipe gérant plus d'un projet Worker ou Pages — avec plus d'un développeur ou un pipeline CI/CD — est affectée par cette lacune.
Le Problème : Tout est à l'échelle du compte
Dans le modèle de permissions de Cloudflare, à la fois les Workers et les Pages sont des ressources au niveau du compte. Lorsque vous accordez à un rôle ou à un jeton l'accès aux Workers ou aux Pages, cet accès s'applique à chaque Worker et à chaque projet Pages du compte — il n'y a pas de filtre de ressource au niveau du Worker individuel ou du projet.
Rôles des membres
Lorsque vous ajoutez un membre à l'équipe et lui attribuez le rôle « Administrateur Cloudflare Workers », il peut lire, écrire et supprimer tous les Workers de votre compte. Il en va de même pour Pages — un membre ayant accès à Pages a accès à tous les projets Pages, sans possibilité de le limiter à un seul projet. Il n'existe aucun mécanisme pour dire « ce développeur peut uniquement accéder à worker-payments » ou « ce développeur peut uniquement déployer le projet Pages marketing ». Les deux rôles s'appliquent à l'ensemble du compte, et c'est la seule option.
Cloudflare dispose d'une fonctionnalité appelée Rôles à portée de domaine, qui permet de restreindre l'accès d'un membre à des zones spécifiques. Cela semble pertinent — mais ce ne l'est pas. Les Rôles à portée de domaine s'appliquent exclusivement aux ressources au niveau de la zone : DNS, SSL, règles de pare-feu, règles de page. Les Workers et les Pages sont des ressources au niveau du compte et échappent totalement au système de portée de domaine. Attribuer un rôle à portée de domaine n'impose aucune restriction sur les Workers ou les Pages. Un membre avec le rôle Administrateur des Workers limité uniquement à votre zone de production possède toujours l'accès Administrateur des Workers — et Pages — sur l'ensemble de votre compte.
Les rôles à portée de domaine ne s'appliquent pas aux Workers ou aux Pages. Ils n'offrent aucun soulagement pour ce problème — aucun.
Jetons ### API
Les jetons API sont le moyen par lequel les pipelines CI/CD s'authentifient pour déployer des Workers via Wrangler et des Pages via l'API Cloudflare ou wrangler pages deploy. Lorsque vous créez un jeton avec l'autorisation "Workers Scripts : Modifier", il peut lire, écrire et supprimer n'importe quel Worker de votre compte. Lorsque vous créez un jeton avec l'autorisation "Cloudflare Pages : Modifier", il peut lire, écrire et supprimer n'importe quel projet Pages de votre compte. Aucune de ces autorisations n'accepte de filtre de ressources au niveau d'un Worker ou d'un projet individuel.
La propre documentation de Cloudflare sur les déploiements CI/CD reconnaît cela directement, conseillant aux développeurs de « limiter la portée de votre jeton » et de le restreindre à un compte spécifique — mais la granularité la plus fine offerte est au niveau du compte. Vous pouvez restreindre un jeton à un compte parmi plusieurs comptes que vous possédez, mais vous ne pouvez pas le restreindre à un Worker ou à un projet Pages spécifique au sein de ce compte.
Le blog sur les permissions de Cloudflare (septembre 2023) le confirme directement : à la date de cette publication, la définition des ressources au-delà des zones est limitée — les jetons R2 peuvent être définis pour des buckets spécifiques, mais Workers et Pages n’ont pas d’équivalent. Cela est confirmé à nouveau dans la documentation Workers Builds, qui génère automatiquement un jeton de déploiement couvrant les Workers Scripts (édition), Workers KV Storage (édition), Workers R2 Storage (édition) et Workers Routes (édition) — au niveau du compte, sans possibilité de restreindre à un seul nom de script. Les déploiements Pages via CI/CD rencontrent le même problème : la permission Cloudflare Pages : Éditer couvre tous les projets Pages du compte.
Les jetons limités dans le temps n'aident pas
Une suggestion courante est d'utiliser des jetons limités dans le temps — des jetons qui expirent après une courte période — pour limiter l'exposition. Cela vaut la peine d'être fait en tant que mesure d'hygiène générale, mais cela ne résout pas du tout le problème de l'étendue. Un jeton qui expire dans une heure a toujours un accès complet à l'ensemble du compte à chaque Worker et à chaque projet Pages pendant cette heure. L'expiration automatise le moment de la révocation — elle ne restreint pas ce que le jeton peut toucher tant qu'il est actif.
Le principe du moindre privilège concerne la portée, pas la durée. Les jetons à durée limitée restreignent la fenêtre d'exposition. Ils ne limitent pas les Workers ou les projets Pages auxquels un jeton peut accéder. Ce sont des problèmes différents.
Qu'est-ce que cela casse
Ces deux lacunes ensemble violent les deux principes de contrôle d'accès les plus fondamentaux dans les systèmes de production :
- Moindre privilège : Un jeton CI/CD pour les paiements des travailleurs ne devrait pas avoir la permission permanente de modifier worker-auth, worker-checkout ou tout projet Pages. Un pipeline de déploiement pour votre site marketing ne devrait pas pouvoir toucher votre Worker de paiements. Aujourd'hui, ils peuvent — et il n'existe aucun mécanisme sur la plateforme pour l'empêcher.
- Séparation des tâches : Un développeur travaillant sur un Worker ou un projet Pages ne devrait pas pouvoir toucher aux ressources d'une autre équipe en production. Aujourd'hui, s'ils ont accès aux Workers ou Pages, ils le peuvent.
Le rayon d'impact d'un jeton compromis ou d'un compte développeur victime de phishing couvre toute la surface des Workers et Pages de votre compte. Dans un compte de production avec plusieurs équipes et projets, il s'agit d'une exposition significative.
Ce que les développeurs font réellement : Les solutions de contournement
Parce que la plateforme ne fournit pas de contrôles d'accès par Worker ou par projet Pages, les équipes ont adopté un ensemble de schémas compensatoires. Voici ce qui est réellement utilisé sur le terrain — et un compte rendu honnête des limites de chacun.
Le modèle de compte séparé — La solution de contournement la plus courante
La solution de contournement la plus largement recommandée dans la communauté Cloudflare consiste à isoler les projets Workers et Pages dans des comptes Cloudflare séparés — un compte par projet ou équipe. Chaque compte dispose de ses propres membres et jetons, et comme chaque compte constitue une limite stricte, l'accès est naturellement isolé.
Un fil de discussion de la communauté Cloudflare d'avril 2025 — posant directement la question « Les membres peuvent-ils accéder uniquement à mes Workers au lieu de l'ensemble du compte de domaine ? » — illustre à quel point cette question est courante. La réponse de la communauté, constante à travers plusieurs fils de discussion remontant à plusieurs années, est la même : vous avez besoin de comptes séparés. Un autre fil de discussion d'avril 2025 a demandé comment isoler la gestion de différents Workers, D1 et Pages entre des équipes dans une petite entreprise — la question mentionne Pages explicitement — et là encore, la réponse pointait vers la séparation des comptes comme étant la seule option réelle.
Ce modèle atteint effectivement l'objectif d'isolation. Mais le qualifier de solution de contournement sous-estime à quel point il est opérationnellement pénible :
- Prolifération des comptes et fragmentation de la facturation. Chaque compte est une entité de facturation distincte, un tableau de bord séparé, un ensemble distinct d'identifiants à sécuriser et à renouveler. Gérer les membres, le SSO et les journaux d'audit sur N comptes est difficile à grande échelle.
- Les ressources ne peuvent pas traverser les limites des comptes. Les Workers qui doivent partager des espaces de noms KV, des bases de données D1, des buckets R2 ou des Durable Objects ne peuvent pas le faire entre comptes. Les projets Pages qui utilisent des Workers comme fonctions backend sont soumis à la même contrainte — les liaisons de services sont limitées au compte.
- Il n'y a aucun moyen de transférer un Worker ou un projet Pages entre comptes. Si vous développez dans un compte isolé et souhaitez le déplacer dans votre compte principal de production, vous devez recréer manuellement le script ou le projet, toutes les liaisons, variables d'environnement, secrets et routes depuis le début. Il n'existe pas d'API de transfert ni de voie de migration pour les Workers ou Pages.
- Observabilité fragmentée. Les journaux, analyses et métriques sont par compte. Vous perdez la visibilité unifiée sur votre flotte de Workers et de Pages et devez utiliser des outils externes pour les agréger.
Créer des comptes séparés pour isoler les projets Workers et Pages est un contrôle compensatoire — et non une architecture de sécurité conçue. Vous contournez une limite d'autorisation manquante, et non pas vous construisez en fonction d'une limite existante.
Jetons Éphémères avec Rotation Aggressive
Certaines équipes atténuent le risque en générant un nouveau jeton API pour chaque exécution de déploiement et en le révoquant immédiatement par la suite. Cela s'applique également aux déploiements Workers via Wrangler et aux déploiements Pages via wrangler pages deploy ou l'API Cloudflare. Il s'agit d'une mesure légitime de défense en profondeur et utile à mettre en place — mais cela ne limite que la durée d'exposition, pas l'étendue. Le jeton a toujours un accès complet à l'ensemble du compte pour tous les projets Workers et Pages tant qu'il existe.
Mettre cela en œuvre correctement nécessite également une infrastructure CI/CD qui prend en charge la création et la révocation dynamiques de jetons via l'API Cloudflare, ce que la plupart des configurations de pipeline standard ne supportent pas nativement.
# Illustrative: short-lived token via Cloudflare API
# Even with expiry set, Workers Scripts: Edit still covers ALL Workers.
# Cloudflare Pages: Edit still covers ALL Pages projects.
# There is no script_name or project_name resource filter in the permissions API.
POST /client/v4/user/tokens
{
"name": "ci-deploy-worker-payments-2026-03-11",
"policies": [{
"effect": "allow",
"resources": { "com.cloudflare.api.account.ACCOUNT_ID": "*" },
"permission_groups": [{ "id": "<workers-scripts-edit-group-id>" }]
// ^ No per-Worker or per-Pages-project resource filter exists. Account-wide only.
}],
"not_before": "2026-03-11T10:00:00Z",
"expires_on": "2026-03-11T11:00:00Z"
}
Verrouillage de l'accès API par utilisateur
Le système de permissions de Cloudflare permet aux Super Administrateurs de restreindre quels membres du compte sont autorisés à générer des jetons API. Cela peut centraliser la création de jetons dans un seul compte de service, réduisant le nombre de personnes pouvant créer des jetons avec des permissions étendues sur à la fois les Workers et les Pages.
Ceci est un contrôle administratif utile — mais cela ne résout pas le problème de portée. Les jetons créés par le compte de service ont toujours accès aux Workers et Pages à l'échelle du compte. Cela réduit le nombre de points par lesquels un jeton surdimensionné peut être créé ou utilisé de manière abusive, mais les jetons qui sont créés sont toujours surdimensionnés par conception.
Ce dont Cloudflare a besoin pour construire
La correction n'est pas complexe à décrire sur le plan architectural. Le billet de blog de Cloudflare de 2022 présentant les rôles à domaine restreint décrivait leur système de permissions Bach comme prenant en charge le périmètre des ressources pour « comptes, zones, environnements de workers ou enregistrements DNS ». Les environnements de workers sont explicitement nommés comme un type de ressource dans ce système sous-jacent — et les projets Pages devraient être traités de la même manière.
L'écart est que cette capacité n'a pas été exposée pour les Workers ou les Pages dans le produit. Ce qui doit se passer :
- Jetons API : Le groupe de permissions des scripts Workers doit accepter un filtre de ressources sur des noms de scripts Worker individuels. Le groupe de permissions Cloudflare Pages doit accepter un filtre de ressources sur des noms de projets Pages individuels. Un jeton limité à
Workers Scripts: Editpour la ressourceworker-paymentsne doit pas pouvoir accéder àworker-auth. Un jeton limité àCloudflare Pages: Editpour le projetmarketing-sitene doit pas pouvoir accéder àpayments-portal. - Rôles des membres : Les rôles Workers Admin et Pages (ou de nouvelles variantes par ressource) doivent pouvoir être limités à des Workers nommés et à des projets Pages nommés — pas seulement aux zones comme le font aujourd'hui les rôles limités au domaine, et de manière à ne pas accorder un accès à l'ensemble du compte.
- R2 est la preuve de concept : Cloudflare supporte déjà la limitation au niveau des buckets pour les jetons R2. Appliquer le même schéma aux noms de scripts Worker et aux noms de projets Pages résoudrait ce problème. La fonctionnalité existe dans le modèle de permissions — elle doit être appliquée aux Workers et aux Pages.
Cela permettrait à un jeton CI/CD d'être incapable, par application de la plateforme, de toucher à un projet Worker ou Pages autre que celui pour lequel il a été émis. Un compte développeur compromis serait limité à l'étendue de leurs ressources assignées. La séparation des responsabilités entre les équipes produits serait appliquée par la plateforme — et non par la politique organisationnelle et la confiance.
Ce que les équipes devraient faire dès maintenant
Tant que cet écart existe, voici comment se rapprocher du principe du moindre privilège autant que la plateforme le permet actuellement. Ce sont des mesures compensatoires — pas des solutions — et elles doivent être comprises comme telles.
- Isolez vos projets Workers et Pages les plus critiques dans un compte dédié. Si vous avez un petit nombre de ressources à enjeux élevés — Workers de traitement de paiements, applications Pages destinées aux clients, services d'authentification — et pouvez tolérer la surcharge opérationnelle, les placer dans leur propre compte offre une véritable isolation. Acceptez que le partage des ressources et l'observabilité soient plus difficiles en tant que compromis.
- Générez des jetons à durée de vie courte à chaque déploiement et révoquez-les immédiatement. Cela s'applique aux pipelines Workers et Pages. Limitez la fenêtre d'exposition même si vous ne pouvez pas limiter la portée.
- Restreignez la création de jetons API à un seul compte de service. Utilisez le contrôle d'accès API par utilisateur de Cloudflare pour empêcher les membres de l'équipe de créer leurs propres jetons larges de manière indépendante.
- Surveillez le journal d'audit. Utilisez l'API du journal d'audit de Cloudflare pour suivre les téléchargements de scripts Worker, les événements de déploiement Pages et toute modification de l'un ou l'autre. Alertez en cas d'acteurs inattendus ou de noms de ressources modifiés de manière inattendue.
- Soulevez le sujet formellement auprès de Cloudflare. Si vous êtes sur un plan Enterprise, demandez le RBAC par ressource pour les Workers et Pages auprès de votre CSM en tant que demande de produit nommée. Publiez dans le forum Community. Plus il y a d'équipes qui documentent explicitement cette lacune, plus la pression est forte pour la combler.
# Audit log query: monitor for Worker and Pages changes
GET /client/v4/accounts/{account_id}/audit_logs
?action.type=Script+Upload
&since=2026-01-01T00:00:00Z
Authorization: Bearer {your_token}
# Run a separate query for Pages deployment events:
GET /client/v4/accounts/{account_id}/audit_logs
?action.type=Deployment
&since=2026-01-01T00:00:00Z
Authorization: Bearer {your_token}
# Review both for unexpected actors or unexpected resource names.
Fermeture
Cloudflare est une plateforme que nous utilisons et recommandons. Ce post n'est pas une condamnation — c'est un compte rendu précis et documenté d'une lacune spécifique qui compte pour la sécurité en production à la fois sur Workers et Pages. L'infrastructure pour la corriger existerait déjà dans Bach. La demande est simple : exposer une portée par ressource pour les jetons et les rôles sur Workers et Pages, exactement comme elle existe déjà pour les buckets R2.
À Evolving Cyber, nous croyons que la bonne sécurité est une décision de conception, et non une adaptation ultérieure. Ce principe s'applique aux plateformes sur lesquelles nous construisons, pas seulement aux logiciels que nous développons. Lorsqu'une plateforme rend le principe du moindre privilège opérationnellement impossible — ou réalisable uniquement par la prolifération des comptes et des compensations manuelles — elle transfère entièrement la charge de la sécurité aux équipes qui l'utilisent. Ce n'est pas une bonne conception.
La demande : limiter les jetons API et les rôles des membres aux noms individuels de scripts Worker et aux noms de projets Pages. R2 le fait déjà pour les buckets. Les Workers et Pages ont besoin de la même chose.
Sources et références
- Documentation Cloudflare — GitHub Actions CI/CD : Guide sur la portée des jetons
- Documentation Cloudflare — Workers Configuration des Builds : Permissions des jetons générées automatiquement
- Docs Cloudflare — Pages : Déployer avec Wrangler
- Documentation Cloudflare — Référence des autorisations des jetons API
- Documentation Cloudflare — Rôles de compte
- Docs Cloudflare — Portées de rôle
- Blog Cloudflare (septembre 2023) — Autorisations de compte, comment les utiliser et meilleures pratiques
- Blog Cloudflare (mars 2022) — Rôles à portée de domaine : Accès anticipé (système de permissions Bach)
- Blog Cloudflare — RBAC pour tout le monde
- Communauté Cloudflare (avril 2025) — Les membres peuvent-ils accéder uniquement à mes workers au lieu de l'ensemble du compte de domaine ?
- Communauté Cloudflare (avril 2025) — Meilleure façon d'isoler la gestion de différentes applications Worker/D1/Pages
- Communauté Cloudflare (juillet 2021) — Comment contrôler l’accès des utilisateurs à des domaines individuels
- Docs Cloudflare — Workers pour Plates-formes : Isolation des Workers
- NIST SP 800-53 — Principe du moindre privilège (AC-6)