---
title: "Secrets"
description: "Comment Beeuni stocke les identifiants du projet et contrôle si le code de l’agent peut lire chaque valeur."
---

Un secret est un identifiant propre à un projet — une clé API, un jeton ou une chaîne de connexion — dont une session a besoin, mais qui ne doit pas se trouver dans le dépôt.
Beeuni stocke les secrets dans le projet, jamais dans le compte, et chiffre chaque valeur avec AES-256-GCM à l’aide d’une clé dérivée pour chaque projet.

<a id="identifier-and-name"></a>

## Identifiant et nom

Chaque secret a deux noms. Le `identifier` est l’identifiant que vous utilisez dans la CLI et dans l’octroi `secrets` d’un agent. Le `name` est la clé de variable d’environnement en majuscules dans le bac à sable, par exemple `STRIPE_API_KEY`. Dans la plupart des projets, l’identifiant et le nom sont identiques. Ils ne diffèrent que lorsqu’un projet contient plusieurs valeurs possibles pour un même nom — par exemple, une clé Google Maps principale et une clé de secours peuvent toutes deux correspondre à `GOOGLE_MAPS_API_KEY`.

Toutes les règles d’accès utilisent l’identifiant. Aucune n’utilise le nom.

<a id="exposure-and-usage"></a>

## Exposition et utilisation

Un secret comporte deux paramètres indépendants. Examinez-les séparément : ils répondent à des questions différentes.

| Paramètre | Question à laquelle il répond | Valeurs |
|---|---|---|
| **Exposition** | Le code de l’agent peut-il lire la valeur réelle ? | `environment`, `egress-enforced`, `none` |
| **Utilisation** | Qui la dépense ? | Code de l’agent, passerelle LLM, connecteur, Git |

L’ancienne documentation Beeuni présentait une liste unique mêlant les deux. Elle n’existe plus. Il n’y a pas de choix entre une « frontière réseau » et un « mandataire HTTPS » : un seul mécanisme s’applique à tous les secrets soumis à l’application des règles de sortie, quel que soit le fournisseur de bac à sable.

<a id="the-three-exposures"></a>

### Les trois expositions

| Exposition | Contenu du bac à sable | À utiliser pour |
|---|---|---|
| **Environnement** | La valeur réelle, sous forme de variable d’environnement en clair | Le choix par défaut. Les valeurs avec lesquelles l’agent doit effectuer des calculs, et les protocoles autres que HTTPS |
| **Sortie contrôlée** | Un **handle** — un espace réservé auto-descriptif, sans valeur en soi | Expérimental. Les appels HTTPS, une fois le flag `secrets_egress` activé |
| **Aucune** | Rien du tout | Un identifiant utilisé uniquement par un service Beeuni, ou une valeur conservée dans le dossier et désactivée |

:::warning[Règle pratique]
**Environnement** est l’exposition par défaut. La valeur réelle est chargée dans le bac à sable, où l’agent peut la lire, l’afficher et la transmettre. **Sortie contrôlée** maintient la valeur hors du bac à sable, mais cette fonctionnalité est expérimentale : activez le flag de fonctionnalité `secrets_egress` (Settings → Feature flags) pour l’utiliser. D’ici là, un secret est chargé dans l’environnement du bac à sable.
:::

<a id="usages"></a>

### Utilisations

La plupart des utilisations sont attribuées par Beeuni, et non par vous :

- **Code de l’agent** — implicite dès que l’exposition n’est pas `none`.
- **Passerelle LLM** — attribuée lorsque la valeur est une clé reconnue d’un fournisseur de modèles. La passerelle authentifie les requêtes au fournisseur côté serveur.
- **Connector:&lt;slug&gt;** — attribuée par le processus de liaison du connecteur.
- **Git** — attribuée par Beeuni pour son propre accès à Git. Lecture seule ; vous ne pouvez ni la définir ni la supprimer.

Un secret dont l’exposition est `none` et qui n’a aucune utilisation apparaît comme **Désactivé** : il est stocké, chiffré et n’est utilisé par rien.

<a id="sent-secrets-and-computed-secrets"></a>

## Secrets transmis et secrets calculés

L’exposition qu’un secret peut utiliser dépend de la **source en amont**, et non de Beeuni.

- **Secrets transmis** — la valeur est transmise sur le réseau. Clés API, jetons Bearer, mots de passe. C’est le cas le plus courant. À un moment donné, la valeur se trouve dans une requête sortante sous forme d’octets ; Beeuni peut donc l’y insérer lui-même, hors du bac à sable. Un secret transmis peut passer en **sortie contrôlée** une fois le flag `secrets_egress` activé ; par défaut, il est chargé dans l’environnement du bac à sable.
- **Secrets calculés** — la valeur entre dans un calcul et n’est jamais transmise. Clés de signature AWS SigV4, secrets de signature HMAC de webhook, assertions de client JWT, clés privées SSH. Celui qui effectue le calcul doit détenir la valeur. Une frontière réseau n’y change rien, puisque les identifiants ne figurent pas dans les données transmises. Les secrets calculés doivent rester dans **l’environnement**.

