<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mathieu Ledru</title>
    <description>The latest articles on DEV Community by Mathieu Ledru (@matyo91).</description>
    <link>https://dev.to/matyo91</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F182978%2F61c41098-10ce-4833-acf3-b00cc42f852c.jpeg</url>
      <title>DEV Community: Mathieu Ledru</title>
      <link>https://dev.to/matyo91</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matyo91"/>
    <language>en</language>
    <item>
      <title>💫 Créateur de Hacker News - AX – L'orchestrateur agentique ouvert de Google</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 21 Sep 2026 14:03:50 +0000</pubDate>
      <link>https://dev.to/matyo91/createur-de-hacker-news-ax-lorchestrateur-agentique-ouvert-de-google-2j7g</link>
      <guid>https://dev.to/matyo91/createur-de-hacker-news-ax-lorchestrateur-agentique-ouvert-de-google-2j7g</guid>
      <description>&lt;h2&gt;
  
  
  À propos de cet article
&lt;/h2&gt;

&lt;p&gt;Google a dévoilé AX, sa dernière initiative visant à créer un « Open Agentic Orchestrator ». Cette avancée devrait influencer la manière dont les développeurs interagissent avec les systèmes d’IA en favorisant une approche davantage axée sur les agents. Les utilisateurs peuvent s’attendre à une transformation des flux de travail technologiques, qui se traduira à terme par une amélioration de la productivité et des capacités d’automatisation.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu Premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à la version supérieure pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Créateur Reddit - r/opensource : Jouez gratuitement à des jeux Windows sur Apple Silicon</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 21 Sep 2026 13:04:02 +0000</pubDate>
      <link>https://dev.to/matyo91/createur-reddit-ropensource-jouez-gratuitement-a-des-jeux-windows-sur-apple-silicon-848</link>
      <guid>https://dev.to/matyo91/createur-reddit-ropensource-jouez-gratuitement-a-des-jeux-windows-sur-apple-silicon-848</guid>
      <description>&lt;p&gt;Découvrez comment MetalSharp facilite l'exécution de jeux Windows sur les appareils Apple Silicon grâce à une configuration intuitive et à des fonctionnalités dédiées.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à la version supérieure pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Auteur sur arXiv - stat.ML : Entropie morale : analyse des biais et de l'incertitude dans le jugement moral</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:03:37 +0000</pubDate>
      <link>https://dev.to/matyo91/auteur-sur-arxiv-statml-entropie-morale-analyse-des-biais-et-de-lincertitude-dans-le-1ob8</link>
      <guid>https://dev.to/matyo91/auteur-sur-arxiv-statml-entropie-morale-analyse-des-biais-et-de-lincertitude-dans-le-1ob8</guid>
      <description>&lt;h2&gt;
  
  
  Résumé
&lt;/h2&gt;

&lt;p&gt;Cet article présente « Moral Entropy », un cadre visant à remédier aux biais inhérents aux jugements moraux. En distinguant les incertitudes aléatoires des incertitudes épistémiques, ce travail invite les développeurs à repenser les méthodes conventionnelles en matière d’éthique computationnelle.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à un abonnement supérieur pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖 Veille Darkwood - 2026-09-21</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Mon, 21 Sep 2026 05:03:49 +0000</pubDate>
      <link>https://dev.to/matyo91/veille-darkwood-2026-09-21-4d5o</link>
      <guid>https://dev.to/matyo91/veille-darkwood-2026-09-21-4d5o</guid>
      <description>&lt;h2&gt;
  
  
  Points saillants
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Orchestrateurs autonomes&lt;/strong&gt; : Démystification des systèmes AI multi-agents et déploiement à grande échelle.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure des data centers&lt;/strong&gt; : Évolution vers des écosystèmes hyper-convergés.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Éducation moderne&lt;/strong&gt; : Transformation par l'intégration technologique.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sécurité numérique&lt;/strong&gt; : Révolution grâce à l'AI.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lisez la suite pour des analyses détaillées.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Premium content.&lt;/b&gt;&lt;br&gt;⬆️ Upgrade to access full analysis.&lt;br&gt;👉 Subscribe here : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Hacker News Creator - Deux lignées parallèles de progéniteurs ectodermiques neuronaux contribuent au développement du cerveau</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 20 Sep 2026 14:03:49 +0000</pubDate>
      <link>https://dev.to/matyo91/hacker-news-creator-deux-lignees-paralleles-de-progeniteurs-ectodermiques-neuronaux-contribuent-dkf</link>
      <guid>https://dev.to/matyo91/hacker-news-creator-deux-lignees-paralleles-de-progeniteurs-ectodermiques-neuronaux-contribuent-dkf</guid>
      <description>&lt;p&gt;La récente découverte concernant les progéniteurs de l'ectoderme neural apporte un éclairage sur les complexités du développement cérébral. Ces connaissances permettent non seulement d'approfondir notre compréhension de la neurobiologie, mais ouvrent également la voie à des innovations potentielles dans les domaines médical et technologique.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à un abonnement supérieur pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🔑 Les clés secrètes deviennent des données d'application</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 20 Sep 2026 13:53:17 +0000</pubDate>
      <link>https://dev.to/matyo91/les-cles-secretes-deviennent-des-donnees-dapplication-4424</link>
      <guid>https://dev.to/matyo91/les-cles-secretes-deviennent-des-donnees-dapplication-4424</guid>
      <description>&lt;p&gt;🔑 Les clés secrètes deviennent des données d'application&lt;/p&gt;

