Migration appliquée en production, dans le seul ordre qui ne casse pas le promote.
1. Création d'ai_agent_prod_prod_write (id=5) avec le scope étroit prod-write — factures, règlements, et soumission de documents (nécessaire à builddoc pour régénérer le PDF d'une facture modifiée). Vérifié fonctionnellement : lectures OK, DELETE sur une facture → 403.
2. Pipeline de promote repointé sur la clé de cet utilisateur. Il n'emprunte plus le credential des skills de lecture ; si la clé est absente il meurt en affichant la commande de provisionnement, au lieu de retomber silencieusement sur autre chose.
3. Révocation de 12 droits d'écriture et de suppression sur ai_agent (id=3), le credential que détiennent toutes les skills de lecture : créer/modifier factures clients et fournisseur, tiers, contacts, coordonnées de paiement, propositions, exports, liens comptables — et supprimer propositions, événements, et documents de la GED.
Vérification après migration — factures, tiers, contacts, produits, propositions, factures fournisseur et comptes bancaires se lisent toujours ; créer une facture renvoie 403 Forbidden: Insuffisant rights. La doctrine et la réalité coïncident enfin.
Une correction qui valait le détour
262 n'est pas « créer/modifier les produits » comme mon premier catalogue le supposait, mais l'extension ACL voir_tous — un droit de lecture dont les skills dépendent : sans lui, les endpoints de liste renvoient des tableaux vides au lieu d'un 403 (le piège documenté par la skill dolibarr). Le révoquer aurait silencieusement aveuglé toutes les lectures, sans la moindre erreur pour le signaler.
C'est précisément pourquoi l'audit lit les libellés sur /user/perms.php plutôt que de faire confiance à des ids en dur. Le socle READ_ONLY est désormais la surface de lecture auditée (35 droits), pas une supposition.
Migration appliquée en production, dans le seul ordre qui ne casse pas le promote.
**1.** Création d'`ai_agent_prod_prod_write` (id=5) avec le scope étroit `prod-write` — factures, règlements, et soumission de documents (nécessaire à `builddoc` pour régénérer le PDF d'une facture modifiée). Vérifié fonctionnellement : lectures OK, `DELETE` sur une facture → **403**.
**2.** Pipeline de promote repointé sur la clé de cet utilisateur. Il n'emprunte plus le credential des skills de lecture ; si la clé est absente il meurt en affichant la commande de provisionnement, au lieu de retomber silencieusement sur autre chose.
**3.** Révocation de **12 droits d'écriture et de suppression** sur `ai_agent` (id=3), le credential que détiennent toutes les skills de lecture : créer/modifier factures clients **et fournisseur**, tiers, contacts, coordonnées de paiement, propositions, exports, liens comptables — et **supprimer** propositions, événements, et documents de la GED.
**Vérification après migration** — factures, tiers, contacts, produits, propositions, factures fournisseur et comptes bancaires se lisent toujours ; créer une facture renvoie `403 Forbidden: Insuffisant rights`. La doctrine et la réalité coïncident enfin.
## Une correction qui valait le détour
`262` n'est **pas** « créer/modifier les produits » comme mon premier catalogue le supposait, mais l'extension ACL **`voir_tous`** — un droit de **lecture** dont les skills dépendent : sans lui, les endpoints de liste renvoient des tableaux vides au lieu d'un 403 (le piège documenté par la skill `dolibarr`). Le révoquer aurait silencieusement aveuglé toutes les lectures, sans la moindre erreur pour le signaler.
C'est précisément pourquoi l'audit lit les libellés sur `/user/perms.php` plutôt que de faire confiance à des ids en dur. Le socle `READ_ONLY` est désormais la surface de lecture **auditée** (35 droits), pas une supposition.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
Migration applied to production, in the only order that does not break the
promote flow:
1. Created `ai_agent_prod_prod_write` (id=5) with the narrow `prod-write` scope —
invoices, payments, and document submission (needed by builddoc to regenerate
a modified invoice's PDF). Verified functionally: reads pass, DELETE on an
invoice returns 403.
2. Repointed the promote pipeline at that user's key. It no longer borrows the
read skills' credential; if the key is absent it dies with the provisioning
command rather than silently falling back.
3. Revoked 12 write/delete rights from `ai_agent` (id=3), the credential every
read skill holds: create/modify on customer AND supplier invoices,
thirdparties, contacts, thirdparty payment details, proposals, exports,
accounting links — and delete on proposals, events, and GED documents.
Verified after: invoices, thirdparties, contacts, products, proposals, supplier
invoices and bank accounts all still read; creating an invoice returns
`403 Forbidden: Insuffisant rights`. The documented posture and the real one
finally agree.
scopes.ts corrected against the live instance: 262 is NOT "créer/modifier les
produits" as the first catalogue guessed but the `voir_tous` ACL extension — a
READ right the skills depend on (without it, list endpoints return empty arrays
instead of 403). Revoking it would have silently blinded every read skill. This
is why the audit reads labels off /user/perms.php rather than trusting ids in
code. The READ_ONLY baseline is now the audited read surface (35 rights), not a
guess.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Migration appliquée en production, dans le seul ordre qui ne casse pas le promote.
1. Création d'
ai_agent_prod_prod_write(id=5) avec le scope étroitprod-write— factures, règlements, et soumission de documents (nécessaire àbuilddocpour régénérer le PDF d'une facture modifiée). Vérifié fonctionnellement : lectures OK,DELETEsur une facture → 403.2. Pipeline de promote repointé sur la clé de cet utilisateur. Il n'emprunte plus le credential des skills de lecture ; si la clé est absente il meurt en affichant la commande de provisionnement, au lieu de retomber silencieusement sur autre chose.
3. Révocation de 12 droits d'écriture et de suppression sur
ai_agent(id=3), le credential que détiennent toutes les skills de lecture : créer/modifier factures clients et fournisseur, tiers, contacts, coordonnées de paiement, propositions, exports, liens comptables — et supprimer propositions, événements, et documents de la GED.Vérification après migration — factures, tiers, contacts, produits, propositions, factures fournisseur et comptes bancaires se lisent toujours ; créer une facture renvoie
403 Forbidden: Insuffisant rights. La doctrine et la réalité coïncident enfin.Une correction qui valait le détour
262n'est pas « créer/modifier les produits » comme mon premier catalogue le supposait, mais l'extension ACLvoir_tous— un droit de lecture dont les skills dépendent : sans lui, les endpoints de liste renvoient des tableaux vides au lieu d'un 403 (le piège documenté par la skilldolibarr). Le révoquer aurait silencieusement aveuglé toutes les lectures, sans la moindre erreur pour le signaler.C'est précisément pourquoi l'audit lit les libellés sur
/user/perms.phpplutôt que de faire confiance à des ids en dur. Le socleREAD_ONLYest désormais la surface de lecture auditée (35 droits), pas une supposition.🤖 Generated with Claude Code
https://claude.ai/code/session_01VRShc4QhLLU73FLHx9vskh