L’environnement est l’exposition par défaut et la seule qui puisse servir un identifiant sur lequel le bac à sable doit effectuer des calculs. Les protocoles autres que HTTPS — chaîne de connexion Postgres, identifiants SMTP — sont dans le même cas : ils doivent rester dans l’environnement.

Lorsque vous enregistrez une valeur qui ressemble à du matériel de signature, comme une paire de clés d’accès `AKIA…` ou du matériel PEM/SSH, Beeuni choisit **Environnement** par défaut et en explique la raison : cette clé signe les requêtes localement, donc l’application des règles de sortie ne peut pas s’appliquer.

<a id="egress-enforced-exposure"></a>

## Exposition à sortie contrôlée

:::warning[Expérimental — nécessite le flag secrets_egress]
L’application des règles au niveau du réseau est expérimentale. Activez le flag de fonctionnalité `secrets_egress` (Settings → Feature flags) pour l’utiliser. D’ici là, un secret est chargé dans l’environnement du bac à sable. Si le flag est désactivé, la création d’un secret à sortie contrôlée renvoie `403` `feature_disabled`.
:::

Le bac à sable reçoit une variable d’environnement dont la valeur est un **handle**, et non l’identifiant. L’agent utilise cette variable comme il utiliserait la vraie clé — dans un en-tête, une chaîne de requête ou un corps. `Authorization: Bearer $VAR`, `Cookie: …=$VAR`, un en-tête `X-Api-Key`, un paramètre de requête et un champ de corps JSON ou de formulaire fonctionnent tous : Beeuni repère le handle où qu’il apparaisse (brut, encodé dans une URL, en base64 seul ou échappé dans du JSON) et le remplace par la valeur réelle. À la sortie, Beeuni remplace le handle par la valeur réelle, mais uniquement pour les requêtes vers les hôtes que vous avez approuvés.

:::warning[Envoyez le handle tel quel — ne l’encodez pas vous-même en base64]
Une chose ne fonctionne pas : cacher le handle dans un bloc base64 que vous créez vous-même, comme le fait l’**authentification HTTP Basic** (`curl -u $VAR:` → `Authorization: Basic <base64>`). Beeuni ne peut pas repérer un handle incorporé et non aligné dans une chaîne base64 que vous avez encodée ; le remplacement n’a donc jamais lieu et le serveur en amont répond `401`. Placez plutôt le handle dans un en-tête Bearer/token, un paramètre de requête ou un champ du corps. Si l’API ne prend en charge que l’authentification Basic, utilisez l’exposition **Environnement** pour ce secret.
:::


Conséquences de ce fonctionnement :

- La valeur réelle ne se trouve **jamais** dans le bac à sable : ni comme variable d’environnement, ni dans un fichier, ni sous forme d’alias.
- Un handle envoyé à un hôte que vous n’avez pas approuvé lui parvient sous forme de chaîne littérale. Le serveur en amont le rejette. Il ne vaut rien.
- Un handle dont la signature est invalide n’est jamais accepté et Beeuni le consigne comme handle falsifié. Un handle valide associé à un secret que cette session n’est pas autorisée à utiliser est consigné comme volé.
- Chaque requête relayée génère une entrée d’audit par requête.
- Les requêtes vers les hôtes qui ne figurent pas dans la liste sont acheminées par le tunnel sans être lues. Les clients avec TLS épinglé et mTLS vers ces hôtes ne sont pas affectés.

<a id="hosts-match-exactly"></a>

### Correspondance exacte des hôtes

Indiquez chaque hôte appelé, avec un nom d’hôte exact par ligne.

| Rejeté | Motif |
|---|---|
| Un hôte générique, `*.example.com` | L’agent ne doit jamais choisir la destination |
| Un schéma d’URL autre que HTTPS | Beeuni termine la connexion TLS pour effectuer la substitution |

`api.example.com` ne couvre pas `uploads.api.example.com`. Ajoutez le second hôte au même secret. Beeuni rejette les règles inapplicables avec `400` lorsque vous les enregistrez : il ne stocke jamais une règle qu’il ne peut pas appliquer.

Deux secrets soumis à l’application des règles de sortie peuvent partager un hôte. Chaque identifiant correspond à sa propre valeur, qui est donc correctement substituée dans la même requête.

<a id="verify-it-with-two-probes"></a>

### Vérifiez avec deux sondes

Exécutez les deux sondes depuis le bac à sable, vers un hôte figurant sur la liste.
L’exemple utilise `postman-echo.com`, qui propose un point de terminaison de chaque type.
Ajoutez-le à la liste des hôtes autorisés pour la durée du test.

```bash
# 1. Reachability — an endpoint that does NOT echo request headers.
curl -s -o /dev/null -w '%{http_code}\n' https://postman-echo.com/status/200
# expected: 200

# 2. Substitution — an endpoint that DOES echo request headers.
curl -sS -H "authorization: Bearer $STRIPE_API_KEY" https://postman-echo.com/get
# expected: 200, with "Bearer [REDACTED]" in the echoed headers
```