&lt;p&gt;La plupart des applications Symfony que j’écris considèrent encore la clé du modèle comme faisant partie de l’infrastructure :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ANTHROPIC_API_KEY=...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cette ligne est simple car la propriété est simple. L’identifiant appartient au déploiement. Les opérateurs l’enregistrent dans &lt;code&gt;.env.local&lt;/code&gt; ou dans un coffre-fort de secrets. Le conteneur l’injecte une seule fois au démarrage. L’application n’a jamais à l’accepter, à le stocker ou à décider quand il est autorisé à exister en mémoire.&lt;/p&gt;

&lt;p&gt;Le modèle « Bring-your-own-key » (apportez votre propre clé) change le propriétaire.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Que se passe-t-il lorsque la clé appartient à l’utilisateur à la place ?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Elle arrive via HTTP. Elle est associée à une entité de l’application. Elle doit perdurer d’une requête à l’autre. Elle ne doit pas être stockée en clair, ne doit pas être réinsérée dans le code HTML, et ne doit être déchiffrée que lorsqu’un élément a réellement besoin d’appeler un fournisseur. Ce fournisseur peut engager des dépenses.&lt;/p&gt;

&lt;p&gt;Le fichier &lt;code&gt;.env&lt;/code&gt; n’est plus la solution. L’identifiant est devenu une donnée d’application.&lt;/p&gt;

&lt;p&gt;L’expérience de cette semaine, &lt;code&gt;navi-key-management&lt;/code&gt;, est une petite application Symfony 8.2 qui implémente ce cycle de vie puis le mesure. Je rapporte ici ce qui a été exécuté le 19/09/2026 : PHP 8.5.4, Symfony 8.2.x-dev, SQLite, Sodium local. Symfony KeyManagement est expérimental. C’est ce qu’indiquent ses docblocks d’installation. Considérez chaque signature ici comme un instantané, et non comme une promesse concernant la version stable 8.2.&lt;/p&gt;

&lt;h2&gt;
  
  
  BYOK modifie les limites
&lt;/h2&gt;

&lt;p&gt;Le chemin que j’ai codé est celui que je souhaitais pouvoir lire :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Utilisateur
  ↓
Formulaire Symfony
  ↓
Chiffrement par KeyManagement
  ↓
Texte chiffré SQLite
  ↓
Déchiffrement au moment de l’exécution
  ↓
Darkwood Navi
  ↓
Symfony AI
  ↓
Anthropic / fournisseur
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chaque flèche représente un type de traitement différent. Le formulaire ne sait pas comment une requête de chat est construite. Navi ne stocke pas les secrets. Symfony AI ne détient pas la ligne de la base de données. KeyManagement ne communique pas avec Claude.&lt;/p&gt;

&lt;p&gt;Je n’ai pas ajouté de couche de référentiel ni de deuxième SDK d’IA. Les abstractions intéressantes existaient déjà dans la pile. L’une d’entre elles pouvait facilement être mal nommée.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;darkwood/navi&lt;/code&gt; est le shell du workflow : &lt;code&gt;Action&lt;/code&gt;, &lt;code&gt;Context&lt;/code&gt;, &lt;code&gt;WorkflowRunner&lt;/code&gt;, &lt;code&gt;Event&lt;/code&gt;. Il ne comporte ni client Anthropic ni type pour une clé API. C’est Symfony AI qui communique avec le modèle. La chaîne d’exécution dans ce référentiel est la suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AiConnection
    ↓
CredentialProtector::decrypt()
    ↓
WorkflowRunner
    ↓
TestAiConnectionAction
    ↓
Anthropic\Factory::createPlatform($apiKey)
    ↓
provider
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navi orchestre une étape. Il ne remplace pas Symfony AI.&lt;/p&gt;

&lt;p&gt;Il y a eu un problème de compatibilité des paquets qui mérite d’être mentionné ici, car il est bien réel. Le paquet Packagist &lt;code&gt;darkwood/navi&lt;/code&gt; &lt;code&gt;^1.0&lt;/code&gt; nécessite toujours Symfony 8.0. Cette application a besoin de la version 8.2.x-dev ; Navi est donc un dépôt de chemin d’accès vers le monorepo local (&lt;code&gt;8.1.x-dev&lt;/code&gt;). Expérimenter avant que les contraintes de la version finale ne soient fixées, c'est ça : un lien symbolique, pas un slogan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Symfony se dote d'une primitive de gestion des clés
&lt;/h2&gt;

&lt;p&gt;Une fois que la clé est considérée comme une donnée d'application, la première pièce manquante n'est pas un autre wrapper AI. C'est un moyen de chiffrer un petit secret sans avoir à inventer un service de cryptographie.&lt;/p&gt;

&lt;p&gt;KeyManagement de Symfony 8.2 est cette fonctionnalité de base. J’ai installé &lt;code&gt;symfony/key-management&lt;/code&gt; et &lt;code&gt;symfony/aws-key-management&lt;/code&gt; sur la version 8.2.x-dev et j’ai utilisé les interfaces que le conteneur connecte automatiquement :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ciphertext&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;encrypter&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;keyId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$apiKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setCiphertextBlob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;base64_encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ciphertext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setKmsKeyId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$ciphertext&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;keyId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La méthode &lt;code&gt;encrypt()&lt;/code&gt; renvoie un objet &lt;code&gt;Ciphertext&lt;/code&gt;, et non une chaîne de caractères. La ligne regroupe le blob et l’identifiant de clé. L’application injecte les interfaces &lt;code&gt;EncrypterInterface&lt;/code&gt; et &lt;code&gt;DecrypterInterface&lt;/code&gt;. Le chiffrement par enveloppe est disponible dans le même bundle. Je ne l’ai pas utilisé. Une clé API fait plusieurs centaines d’octets, ce qui est bien en deçà de la limite de 4 Ko imposée par le chiffrement direct sur AWS KMS. Le chiffrement d’enveloppe est destiné aux fichiers et aux documents volumineux, ou à une politique stipulant que le KMS ne doit jamais avoir accès au texte en clair de l’application. Ce n’est pas obligatoire, car le composant le fournit.&lt;/p&gt;

&lt;p&gt;La configuration que j’ai finalement retenue n’est pas le DSN d’une seule ligne que j’avais d’abord essayé.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;key_management&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;clients&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sodium://?keys[app-key]=%env(DEV_KMS_KEY)%'&lt;/span&gt;
    &lt;span class="na"&gt;default_client&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;app&lt;/span&gt;

&lt;span class="na"&gt;when@prod&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;key_management&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="na"&gt;clients&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;aws-kms://default?region=%env(AWS_KMS_REGION)%'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Un simple &lt;code&gt;'%env(KMS_DSN)%'&lt;/code&gt; ne se compile pas. L’arborescence de configuration expérimentale marque le DSN du client comme &lt;code&gt;cannotBeEmpty&lt;/code&gt;, et une variable d’environnement entièrement substituée est traitée comme vide au moment de la compilation :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Le chemin « key_management.clients.app » ne peut pas contenir de variable d’environnement
lorsque les valeurs vides ne sont pas autorisées par définition et font l’objet d’une validation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le modèle de fonctionnement conserve un schéma littéral — &lt;code&gt;sodium://&lt;/code&gt; dans &lt;code&gt;dev&lt;/code&gt;/&lt;code&gt;test&lt;/code&gt;, &lt;code&gt;aws-kms://&lt;/code&gt; dans &lt;code&gt;prod&lt;/code&gt; — et ne remplace par la variable d’environnement que la clé ou la région.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dev / test
    ↓
Sodium ← testé dans ce dépôt

prod
    ↓
AWS KMS ← configuré, non appelé
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;C’est grâce à Sodium que l’expérience est reproductible localement. Le processus dispose de &lt;code&gt;DEV_KMS_KEY&lt;/code&gt;. Je l’ai générée avec &lt;code&gt;sodium_crypto_aead_xchacha20poly1305_ietf_keygen()&lt;/code&gt; et &lt;code&gt;Base64UrlSafe&lt;/code&gt;. Quiconque peut lire cette valeur d’environnement peut déchiffrer toutes les clés API stockées. C’est acceptable pour une démonstration sur un ordinateur portable. Ce n’est pas le cas en production.&lt;/p&gt;

&lt;p&gt;AWS KMS est la frontière externe vers laquelle pointe le DSN de production. Le pont AWS chiffrer côté serveur ; la clé principale est censée rester dans KMS. Je n’ai pas envoyé de requête à AWS. Le bloc de production correspond à la configuration, et non à un résultat de test.&lt;/p&gt;

&lt;p&gt;Le badge de l’interface utilisateur n’analyse pas le DSN. &lt;code&gt;KMS_BACKEND&lt;/code&gt; est une étiquette (&lt;code&gt;Sodium&lt;/code&gt; ou &lt;code&gt;AWS KMS&lt;/code&gt;), de sorte que le matériel de chiffrement ne devient jamais une variable Twig.&lt;/p&gt;

&lt;p&gt;La clé de développement enregistrée dans le fichier &lt;code&gt;.env&lt;/code&gt; de l’expérience est une clé de développement uniquement. Générez une clé privée Sodium avant d’utiliser ce modèle pour une application réelle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Une petite expérience
&lt;/h2&gt;

&lt;p&gt;Le modèle est constitué d’une seule entité, &lt;code&gt;AiConnection&lt;/code&gt; : libellé, fournisseur, modèle, point de terminaison facultatif, &lt;code&gt;ciphertextBlob&lt;/code&gt;, &lt;code&gt;kmsKeyId&lt;/code&gt;, horodatages. Il n’y a pas de colonne contenant la clé API en clair.&lt;/p&gt;