Examinez les deux résultats ensemble, en commençant par la sonde 1 : c’est la seule qui indique si l’hôte est joignable, et la sonde 2 ne prouve rien tant qu’elle n’a pas réussi.

| Résultat de la sonde 2 | Signification |
|---|---|
| `200`, l’en-tête renvoyé affiche `[REDACTED]` | Fonctionne. La vraie valeur a été transmise en amont et la réponse renvoyée a été expurgée. |
| `200`, l’en-tête renvoyé affiche l’identifiant lui-même | La substitution n’a pas eu lieu. Vérifiez la liste des hôtes et l’autorisation accordée à l’agent. |
| `401` depuis un véritable hôte d’API | La substitution n’a pas eu lieu. Même vérification. |
| Réponse vide ou erreur de connexion | Il s’agit d’un véritable échec, pas d’un signe de réussite. |

Vérifiez que la vraie valeur n’est présente nulle part dans l’environnement invité :

```bash
env | grep '^STRIPE_API_KEY='
# expected: the handle, not the credential
```

L’identifiant figure également dans `BEEUNI_SECRET_CAPABILITIES`, le catalogue sans valeurs qui indique à l’agent quels secrets existent, quelle variable contient chaque identifiant et quels hôtes sont couverts par chacun. Il ne contient jamais de valeur.

Un hôte figurant sur la liste présente un certificat délivré par Beeuni pour ce bac à sable, auquel celui-ci fait déjà confiance, plutôt que le certificat de l’origine :

```bash
curl -sv https://postman-echo.com/status/200 2>&1 | grep 'issuer:'
# issuer: CN=Beeuni Egress CA (<project prefix>); O=Beeuni
```

<a id="what-the-relay-changes"></a>

### Ce que change le relais

Un hôte approuvé est joint via Beeuni ; son comportement diffère donc légèrement d’un appel direct :

- Les réponses ne sont pas diffusées en flux. Les événements envoyés par le serveur et les websockets ne fonctionnent pas via un hôte approuvé.
- Le corps d’une requête est limité à 1 Mio, une réponse à 5 Mio et la durée totale de l’appel à 30 secondes. Beeuni suit au maximum 3 redirections.
- Seul un ensemble fixe d’en-têtes de réponse est renvoyé : le type et la langue du contenu, les validateurs de cache, les en-têtes de limitation du débit, `retry-after`, `x-request-id`.
- Seuls les clients qui respectent `https_proxy` sont interceptés. Beeuni définit cette variable et la confiance correspondante dans l’autorité de certification dans l’environnement de l’agent. Un processus lancé avec un environnement nettoyé appelle directement l’hôte, et sa requête part avec l’identifiant.

Pour les requêtes que Beeuni ne peut pas intercepter, l’agent dispose d’un accès explicite aux mêmes hôtes, selon la même politique :

```bash
beeuni secrets call STRIPE_API_KEY https://api.stripe.com/v1/customers
```

<a id="environment-exposure"></a>

## Exposition via l’environnement

Le bac à sable reçoit la vraie valeur sous forme de variable d’environnement ordinaire. Le code de l’agent peut la lire, l’afficher et la transmettre n’importe où. Beeuni ne peut ni l’expurger, ni auditer son utilisation, ni empêcher qu’elle soit divulguée.

L’exposition via l’environnement est celle par défaut. Chaque nouveau secret l’utilise, sauf si vous le déplacez vers le mode soumis à l’application des règles de sortie, qui est expérimental et nécessite le drapeau `secrets_egress`. Un identifiant calculé et tout protocole autre que HTTPS doivent rester dans l’environnement.

<a id="who-can-use-a-secret"></a>

## Qui peut utiliser un secret

Chaque valeur secrète a un public — le même choix **Qui peut l’utiliser** que pour un compte de connecteur :

| Choix | Qui peut utiliser la valeur |
| --- | --- |
| **Tout le monde dans le projet** (par défaut) | Chaque session du projet, y compris les déclencheurs, les tâches planifiées et les sessions partagées. |
| **Vous uniquement** | Vous, directement, et vos propres sessions privées. |
| **Personnes, groupes ou agents spécifiques** | Les personnes et groupes que vous choisissez (directement et dans leurs propres sessions privées), ainsi que les agents sélectionnés (dans toutes leurs sessions). |

Une session correspond à deux entités à la fois : son **agent**, toujours, et sa **personne**, uniquement tant que la session est privée.

- **Une personne** accède à une valeur dans une session **privée** démarrée par cette personne. Un message de quelqu’un d’autre efface la personne associée à la session : la valeur cesse alors d’y être accessible. Les sessions partagées, les déclencheurs, les tâches planifiées, les webhooks et les sessions par e-mail ou Telegram n’ont pas de personne.
- **Un agent** accède à une valeur dans chacune de ses sessions, y compris les déclencheurs, les tâches planifiées et les sessions partagées. Partagez une valeur avec l’agent si une exécution sans surveillance en a besoin. Toute personne pouvant exécuter cet agent peut alors utiliser la valeur par son intermédiaire : l’accès dépend donc de l’autorisation d’exécuter l’agent (les personnes autorisées sont définies dans les paramètres de l’agent).
- Les consommateurs côté serveur suivent la même règle. Un connecteur associé au secret ne l’utilise que pour les appelants qui font partie du public autorisé. Les autres obtiennent `credential_not_shared`, et aucune requête ne quitte Beeuni.
- Les services Beeuni qui n’agissent pour personne — le proxy Git, la vérification des signatures de webhook, les installations de canaux et les applications Beeuni — utilisent uniquement les valeurs partagées avec tout le monde.