&lt;p&gt;L’interface utilisateur se compose de quatre routes et d’un panneau sombre. Elle a pour but de rendre le cycle de vie visible : une liste avec des badges « &lt;strong&gt;chiffré&lt;/strong&gt; » et « backend », un formulaire, une action de test, une page de résultats. Il ne s’agit pas d’un produit de type tableau de bord.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /
GET|POST   /connections/new
GET|POST   /connections/{id}/edit
POST /connections/{id}/test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cela constitue l'intégralité de l'interface de l'application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le formulaire est désormais une frontière de sécurité
&lt;/h2&gt;

&lt;p&gt;La clé était auparavant introduite via dotenv. Elle est désormais saisie via un formulaire. Le formulaire fait donc désormais partie intégrante de la conception de la sécurité, et n’est plus simplement une « enveloppe » d’un DTO.&lt;/p&gt;

&lt;p&gt;Symfony 8.2 peut déduire le type de formulaire à partir de la classe qui contient les données. Ce DTO comporte cinq champs. C’est à cette taille que les nouveaux attributs sont adaptés.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="na"&gt;#[AsFormType]&lt;/span&gt;
&lt;span class="k"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AiConnectionInput&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChoiceType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'choices'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'Anthropic'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'anthropic'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'OpenAI'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'openai'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;])]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$provider&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'anthropic'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

 &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FormField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PasswordType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'always_empty'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'attr'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'autocomplete'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'new-password'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;])]&lt;/span&gt;
    &lt;span class="na"&gt;#[Assert\NotBlank(groups: ['create'])]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;createForm(AiConnectionInput::class, $input)&lt;/code&gt; suffit. Il n'y a pas d'&lt;code&gt;AbstractType&lt;/code&gt;. Le nom compilé est &lt;code&gt;ai_connection_input&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Le comportement de sécurité que je souhaitais est assuré à la fois par les attributs et par le contrôleur. Le champ « key » correspond à la saisie d’un mot de passe. &lt;code&gt;always_empty&lt;/code&gt; empêche le navigateur d’afficher une valeur. Lors de la modification, le contrôleur copie le libellé, le fournisseur, le modèle et le point de terminaison dans le DTO et laisse &lt;code&gt;apiKey&lt;/code&gt; nul. Un envoi sans valeur n’appelle pas &lt;code&gt;encrypt()&lt;/code&gt; ; le texte chiffré existant est conservé. &lt;code&gt;NotBlank&lt;/code&gt; n’apparaît que dans le groupe &lt;code&gt;create&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Les formulaires basés sur des attributs m’ont évité d’écrire une classe que j’aurais autrement dû créer. Ils n’ont pas supprimé les groupes de validation ni la protection CSRF. La recette Flex « stateless-CSRF » a laissé &lt;code&gt;value="csrf-token"&lt;/code&gt; dans le code HTML et prévoyait un contrôleur Stimulus que cette application ne fournit pas. La protection CSRF par session a permis de faire fonctionner un envoi normal via le navigateur. C’est une petite leçon de la version 8.2 qui vient compléter la grande : les nouveaux attributs de formulaire s’intègrent bien dans un DTO de configuration, et ils ne suppriment pas le reste de la pile de formulaires.&lt;/p&gt;

&lt;h2&gt;
  
  
  Texte chiffré dans SQLite
&lt;/h2&gt;

&lt;p&gt;Après l’envoi par le navigateur d’une fausse clé, SQLite a conservé des métadonnées ainsi qu’un blob :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sqlite3 var/data.db "SELECT kms_key_id, length(ciphertext_blob), instr(ciphertext_blob, 'sk-ant') FROM ai_connection;"
app-key|96|0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;instr(ciphertext_blob, 'sk-ant') = 0&lt;/code&gt;. Une comparaison &lt;code&gt;LIKE&lt;/code&gt; avec la valeur soumise a également donné 0. Le texte stocké est un Base64 opaque de &lt;code&gt;Ciphertext::$blob&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Il s’agit de la preuve de persistance la plus solide de la semaine, mais elle présente une limite claire. Elle prouve que le texte en clair identifiable est absent de cette colonne. Il ne s’agit pas d’un audit cryptographique. Elle ne prouve pas que l’algorithme de chiffrement soit Sodium XChaCha, ne prouve pas la gestion des nonces, et ne prouve pas qu’un attaquant disposant de la clé principale de développement soit bloqué. PHPUnit effectue le même contrôle d’absence sur la réponse HTTP : la clé que j’ai publiée n’apparaît pas dans le code HTML.&lt;/p&gt;

&lt;p&gt;La page de liste affiche &lt;strong&gt;chiffré&lt;/strong&gt; et &lt;strong&gt;Sodium&lt;/strong&gt;. Elle n’affiche pas la clé.&lt;/p&gt;

&lt;h2&gt;
  
  
  Déchiffrer au dernier moment responsable
&lt;/h2&gt;

&lt;p&gt;La consultation d’une connexion ne déchiffre rien. Sa modification ne déchiffre rien. La clé n’est reconstruite que lorsqu’une action d’IA en a besoin.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;workflows&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;fromArray&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
 &lt;span class="s1"&gt;'connection_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getId&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
 &lt;span class="s1"&gt;'provider'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getProvider&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
 &lt;span class="s1"&gt;'model'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getModel&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
 &lt;span class="p"&gt;]),&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TestAiConnectionAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$apiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="cm"&gt;/* fournisseur, modèle, point de terminaison */&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$apiKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;str_repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\0&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;\strlen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$apiKey&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;unset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$apiKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;texte chiffré stocké
 ↓
Test de connexion / sondage
 ↓
déchiffrement
 ↓
constructeur de TestAiConnectionAction
 ↓
Factory::createPlatform($apiKey)
 ↓
une invite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;L'action marque l'argument du constructeur &lt;code&gt;#[\SensitiveParameter]&lt;/code&gt;. Le &lt;code&gt;Context&lt;/code&gt; transporte des identifiants. Il ne transporte pas le secret. C’est délibéré : le &lt;code&gt;Context&lt;/code&gt; de Navi dispose de la méthode &lt;code&gt;toArray()&lt;/code&gt;. Y placer la clé transformerait l’état de l’orchestration en une fuite d’informations.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app:probe-connection&lt;/code&gt; a signalé &lt;code&gt;context_has_secret: no&lt;/code&gt; après une exécution en production. Navi peut orchestrer l’appel sans intégrer les identifiants dans le flux de travail.&lt;/p&gt;

&lt;p&gt;Au sein de l’action, Symfony AI est instancié au moment de l’exécution. Une variable &lt;code&gt;ANTHROPIC_API_KEY&lt;/code&gt; au niveau du conteneur dans &lt;code&gt;ai.yaml&lt;/code&gt; aurait contrecarré le principe BYOK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;AnthropicFactory&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;createPlatform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;apiKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;baseUrl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s1"&gt;'https://api.anthropic.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La prompt ne comporte qu’une seule ligne : &lt;code&gt;Réponds par le mot pong.&lt;/code&gt; Si le client HTTP renvoie un message contenant la clé, &lt;code&gt;SecretRedactor&lt;/code&gt; remplace cette sous-chaîne avant que l’erreur n’atteigne Twig.&lt;/p&gt;

&lt;h2&gt;
  
  
  Une requête ayant échoué peut tout de même nous apporter des informations
&lt;/h2&gt;

&lt;p&gt;J’ai utilisé un identifiant Anthropic disponible localement via &lt;code&gt;app:probe-connection&lt;/code&gt;. Je ne vais pas l’afficher ici.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;plaintext_in_ciphertext: no
decrypt_matches: yes
context_has_secret: no
test_ok: false
test_error: Votre solde de crédit est trop faible pour accéder à l’API Anthropic. ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le chiffrement et le déchiffrement ont concordé. La clé était absente de Navi Context. La requête a quitté le processus et a atteint Anthropic. Anthropic a répondu par une erreur de facturation.&lt;/p&gt;

&lt;p&gt;Une erreur de facturation reste une preuve de la distance parcourue par la requête. Une réponse indiquant une clé invalide aurait signifié que nous ne nous étions jamais authentifiés. Nous sommes allés plus loin que cela.&lt;/p&gt;

&lt;p&gt;Il ne s’agit pas d’une opération réussie. Il ne s’agit pas d’une utilisation de jeton. Il ne s’agit pas d’un reçu. Le parcours de l’interface utilisateur avec une fausse clé affichait « La clé API est invalide. » et aucune information confidentielle. Les deux parcours d’erreur étaient utiles. Aucun des deux ne correspond à une conversation aboutie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Les clés ont un rayon d’impact économique
&lt;/h2&gt;

&lt;p&gt;L’article « Cost of a diff » de Guillaume Moigneu est à l’origine d’une idée, et non de ce code : une action d’IA a un coût économique observable. Des jetons d’entrée, des jetons de sortie, des jetons mis en cache, un modèle, un tarif.&lt;/p&gt;

&lt;p&gt;Un secret qui déverrouille un fournisseur d’IA ne sert donc pas uniquement au contrôle d’accès. Il protège quelque chose qui peut dépenser de l’argent.&lt;/p&gt;

&lt;p&gt;L’application dispose du chemin comptable. &lt;code&gt;TestAiConnectionAction&lt;/code&gt; lit l’interface &lt;code&gt;TokenUsageInterface&lt;/code&gt; de Symfony AI lorsque le résultat de l’appel contient &lt;code&gt;token_usage&lt;/code&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;jetons de prompt → entrée
jetons de complétion    → sortie
création de cache → cache_write
lecture de cache → cache_read
jetons mis en cache → mis en cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Les métriques manquantes restent &lt;code&gt;null&lt;/code&gt; et s’affichent comme « non rapportées ». &lt;code&gt;AiCostTable&lt;/code&gt; applique ensuite une liste explicite par million de dollars US datée du 19/09/2026 :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;usd = entrée  × taux_d’entrée  / 1_000_000
    + sortie × taux_de_sortie / 1_000_000
    + cache_write × cache_write_rate / 1_000_000   (si la table en comporte un)
    + cache_read  × cache_read_rate  / 1_000_000   (si la table en comporte un)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Sonnet 4.5 : dans cette table, les valeurs sont respectivement de 3 $ / 15 $ / 3,75 $ / 0,30 $. Une simulation locale avec des chiffres fictifs (42 entrées, 8 sorties) donne &lt;code&gt;0,000246 $&lt;/code&gt;. Ce chiffre est issu d’une vérification sur tableur. Il ne s’agit pas d’un reçu du fournisseur.&lt;/p&gt;