Plusieurs valeurs peuvent porter le même nom. Une valeur partagée avec la personne de la session prévaut sur celle partagée avec son agent, qui prévaut à son tour sur celle partagée avec tout le monde. Exemple : `DEEL_API_TOKEN` contient une valeur d’équipe, et une seconde valeur portant l’identifiant `DEEL_API_TOKEN-finance` est partagée uniquement avec le groupe Finance. Les membres de Finance obtiennent la valeur Finance dans leurs sessions privées ; tous les autres, ainsi que chaque déclencheur, obtiennent la valeur de l’équipe.

Une personne définit le public. Une session d’agent ne peut pas le modifier (`403`) : un agent ne peut donc ni élargir l’accès à une valeur dont il a été exclu, ni s’y ajouter. Les personnes qui gèrent les secrets du projet voient tout de même les valeurs qui ne leur sont pas partagées, avec la mention **Non partagé avec vous**, afin de pouvoir en élargir l’accès.

<a id="sharing-a-session-that-holds-a-personal-value"></a>

### Partager une session contenant une valeur personnelle

Une valeur partagée uniquement avec vous, qui a été transmise à votre session privée sous forme de **variable d’environnement**, est en clair dans ce bac à sable. Partager la session permettrait à chaque nouveau participant de la lire, et une variable d’environnement ne peut pas être retirée d’un bac à sable en cours d’exécution. Beeuni refuse donc de partager cette session ou de créer un lien public vers celle-ci si elle contient `409 PERSONAL_SECRET_REQUIRES_PRIVATE_SESSION` et les noms associés. Démarrez une nouvelle session pour la partager ou partagez d’abord la valeur avec tout le monde. Les valeurs accessibles via l’agent, ainsi que celles soumises à l’application des règles de sortie ou utilisées côté serveur (vérifiées à chaque requête), n’empêchent pas le partage.

Lorsque vous restreignez le public, Beeuni transmet de nouveau les paramètres à chaque bac à sable en cours d’exécution. Une valeur déjà transmise comme variable d’environnement reste dans le bac à sable jusqu’à son redémarrage. Si elle a pu être lue, faites-la tourner.

<a id="when-you-enter-a-value-through-a-link"></a>

### Saisir une valeur via un lien

Un agent qui a besoin d’une valeur que vous ne lui avez pas fournie vous envoie un lien. La page du lien propose le choix **Qui peut l’utiliser** : tout le monde dans le projet (par défaut) ou uniquement la personne qui l’a demandé. Choisissez la seconde option pour toute information personnelle, comme un jeton de paie ou des identifiants de connexion personnels. La page indique le nom d’affichage de la personne qui en a fait la demande, jamais son adresse e-mail, car toute personne disposant du lien peut l’ouvrir.

<a id="personal-override"></a>

### Remplacement personnel

Un remplacement personnel est votre propre valeur pour un nom donné. Elle est utilisée à la place de la valeur partagée dans les sessions que vous démarrez. Pour l’instant, Beeuni l’utilise uniquement pour un identifiant de connexion OAuth. Beeuni ne permet jamais, par exemple, d’utiliser une clé de fournisseur LLM comme `ANTHROPIC_API_KEY` en tant que remplacement personnel.

<a id="add-a-secret"></a>

## Ajouter un secret

1. **Définir la valeur depuis la CLI**

    ```bash
    beeuni secrets set STRIPE_API_KEY=sk_live_...
    ```

    Beeuni l’enregistre pour tout le monde dans le projet. Ajoutez `--only-me` pour qu’elle ne soit utilisable que par vous. Pour stocker plusieurs valeurs sous le même nom, ajoutez `--identifier <id>`. Les noms ne peuvent pas commencer par `BEEUNI_` : Beeuni réserve ce préfixe aux valeurs de la plateforme.

    Modifier les personnes autorisées à l’utiliser ultérieurement :

    ```bash
    beeuni secrets share DEEL_API_TOKEN --user me
    beeuni secrets share DEEL_API_TOKEN --user finance@example.com --group <group-id>
    beeuni secrets share NIGHTLY_REPORT_TOKEN --agent reporter
    beeuni secrets share DEEL_API_TOKEN --everyone
    ```