&lt;p&gt;Aucune transaction payante n’a abouti cette semaine. Le chemin de facturation existe. Il n’a pas été validé par rapport aux métadonnées d’utilisation fournies par Anthropic. Je ne vais pas inventer de jetons pour donner l’impression que l’interface utilisateur est terminée.&lt;/p&gt;

&lt;h2&gt;
  
  
  Le fournisseur n’est pas un point de terminaison
&lt;/h2&gt;

&lt;p&gt;Claude, via un abonnement Azure AI, fonctionnait en redirigeant le pont Anthropic existant vers une URL de messages compatible avec Anthropic, plutôt qu’en ajoutant une nouvelle abstraction Azure-Claude.&lt;/p&gt;

&lt;p&gt;La structure rapportée était la suivante :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;resource&amp;gt;.services.ai.azure.com/anthropic/v1/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Le test rapporté comprenait un échange de messages complet et la mise en cache des invites. Je ne répéterai pas les identités privées mentionnées dans ce fil de discussion.&lt;/p&gt;

&lt;p&gt;La méthode &lt;code&gt;Factory::createPlatform()&lt;/code&gt; d’Anthropic déjà installée dispose déjà de &lt;code&gt;$baseUrl&lt;/code&gt;. &lt;code&gt;ModelClient&lt;/code&gt; envoie des requêtes vers &lt;code&gt;{baseUrl}/v1/messages&lt;/code&gt;. Le point de terminaison facultatif du formulaire correspond donc à la base Azure sans ce suffixe :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://&amp;lt;resource&amp;gt;.services.ai.azure.com/anthropic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;baseUrl&lt;/code&gt; est configurée. L’appel à Azure Anthropic n’a pas été effectué.&lt;/p&gt;

&lt;p&gt;Bedrock ne fonctionne pas de la même manière. Il s’authentifie à l’aide d’identifiants AWS, et non d’une clé Anthropic associée à un hôte. La compatibilité était un problème de point de terminaison pour la passerelle Azure. Il s’agit d’un problème de modèle d’authentification pour Bedrock. Je n’ai pas ajouté de couche Bedrock.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;L’identité du fournisseur, le point de terminaison de transport et le stockage des identifiants sont des préoccupations distinctes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Parfois, la compatibilité est une question de configuration, et non une autre abstraction. C’est la même habitude que de garder Navi hors de la persistance et Symfony AI hors du formulaire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sodium en local, KMS en externe
&lt;/h2&gt;

&lt;p&gt;Je ne vais pas transformer cet article en tutoriel de cryptographie. La différence opérationnelle suffit.&lt;/p&gt;

&lt;p&gt;Avec Sodium, l’application détient la clé de chiffrement et peut déchiffrer chaque ligne qu’elle a écrite. L’expérience est exécutable sans compte AWS. La compromission de &lt;code&gt;DEV_KMS_KEY&lt;/code&gt; équivaut à la compromission des clés API stockées.&lt;/p&gt;

&lt;p&gt;Avec AWS KMS, l’application interroge un service externe. La clé principale est censée rester en dehors du stockage de l’application. La compromission du fichier &lt;code&gt;.env&lt;/code&gt; ne suffit pas ; un attaquant a toujours besoin des identifiants AWS et d’une politique de clé autorisant le déchiffrement.&lt;/p&gt;

&lt;p&gt;Il s’agit d’une amélioration en matière de gestion des clés. Ce n’est pas une protection miracle contre un environnement d’exécution compromis. Si l’application en cours d’exécution peut appeler &lt;code&gt;decrypt()&lt;/code&gt;, un attaquant suffisamment présent peut également l’appeler. L’avantage réside dans le fait que la clé principale n’est pas une chaîne d’octets placée à côté du texte chiffré, et que le chiffrement et le déchiffrement peuvent être audités en dehors de l’application. J’ai vérifié le premier cas de figure. J’ai configuré le second.&lt;/p&gt;

&lt;h2&gt;
  
  
  L’IA modifie les deux facettes de la sécurité
&lt;/h2&gt;

&lt;p&gt;Symfony recevait auparavant environ un rapport de sécurité par trimestre et qu’il en reçoit désormais au moins un par jour. Les agents analysent une nouvelle version dès sa sortie. Un rapport arrivant dans la boîte de réception doit être considéré comme déjà public. Les embargos partaient du principe que la découverte d’une faille coûtait cher.&lt;/p&gt;

&lt;p&gt;Il ne s’agit pas d’un CVE dans cette application. Je n’associe pas cette expérience à un avis numéroté.&lt;/p&gt;

&lt;p&gt;Le lien pertinent est d’ordre économique. Les agents réduisent le coût de la recherche, dans une base de code, de l’endroit où un secret fuit. Parallèlement, un identifiant généré par l’IA a une valeur financière directe : il peut être dépensé. Ces deux faits combinés expliquent pourquoi la gestion BYOK (Bring Your Own Key) relève de l’architecture de l’application plutôt que de la gestion du déploiement.&lt;/p&gt;

&lt;p&gt;Les choix concrets dans le dépôt sont volontairement simples : pas de colonne en texte clair, pas de saisie de mot de passe, pas de réaffichage, décryptage uniquement pour l’exécution, clé absente de Navi Context, faux fichier &lt;code&gt;.env.example&lt;/code&gt;, badge backend sans DSN. KeyManagement se charge du chiffrement. Le reste relève des bonnes pratiques de sécurité, car l’objet que nous protégeons est désormais une ligne de base de données.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce qui a réellement fonctionné
&lt;/h2&gt;

&lt;p&gt;Ces vérifications ont été effectuées.&lt;/p&gt;

&lt;p&gt;Container, Twig et YAML ont passé les vérifications de syntaxe sans erreur.&lt;/p&gt;

&lt;p&gt;PHPUnit : 2 tests, 15 assertions, OK. Un test effectue un chiffrement et un déchiffrement via Sodium et vérifie que le texte en clair est absent du blob de l’entité. L’autre envoie le formulaire basé sur les attributs et vérifie que la clé est absente de SQLite et du code HTML.&lt;/p&gt;

&lt;p&gt;Dans le navigateur, j’ai ajouté une connexion, j’ai vu les badges « crypté » et « Sodium », j’ai ouvert l’édition avec un champ de clé API vide, puis j’ai testé un faux identifiant. Le fournisseur a répondu : « Clé API non valide. »&lt;/p&gt;

&lt;p&gt;SQLite après cette soumission :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;instr(ciphertext_blob, 'sk-ant') = 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La sonde Anthropic en direct :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;chiffrement/déchiffrement : correspondance
identifiants dans le contexte Navi : non
fournisseur atteint : oui
résultat : erreur de facturation — solde créditeur trop faible
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Telles sont les conclusions que je suis prêt à défendre.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ce que je n’ai pas vérifié
&lt;/h2&gt;

&lt;p&gt;AWS KMS a été configuré mais n’a pas été appelé.&lt;/p&gt;

&lt;p&gt;La &lt;code&gt;baseUrl&lt;/code&gt; d’Anthropic sur Azure a été configurée mais n’a pas été appelée.&lt;/p&gt;

&lt;p&gt;Aucune opération payante sur Anthropic n’a abouti. Par conséquent, aucun jeton n’a été réellement reçu, et la comptabilisation des coûts n’a pas été validée par rapport à une réponse positive du fournisseur.&lt;/p&gt;

&lt;p&gt;KeyManagement reste expérimental.&lt;/p&gt;

&lt;p&gt;« Implémenté », « configuré », « testé » et « vérifié » sont quatre termes distincts. Cette semaine, j’ai utilisé les quatre. Je ne les confonds pas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Le fichier &lt;code&gt;.env&lt;/code&gt; est un bon modèle lorsque le secret appartient au déploiement.&lt;/p&gt;

&lt;p&gt;Le BYOK change de propriétaire.&lt;/p&gt;

&lt;p&gt;Dès lors qu’un identifiant appartient à un utilisateur de l’application, il nécessite un cycle de vie propre à l’application : saisie, chiffrement, persistance, exécution, observabilité et, à terme, rotation. La gestion des clés de Symfony 8.2 est une primitive utile pour l’étape de chiffrement. Il est expérimental, et son arbre de configuration est pointilleux sur les variables d’environnement, mais les interfaces que j’ai testées — chiffrer un petit secret, stocker un &lt;code&gt;Ciphertext&lt;/code&gt;, déchiffrer au dernier moment — sont celles dont BYOK a réellement besoin.&lt;/p&gt;

&lt;p&gt;Navi n’a pas besoin de devenir un gestionnaire de secrets. Symfony AI n’a pas besoin de gérer la persistance. Le formulaire n’a pas besoin de savoir comment la requête IA est construite.&lt;/p&gt;

&lt;p&gt;Chaque couche peut rester légère. La clé n’est plus une ligne dans &lt;code&gt;.env&lt;/code&gt;. C’est une ligne de table, un texte chiffré, un argument de constructeur et un élément de ligne. C’est là tout le changement.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Auteur sur Reddit - r/opensource : Un projet CAPTCHA open source serait-il une bonne idée ?</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 20 Sep 2026 13:04:00 +0000</pubDate>
      <link>https://dev.to/matyo91/auteur-sur-reddit-ropensource-un-projet-captcha-open-source-serait-il-une-bonne-idee--271p</link>
      <guid>https://dev.to/matyo91/auteur-sur-reddit-ropensource-un-projet-captcha-open-source-serait-il-une-bonne-idee--271p</guid>
      <description>&lt;h2&gt;
  
  
  À propos de cet article
&lt;/h2&gt;