2. **Ou utilisez le tableau de bord**

    Ouvrez la page Secrets du projet, saisissez la clé et la valeur, choisissez **Qui peut l’utiliser** et enregistrez. Beeuni chiffre immédiatement la valeur et définit par défaut chaque nouveau secret sur **Tout le monde dans le projet** et une exposition **environnement** — la vraie valeur est chargée dans le bac à sable. La colonne **Qui peut l’utiliser** indique le public de chaque valeur.

    Pour passer un secret à une exposition avec contrôle de sortie réseau, activez d’abord l’indicateur de fonctionnalité `secrets_egress` (Settings → Feature flags) ; cette fonctionnalité est expérimentale. Une fois l’indicateur activé, la page Secrets affiche le contrôle **« Votre code peut-il lire cette valeur ? »** : répondre *non* fait passer le secret au contrôle de sortie réseau et affiche la liste des hôtes ; répondre *oui* conserve l’exposition environnement. Lorsque l’indicateur est désactivé, le secret reste en exposition environnement.

3. **Accorder l’accès à un agent**

    Choisissez un agent sur la page Secrets ou ajoutez vous-même l’identifiant à la liste `secrets` de cet agent dans `beeuni.yaml`. Une session ne reçoit que les secrets accordés à son agent. Voir [Accorder un secret à un
    agent](#grant-a-secret-to-an-agent).

<a id="grant-a-secret-to-an-agent"></a>

## Accorder un secret à un agent

Une session ne reçoit un secret que si l’agent qui l’exécute indique l’identifiant dans sa liste `secrets`. La correspondance se fait avec l’identifiant, pas le nom, sans tenir compte de la casse.

:::warning[Les utilisations avec contrôle de sortie réseau et par les services nécessitent une autorisation explicite]
`secrets: all` n’accorde que l’exposition environnement. Un secret avec contrôle de sortie réseau, ainsi que tout secret utilisé par un service Beeuni, doit être explicitement inscrit dans la liste d’un agent. Un projet sans bloc `agents:` dans `beeuni.yaml` n’en reçoit jamais. Un secret non autorisé est ignoré sans avertissement : la session démarre normalement et le premier appel à l’hôte échoue comme si les identifiants étaient incorrects.
:::

<a id="from-the-dashboard"></a>

### Depuis le tableau de bord

La page Secrets signale les secrets qu’aucun agent ne peut recevoir : **Aucun agent ne peut recevoir ce secret**. Choisissez un agent et confirmez. Beeuni modifie `beeuni.yaml` et l’enregistre sous la forme `chore(agents): grant <IDENTIFIER> to <agent>`.

L’autorisation fonctionne que le manifeste déclare déjà l’agent ou non. Si l’agent n’est pas déclaré dans le manifeste, une nouvelle entrée contenant cette seule liste `secrets` est créée. Si l’agent est déjà déclaré, tous ses autres champs — modèle, outils, connecteurs — sont conservés, et l’identifiant est ajouté à sa liste existante. Si l’agent autorise déjà l’identifiant, aucun enregistrement n’est nécessaire et Beeuni n’en effectue pas.

Un agent sur `secrets: all` constitue un cas particulier. `all` ne peut pas contenir de secret avec contrôle de sortie réseau ; Beeuni crée donc une liste explicite comprenant tous les identifiants actuellement présents dans le projet, plus celui-ci. Rien ne change à ce que l’agent reçoit aujourd’hui. Tout secret ajouté ultérieurement devra faire l’objet de sa propre autorisation.

Deux cas empêchent l’autorisation :

- Un projet sur `beeuni_version: 1` (`beeuni.toml`) n’a aucune map d’agents à modifier. La requête échoue avec `400` et `manifest_v1_unsupported`. Modifiez le manifeste manuellement ou passez le projet à `beeuni_version: 2`.
- Un secret **Désactivé** ne peut rien fournir. La requête échoue avec `409` et `secret_not_grantable`. Définissez d’abord son exposition.

Si le projet ne contient pas encore de bloc `agents:`, lisez [Le premier bloc `agents:` change tout le projet](#the-first-agents-block-changes-the-whole-project) avant de confirmer.
Cette modification change l’accès aux secrets de tous les autres agents.

<a id="by-hand"></a>

### Manuellement

Voici la même autorisation, écrite directement :

```yaml
beeuni_version: 2
agents:
  my-agent:
    secrets: [STRIPE_API_KEY]
```

<a id="when-a-session-asks-for-a-secret-its-agent-is-not-granted"></a>

### Lorsqu’une session demande un secret non autorisé pour son agent

Un agent qui a besoin d’un identifiant crée un lien de secret (`beeuni secrets request`).
La valeur que vous saisissez est enregistrée même si l’agent de la session n’y est pas autorisé. Cette session ne la reçoit jamais ; Beeuni l’indique donc partout :

- Le formulaire du lien affiche **Enregistré, mais `<agent>` ne peut pas encore le lire** et indique le secret.
- La réponse de création et le message de suivi envoyé à la session énumèrent les noms `withheld` ainsi que la marche à suivre.
- Dans la session, `beeuni secrets ls` affiche une clé déclarée mais non autorisée sous la forme `not granted`, et non `missing`.

L’agent ne peut pas étendre lui-même ses autorisations. Ouvrez **Customize → Agents → `<agent>` → Secrets** et activez le secret. Beeuni transmet la modification aux sessions en cours de l’agent lorsque vous l’enregistrez. L’agent peut aussi la récupérer immédiatement avec `beeuni secrets sync`, et chaque prompt resynchronise les secrets d’une session. Aucun redémarrage n’est nécessaire.

<a id="the-first-agents-block-changes-the-whole-project"></a>

### Le premier bloc `agents:` change tout le projet

:::warning[Déclarer un agent bloque tous les autres]
Un projet sans bloc `agents:` — ou sans aucun `beeuni.yaml` — n’est pas contrôlé : chaque agent reçoit tous les secrets exposés à l’environnement, et aucun agent ne reçoit de secret avec contrôle de sortie réseau.

Dès que le projet déclare son premier agent, tous les agents **qui ne sont pas** listés ne reçoivent plus aucun secret du projet, y compris les secrets d’environnement qui fonctionnaient une minute auparavant. En lister un révoque l’accès des autres.
:::

Listez donc tous les agents qui ont besoin de secrets, pas seulement celui que vous corrigez. C’est pourquoi le tableau de bord vous demande de confirmer la première fois : après cet enregistrement, `agents:` constitue la liste d’autorisation du projet, et tout agent qui en est absent s’exécute sans aucun secret du projet.

<a id="exposing-capabilities-to-third-party-users"></a>

## Exposer des fonctionnalités à des utilisateurs tiers

:::warning[Les politiques de secrets Beeuni ne sont pas un système d’autorisation multi-tenant]
Une politique de secret protège **l’agent de votre projet** contre la divulgation de vos propres identifiants. Elle ne détermine pas lesquels de vos utilisateurs finaux peuvent les utiliser.
:::

Si vous créez un produit où des **utilisateurs tiers non fiables** peuvent accéder à une fonctionnalité — une interface de chat publique, une application partagée, un agent que n’importe qui sur Internet peut solliciter — ne leur donnez pas accès aux politiques de secrets. Tous les utilisateurs de cette interface partagent un seul agent de projet, une seule autorisation et une seule liste d’hôtes. Beeuni ne peut pas distinguer vos clients les uns des autres : un secret avec contrôle de sortie réseau accessible à partir du prompt de n’importe quel utilisateur est donc un identifiant que chaque utilisateur peut utiliser, dans toute la mesure permise par la clé en amont.

Mettez en place de votre côté la séparation dont vous avez réellement besoin :

1. Déployez votre propre service d’autorisation et de proxy. Il détient l’identifiant en amont.
2. Dirigez l’agent vers votre service, pas vers le service en amont. Donnez à l’agent uniquement un identifiant pour votre service — celui-ci peut être soumis au contrôle de sortie réseau vers votre propre hôte.
3. Votre service identifie l’utilisateur final, applique vos propres règles d’autorisation et quotas par utilisateur, puis effectue l’appel en amont à l’aide de l’identifiant qu’il détient.

C’est dans ce service que doivent s’appliquer les règles par utilisateur : qui peut appeler quoi, à quelle fréquence et pour quels enregistrements. L’exposition des secrets Beeuni se situe une couche en dessous et ne la remplace pas.

<a id="list-your-secrets"></a>

## Lister vos secrets

Exécutez `beeuni secrets ls` pour voir les secrets déclarés par un projet et ceux dont la valeur est définie.

La liste contient des métadonnées de configuration. Elle ne renvoie jamais les valeurs des secrets. Un jeton d’agent limité à un périmètre donné ne voit que les identifiants figurant dans les autorisations de cet agent. Un `secrets_allowlist` propre à une session contrôle la transmission des secrets à cette session, mais ne masque pas les métadonnées de configuration autorisées par les droits de l’agent.

<a id="rotate-a-secret"></a>

## Renouveler un secret

1. **Définir une nouvelle valeur**

    Exécutez la même commande avec la nouvelle valeur ou définissez-la à nouveau sur la page Secrets du projet :

    ```bash
    beeuni secrets set STRIPE_API_KEY=sk_live_new...
    ```

2. **Beeuni le transmet aux sessions en cours**

    Beeuni transmet la modification, dans la mesure du possible, à chaque sandbox
    qui a une session active pour le projet. Pour les identifiants du modèle ou de la passerelle,
    Beeuni redémarre le processus de compatibilité harness standard.

    La rotation d’un secret soumis à un contrôle de sortie ne nécessite aucun transfert de sa valeur : la
    sandbox détient un identifiant, et Beeuni lit la valeur actuelle à la prochaine
    requête.

<a id="remove-a-secret"></a>

## Supprimer un secret

Exécutez `beeuni secrets unset STRIPE_API_KEY` (ou `unset <identifier>`), ou
supprimez-le depuis la page Secrets du projet.

:::warning[La suppression est immédiate, la propagation ne l’est pas]
Beeuni supprime immédiatement un secret partagé. Le transfert vers les sandboxes
déjà en cours d’exécution est soumis aux mêmes limites que la rotation.
:::

<a id="share-a-value-without-seeing-it"></a>

## Partager une valeur sans la voir

Exécutez `beeuni secrets request STRIPE_API_KEY` pour créer un lien. Toute personne disposant du
lien peut saisir la valeur. Vous ne la voyez jamais. Par défaut, les liens restent valides pendant 7 jours ;
ajustez cette durée avec `--expires <minutes>` (30 jours maximum). Un lien expiré affiche
une page indiquant clairement qu’il a expiré : créez-en un nouveau avec la même commande.

<a id="give-an-agent-a-value-directly"></a>

## Fournir directement une valeur à un agent

Si vous collez une clé dans une session, l’agent l’enregistre immédiatement avec
`beeuni secrets set`. Il ne vous envoie pas de lien. L’agent doit disposer de l’autorisation d’écriture des secrets du projet. Sans cette autorisation, l’agent reçoit
`403` et crée plutôt un lien secret. Un agent peut enregistrer un secret d’environnement
ou un secret de connecteur (`--scope connector`). La livraison soumise à contrôle et les listes d’hôtes
restent réservées aux humains.

<a id="end-to-end-example"></a>

## Exemple de bout en bout

`beeuni.yaml` :

```yaml
beeuni_version: 2
default_agent: my-agent
agents:
  my-agent:
    secrets: [STRIPE_API_KEY]
```

Configuration des secrets. La première commande enregistre la valeur avec l’exposition par défaut
dans l’environnement. La deuxième la fait passer à une exposition soumise à un contrôle de sortie, fonctionnalité
expérimentale qui nécessite l’option `secrets_egress` (Settings → Feature flags) ; elle
renvoie `403` `feature_disabled` lorsque l’option est désactivée.

```bash
beeuni secrets set STRIPE_API_KEY=sk_live_...
beeuni secrets delivery STRIPE_API_KEY egress --allow-host api.stripe.com
```

L’agent appelle ensuite Stripe avec la variable qui lui a été fournie :

```bash
curl -s -o /dev/null -w '%{http_code}\n' \
  -H "authorization: Bearer $STRIPE_API_KEY" \
  https://api.stripe.com/v1/customers
# expected: 200
```

`$STRIPE_API_KEY` contient un identifiant. Stripe reçoit la vraie clé, car
`api.stripe.com` figure dans la liste. La même requête envoyée à un hôte qui ne figure pas dans la
liste transmet l’identifiant, que le serveur en amont rejette.

La même requête, effectuée par un agent dont la liste `secrets` ne contient pas `STRIPE_API_KEY`,
renvoie `401`. La session démarre normalement : un secret non autorisé n’est pas une erreur,
il n’est tout simplement jamais transmis.

<a id="cli-commands"></a>

## Commandes CLI

| Commande | Fonction |
|---|---|
| `beeuni secrets ls` | Répertorier les secrets déclarés et définis pour le projet |
| `beeuni secrets set KEY=VALUE [--identifier <id>] [--scope runtime\|connector]` | Créer ou mettre à jour un secret. `KEY=-` lit la valeur depuis stdin. `--scope connector` la conserve côté serveur |
| `beeuni secrets unset IDENTIFIER` | Supprimer un secret |
| `beeuni secrets delivery IDENTIFIER egress --allow-host <host>` | Exposition soumise à un contrôle de sortie pour les hôtes indiqués. Fonctionnalité expérimentale ; nécessite l’option `secrets_egress` |
| `beeuni secrets delivery IDENTIFIER runtime` | Exposition dans l’environnement (par défaut) |
| `beeuni secrets delivery IDENTIFIER denied` | Désactivé |
| `beeuni secrets call IDENTIFIER URL` | Envoyer une requête HTTPS soumise à une politique via Beeuni. Fonctionnalité expérimentale ; nécessite l’option `secrets_egress` |
| `beeuni secrets sync` | Dans une session d’agent : récupérer les secrets de cette session et accorder l’accès maintenant. Pour une personne : renvoyer les secrets à toutes les sandboxes actives du projet |
| `beeuni secrets request NAME [--scope runtime\|connector] [--expires <min>]` | Créer un lien permettant à quelqu’un d’autre de saisir une valeur |
| `beeuni env push --from <path>` | Importer un fichier `.env` sous forme de secrets |
| `beeuni env pull [--out <path>] [--force]` | Exporter les noms des secrets, et non leurs valeurs, dans un fichier `.env` |

La CLI conserve la terminologie enregistrée : `runtime` correspond à l’exposition dans l’environnement,
`egress` à l’exposition soumise à un contrôle de sortie, `denied` à l’exposition désactivée. Exécutez
`beeuni secrets --help` pour voir toutes les options.

Par défaut, les liens de configuration utilisent `connector`. Utilisez `--scope runtime` uniquement si le shell de l’agent
doit recevoir la valeur. Un secret associé à un connecteur reste côté serveur.

<a id="names-and-permissions"></a>

## Noms et autorisations

Règles de format pour les deux noms :

| Nom | Format |
|---|---|
| `identifier` | `^[A-Za-z0-9][A-Za-z0-9_.-]{0,127}$` |
| `name` | `^[A-Z_][A-Z0-9_]{0,63}$` |

La lecture ou l’écriture d’un secret nécessite l’autorisation `project.secret.read` ou
`project.secret.write`. Un responsable de projet détient les deux. Un rôle personnalisé
ne peut qu’ajouter des autorisations — Beeuni ne prévoit aucune règle de refus — ; aucun rôle ne peut donc en retirer une à un responsable.
Pour restreindre un responsable, supprimez son rôle de responsable.

La livraison à une session dépend de la décision concernant le rôle de la personne qui l’a démarrée,
combinée aux autorisations accordées dans le manifeste de l’agent lancé.
Les deux doivent autoriser l’accès au secret. Voir
[Un vocabulaire, deux associations](/docs/fr/accounts#one-vocabulary-two-bindings).

<a id="rest-routes"></a>

## Routes REST

Toutes les routes se trouvent sous `/v1/projects/{projectId}`.

| Méthode | Chemin | Description |
|---|---|---|
| GET | `/secrets` | Lister les secrets. Si l’appelant utilise un jeton d’agent à portée limitée, la liste est limitée aux secrets auxquels il a droit. |
| POST | `/secrets` | Créer ou mettre à jour la valeur partagée. Corps : `{name, identifier?, value}`, avec une politique de livraison facultative. |
| PUT | `/secrets/{identifier}/strategy` | Modifier l’exposition et la liste d’hôtes associée. |
| POST | `/secrets/{identifier}/grant` | Ajouter l’identifiant à la liste `secrets` d’un agent dans `beeuni.yaml`. Corps : `{agent}`. |
| DELETE | `/secrets/{name}` | Supprimer la valeur partagée. Les dérogations personnelles sont conservées. |
| PUT | `/secrets/{name}/personal` | Définir ou activer la dérogation personnelle de l’appelant. |
| DELETE | `/secrets/{name}/personal` | Supprimer la dérogation personnelle de l’appelant. |

`POST /secrets` rejette les noms commençant par `BEEUNI_`. Il renvoie `409`
si le `identifier` existe déjà avec un `name` différent. Il rejette le nom exact `CODEX_AUTH_JSON` avec `400` — Beeuni gère ce secret
lors de la configuration de l’abonnement ChatGPT.

Les deux routes d’écriture renvoient un objet `delivery_sync` lorsque la modification devait être transmise
aux sandboxes en cours d’exécution. `ok: false` signifie que la valeur est enregistrée, mais qu’au moins une session active
utilise encore la précédente ; les sessions répertoriées la récupéreront au redémarrage.

Un secret dans la liste contient `delivery_blocked_reason`. La valeur
`no_agent_grant` signifie qu’aucun agent ne peut recevoir ce secret. `null` signifie qu’il est autorisé, que son exposition ne nécessite aucune autorisation ou que Beeuni n’a pas pu lire le manifeste.

`POST /secrets/{identifier}/grant` supprime cette raison. Il renvoie
`already_granted: true` si la liste de l’agent autorise déjà l’identifiant ; dans ce cas, Beeuni n’effectue aucune modification. Il renvoie `adopted_governance: true` lorsque
la modification ajoute le premier bloc `agents:` du projet — la modification [décrite
ci-dessus](#grant-a-secret-to-an-agent). Pour un projet `beeuni.toml`, il renvoie `400` `manifest_v1_unsupported`,
et pour un secret désactivé, `409` `secret_not_grantable`.

<a id="rotation-and-propagation"></a>

## Rotation et propagation

L’écriture d’un secret n’attend pas le redémarrage d’une session. Beeuni transmet la
modification à chaque sandbox active du projet :

1. Beeuni crée un nouvel instantané de l’environnement, en utilisant les autorisations `secrets` de l’agent en cours d’exécution.
2. La sandbox écrit l’instantané dans l’environnement de l’agent actif. Les nouveaux appels d’outils
   prennent immédiatement en compte la modification.
3. Si le secret modifié est un identifiant de fournisseur LLM, Beeuni redémarre
   harness standard.

Ce transfert est effectué dans la mesure du possible. L’appel API qui modifie le secret renvoie
sa réponse avant la fin du transfert. Les échecs de transfert sont uniquement consignés et ne sont pas réessayés. Une
sandbox dont le transfert a échoué conserve l’ancienne valeur jusqu’au prochain transfert réussi
ou jusqu’au redémarrage de la session.

<a id="model-credentials"></a>

## Identifiants de modèle

Un projet qui utilise l’accès aux modèles géré par Beeuni n’a pas besoin de sa propre clé. Pour utiliser
vos propres clés, définissez les variables de fournisseur référencées par la configuration de fournisseur harness standard.
Une clé de modèle reconnue se voit attribuer l’usage **passerelle LLM**, qui la consomme
côté serveur ; elle n’a pas besoin d’être présente dans la sandbox.

N’utilisez pas le résultat générique d’une vérification du fournisseur comme preuve du fonctionnement à l’exécution. Il ne peut
pas confirmer le modèle, la région, les droits d’accès et le dialecte API sélectionnés. Envoyez une véritable
requête au modèle exact.