&lt;p&gt;Une discussion communautaire s’est engagée autour de la possibilité de créer un projet CAPTCHA open source, soulignant la nécessité de solutions respectueuses de la vie privée et auto-hébergées que les développeurs puissent facilement intégrer.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à un abonnement supérieur pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖 Veille Darkwood - 2026-09-20</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sun, 20 Sep 2026 05:03:07 +0000</pubDate>
      <link>https://dev.to/matyo91/veille-darkwood-2026-09-20-33np</link>
      <guid>https://dev.to/matyo91/veille-darkwood-2026-09-20-33np</guid>
      <description>&lt;h2&gt;
  
  
  Points saillants
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;L'AI a amélioré la tolérance au risque dans l'investissement automatisé.&lt;/li&gt;
&lt;li&gt;De nouvelles compétences d'agent ont été identifiées, dont certaines compromettent la sécurité.&lt;/li&gt;
&lt;li&gt;Des applications agents poussent les logiciels d'entreprise au-delà des systèmes traditionnels.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚨 &lt;b&gt;Premium content.&lt;/b&gt;&lt;br&gt;⬆️ Upgrade to access full analysis.&lt;br&gt;👉 Subscribe here : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Hacker News Creator : Claude Code lit désormais le fichier AGENTS.md s'il n'y a pas de fichier Claude.md</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sat, 19 Sep 2026 14:03:29 +0000</pubDate>
      <link>https://dev.to/matyo91/hacker-news-creator-claude-code-lit-desormais-le-fichier-agentsmd-sil-ny-a-pas-de-fichier-328g</link>
      <guid>https://dev.to/matyo91/hacker-news-creator-claude-code-lit-desormais-le-fichier-agentsmd-sil-ny-a-pas-de-fichier-328g</guid>
      <description>&lt;h2&gt;
  
  
  À propos de cet article
&lt;/h2&gt;

&lt;p&gt;La récente mise à jour de Claude Code met l'accent sur sa polyvalence, lui permettant de lire le fichier AGENTS.md en l'absence de Claude.md. Cette évolution pourrait améliorer l'expérience utilisateur en fournissant un contexte et des fonctionnalités pertinents sans intervention manuelle.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à la version supérieure pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Créateur Reddit - r/opensource : Présentation de Presume, une bibliothèque de tests basés sur les propriétés pour Java sous licence MIT</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sat, 19 Sep 2026 13:03:43 +0000</pubDate>
      <link>https://dev.to/matyo91/createur-reddit-ropensource-presentation-de-presume-une-bibliotheque-de-tests-bases-sur-les-3od1</link>
      <guid>https://dev.to/matyo91/createur-reddit-ropensource-presentation-de-presume-une-bibliotheque-de-tests-bases-sur-les-3od1</guid>
      <description>&lt;h2&gt;
  
  
  À propos de cet article
&lt;/h2&gt;

&lt;p&gt;Découvrez Presume, une nouvelle bibliothèque de tests basés sur les propriétés pour Java, dotée d’une API impérative conviviale et distribuée sous licence MIT. Cette bibliothèque vise à fournir aux développeurs un outil polyvalent permettant de générer efficacement des données complexes, comblant ainsi le fossé entre les méthodes de test traditionnelles et les approches modernes.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à la version supérieure pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🤖 Veille Darkwood - 2026-09-19</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Sat, 19 Sep 2026 05:03:19 +0000</pubDate>
      <link>https://dev.to/matyo91/veille-darkwood-2026-09-19-52m</link>
      <guid>https://dev.to/matyo91/veille-darkwood-2026-09-19-52m</guid>
      <description>&lt;h2&gt;
  
  
  Points saillants
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;VFLO Index&lt;/strong&gt; : Analyse de la résilience SaaS.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GeneSign&lt;/strong&gt; : Agent de biosécurité autonome innovant.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Grok API&lt;/strong&gt; : Simplification de la veille technologique en IA.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🚨 &lt;b&gt;Premium content.&lt;/b&gt;&lt;br&gt;⬆️ Upgrade to access full analysis.&lt;br&gt;👉 Subscribe here : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>💫 Bluesky Creator - @martinfowler.com : Réflexions sur le piratage de RubyGems</title>
      <dc:creator>Mathieu Ledru</dc:creator>
      <pubDate>Fri, 18 Sep 2026 15:04:41 +0000</pubDate>
      <link>https://dev.to/matyo91/bluesky-creator-martinfowlercom-reflexions-sur-le-piratage-de-rubygems-130c</link>
      <guid>https://dev.to/matyo91/bluesky-creator-martinfowlercom-reflexions-sur-le-piratage-de-rubygems-130c</guid>
      <description>&lt;h2&gt;
  
  
  À propos de cet article
&lt;/h2&gt;

&lt;p&gt;Découvrez l'analyse de Martin Fowler sur le piratage de RubyGems, dans laquelle il aborde deux explications inquiétantes ainsi que la réalité des agents d'IA.&lt;/p&gt;

&lt;p&gt;🚨 &lt;b&gt;Contenu premium.&lt;/b&gt;&lt;br&gt;⬆️ Passez à un abonnement supérieur pour accéder à l'analyse complète.&lt;br&gt;👉 Abonnez-vous ici : &lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;a href="https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php" rel="noopener noreferrer"&gt;https://www.bonzai.pro/matyo91/shop/48ov_2168/automation-avec-flow-en-php&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
