# Segreti

Come Beeuni archivia le credenziali dei progetti e controlla se il codice degli agenti può leggere ciascun valore.

Canonical page: https://beeuni.ai/docs/it/project/secrets

Un segreto è una credenziale specifica del progetto — una chiave API, un token o una stringa di connessione — necessaria a una sessione, ma che non deve trovarsi nel repository. Beeuni archivia i segreti nel progetto, mai nell’account, e cifra ogni valore con AES-256-GCM usando una chiave derivata per progetto.

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

## Identificatore e nome

Ogni segreto ha due nomi. L’`identifier` è l’identificatore da usare nella CLI e nella concessione `secrets` di un agente. Il `name` è la chiave in maiuscolo della variabile d’ambiente nella sandbox, ad esempio `STRIPE_API_KEY`. Nella maggior parte dei progetti, identificatore e nome corrispondono. Sono diversi solo quando un progetto contiene harness sperimentaleù valori possibili per lo stesso nome: per esempio, una chiave Google Maps principale e una di riserva possono entrambe corrispondere a `GOOGLE_MAPS_API_KEY`.

Tutte le regole di accesso usano l’identificatore, mai il nome.

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

## Esposizione e utilizzo

Un segreto ha due impostazioni indipendenti. Considerale separatamente: rispondono a domande diverse.

| Impostazione | A quale domanda risponde | Valori |
|---|---|---|
| **Esposizione** | Il codice dell’agente può leggere il valore reale? | `environment`, `egress-enforced`, `none` |
| **Utilizzo** | Chi lo usa? | Codice dell’agente, gateway LLM, connettore, Git |

La documentazione precedente di Beeuni presentava un unico elenco che mescolava i due aspetti. Non esiste harness sperimentaleù. Non c’è una scelta tra un «confine di rete» e un «broker HTTPS»: un solo meccanismo serve tutti i segreti con uscita di rete controllata su ogni provider di sandbox.

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

### Le tre modalità di esposizione

| Esposizione | Cosa contiene la sandbox | Quando usarla |
|---|---|---|
| **Environment** | Il valore reale, come variabile d’ambiente in chiaro | Modalità predefinita. Valori con cui l’agente deve eseguire calcoli e protocolli diversi da HTTPS |
| **Egress-enforced** | Un **handle** — segnaposto auto-descrittivo, privo di valore di per sé | Sperimentale. Chiamate HTTPS, quando è attivo il flag `secrets_egress` |
| **None** | Nulla | Credenziale usata solo da un servizio Beeuni oppure valore archiviato e disattivato |

> **Regola pratica**
>
> **Environment** è la modalità di esposizione predefinita. Il valore reale viene caricato nella sandbox, dove l’agente può leggerlo, stamparlo e inoltrarlo. **Egress-enforced** mantiene il valore fuori dalla sandbox, ma è una modalità sperimentale: per usarla, attiva il flag `secrets_egress` (Settings → Feature flags). Fino ad allora, il segreto viene caricato nell’ambiente della sandbox.

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

### Utilizzi

La maggior parte degli utilizzi viene assegnata da Beeuni, non da te:

- **Codice dell’agente** — implicito ogni volta che l’esposizione non è `none`.
- **Gateway LLM** — assegnato quando il valore è una chiave riconosciuta di un provider di modelli. Il gateway autentica le richieste al provider lato server.
- **Connector:&lt;slug&gt;** — assegnato dal flusso di collegamento del connettore.
- **Git** — assegnato da Beeuni per il proprio accesso a Git. È di sola lettura: non puoi impostarlo né rimuoverlo.

Un segreto con esposizione `none` e nessun utilizzo viene visualizzato come **Disabled**: è archiviato, cifrato e non viene usato da nessuno.

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

## Segreti trasmessi e segreti calcolati

La modalità di esposizione che un segreto può usare dipende dal **sistema a monte**, non da Beeuni.

- **Segreti trasmessi** — il valore viene inviato sulla rete. Chiavi API, token bearer, password. È la categoria di gran lunga harness sperimentaleù comune. Poiché il valore compare per un momento come byte in una richiesta in uscita, Beeuni può inserirlo direttamente, fuori dalla sandbox. Un segreto trasmesso può passare a **egress-enforced** quando è attivo il flag `secrets_egress`; per impostazione predefinita, viene caricato nell’ambiente della sandbox.
- **Segreti calcolati** — il valore è un ingrediente di un calcolo e non viene mai trasmesso. Chiavi di firma AWS SigV4, segreti di firma HMAC per webhook, asserzioni client JWT, chiavi private SSH. Chi esegue il calcolo deve avere il valore. Un confine di rete non aiuta, perché la credenziale non compare nella trasmissione. I segreti calcolati devono rimanere su **environment**.

Environment è la modalità di esposizione predefinita ed è l’unica che può fornire una credenziale con cui la sandbox deve eseguire calcoli. Anche i protocolli diversi da HTTPS — una stringa di connessione Postgres, credenziali SMTP — richiedono la modalità environment.

Quando salvi un valore che sembra materiale di firma, come una coppia di chiavi `AKIA…` o materiale PEM/SSH, Beeuni imposta la modalità predefinita su **environment** e ne spiega il motivo: questa chiave firma le richieste localmente, quindi non è possibile applicare l’uscita di rete controllata.

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

## Esposizione Egress-enforced

> **Funzionalità sperimentale — richiede il flag secrets_egress**
>
> Il controllo a livello di rete è sperimentale. Per usarlo, attiva il flag `secrets_egress` (Settings → Feature flags). Fino ad allora, il segreto viene caricato nell’ambiente della sandbox. Se il flag è disattivato, creare un segreto egress-enforced restituisce `403` `feature_disabled`.

La sandbox riceve una variabile d’ambiente il cui valore è un **handle**, non la credenziale. L’agente usa questa variabile proprio come userebbe la chiave reale: in un’intestazione, una stringa di query o un corpo. `Authorization: Bearer $VAR`, `Cookie: …=$VAR`, un’intestazione `X-Api-Key`, un parametro di query e un campo del corpo JSON o di un modulo funzionano tutti: Beeuni individua l’handle ovunque si trovi (in chiaro, con codifica URL, come Base64 autonomo o con escape JSON) e lo sostituisce con il valore reale. In uscita, Beeuni sostituisce l’handle con il valore reale, ma solo per le richieste dirette agli host che hai approvato.

> **Invia l’handle così com’è: non convertirlo in Base64**
>
> Una cosa non funziona: nascondere l’handle in un blocco Base64 creato da te, come fa l’autenticazione **HTTP Basic** (`curl -u $VAR:` → `Authorization: Basic <base64>`). Beeuni non riesce a trovare un handle incorporato e non allineato nel Base64 che hai codificato, quindi la sostituzione non avviene e il sistema a monte risponde `401`. Inserisci invece l’handle in un’intestazione Bearer/token, in un parametro di query o in un campo del corpo. Se l’API supporta solo l’autenticazione Basic, usa l’esposizione **environment** per quel segreto.

Da questa struttura derivano alcuni fatti:

- Il valore reale **non** si trova mai nella sandbox: né come variabile d’ambiente, né come file, né come alias.
- Un handle inviato a un host che non hai approvato arriva come stringa letterale. Il sistema a monte lo rifiuta. Non ha alcun valore.
- Un handle con firma non valida non viene mai accettato e Beeuni lo registra come handle contraffatto. Un handle valido per un segreto che questa sessione non può usare viene registrato come rubato.
- Ogni richiesta inoltrata genera un record di controllo per la singola richiesta.
- Il traffico verso gli host non inclusi nell’elenco viene instradato attraverso il tunnel senza essere letto. I client TLS con certificato bloccato e i client mTLS che comunicano con questi host non subiscono modifiche.

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

### Corrispondenza esatta degli host

Elenca tutti gli host che contatti, uno per riga, usando il nome host esatto.

| Rifiutato | Motivo |
|---|---|
| Un host jolly, `*.example.com` | L’agente non deve poter scegliere la destinazione |
| Uno schema URL diverso da HTTPS | Beeuni termina la connessione TLS per eseguire la sostituzione |

`api.example.com` non include `uploads.api.example.com`. Aggiungi il secondo host allo stesso segreto. Beeuni rifiuta le policy non applicabili con `400` quando le salvi: non archivia mai una regola che non può applicare.

Due segreti con egress vincolato possono condividere un host. Ogni handle corrisponde al proprio valore, quindi entrambi vengono sostituiti correttamente nella stessa richiesta.

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

### Verificalo con due test

Esegui entrambi i test dall'interno della sandbox, verso un host presente nell'elenco. L'esempio usa `postman-echo.com`, che offre un endpoint per ciascun tipo. Aggiungilo agli host consentiti per la durata del 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
```

Esamina i risultati insieme, eseguendo prima il test 1: è l'unico che ti dice se l'host è raggiungibile, e il test 2 non dimostra nulla finché il primo non ha esito positivo.

| Risultato del test 2 | Significato |
| --- | --- |
| `200`, l'intestazione restituita mostra `[REDACTED]` | Funziona. Il valore reale è stato inviato al server e l'echo è stato oscurato al ritorno. |
| `200`, l'intestazione restituita mostra l'handle stesso | La sostituzione non è stata eseguita. Controlla l'elenco degli host e l'autorizzazione dell'agente. |
| `401` da un host API reale | La sostituzione non è stata eseguita. Stessi due controlli. |
| Una risposta vuota o un errore di connessione | Un errore reale. Non indica un esito positivo. |

Verifica che il valore reale non sia presente da nesbeeuni parte nell'ambiente guest:

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

L'identificatore compare anche in `BEEUNI_SECRET_CAPABILITIES`, il catalogo privo di valori che indica all'agente quali segreti esistono, quale variabile contiene ogni handle e quali host copre ciascuno. Non contiene mai un valore.

Un host presente nell'elenco presenta un certificato emesso da Beeuni per questa sandbox, di cui la sandbox si fida già, anziché quello dell'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>

### Cosa cambia con il relay

Si raggiunge un host approvato tramite Beeuni, quindi il comportamento è leggermente diverso da una chiamata diretta:

- Le risposte non vengono trasmesse in streaming. Gli eventi inviati dal server e i websocket non funzionano tramite un host approvato.
- Il corpo di una richiesta è limitato a 1 MiB, la risposta a 5 MiB e l'intera chiamata a 30 secondi. Beeuni segue al massimo 3 reindirizzamenti.
- Viene restituito solo un insieme fisso di intestazioni di risposta: tipo e lingua del contenuto, validatori di cache, le intestazioni relative ai limiti di frequenza, `retry-after`, `x-request-id`.
- Vengono intercettati solo i client che rispettano `https_proxy`. Beeuni imposta questa variabile e la relativa CA attendibile nell'ambiente dell'agente. Un processo avviato con un ambiente ripulito chiama direttamente l'host e invia la richiesta contenente l'handle.

Per le richieste che Beeuni non può intercettare, l'agente dispone di un accesso esplicito agli stessi host, secondo la stessa policy:

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

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

## Esposizione nell'ambiente

La sandbox riceve il valore reale come variabile d'ambiente in testo semplice. Il codice dell'agente può leggerlo, stamparlo e inoltrarlo ovunque. Beeuni non può oscurarlo, verificarne l'uso né impedirne la fuoriuscita.

L'esposizione nell'ambiente è quella predefinita. Ogni nuovo segreto la usa, a meno che tu non lo trasferisca all'egress vincolato, una funzionalità sperimentale che richiede il flag `secrets_egress`. Una credenziale calcolata e qualsiasi protocollo non HTTPS devono rimanere nell'ambiente.

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

## Chi può usare un segreto

Ogni valore segreto ha un pubblico, la stessa scelta **Chi può usarlo** disponibile per un account di un connettore:

| Scelta | Chi può usare il valore |
| --- | --- |
| **Tutti nel progetto** (predefinito) | Ogni sessione del progetto, inclusi trigger, pianificazioni e sessioni condivise. |
| **Solo tu** | Tu, direttamente, e le tue sessioni private. |
| **Persone, gruppi o agenti specifici** | Le persone e i gruppi che selezioni (direttamente e nelle loro sessioni private) e gli agenti che selezioni (in tutte le loro sessioni). |

Una sessione svolge sempre due ruoli: è il suo **agente** e, solo quando è privata, la sua **persona**.

- **Una persona** può accedere a un valore in una sessione **privata** avviata da quella persona. Un prompt di chiunque altro rimuove la persona dalla sessione, che quindi non può harness sperimentaleù accedere al valore. Le sessioni condivise, i trigger, le pianificazioni, i webhook e le sessioni email e Telegram non hanno una persona.
- **Un agente** può accedere a un valore in tutte le proprie sessioni, incluse quelle con trigger, pianificazioni e condivise. Condividi un valore con l'agente se serve a un'esecuzione senza supervisione. Chiunque possa eseguire quell'agente può quindi usare il valore tramite l'agente, perciò il controllo è l'autorizzazione a eseguire l'agente (l'autorizzazione è configurata nell'agente).
- La stessa regola vale per i consumer lato server. Un connettore associato al segreto lo usa solo per un chiamante incluso nel pubblico. Chiunque altro riceve `credential_not_shared` e nesbeeuni richiesta lascia Beeuni.
- I servizi Beeuni che agiscono per conto di nessuno — il proxy Git, i controlli delle firme dei webhook, le installazioni dei canali e le app Beeuni — usano solo valori condivisi con tutti.

harness sperimentaleù valori possono condividere lo stesso nome. Un valore condiviso con la persona della sessione ha la precedenza su uno condiviso con l'agente, che a sua volta ha la precedenza su quello condiviso con tutti. Esempio: `DEEL_API_TOKEN` contiene un valore del team, mentre un secondo valore con l'identificatore `DEEL_API_TOKEN-finance` è condiviso solo con il gruppo Finance. I membri di Finance ricevono il valore Finance nelle loro sessioni private; tutti gli altri e ogni trigger ricevono il valore del team.

È una persona a impostare il pubblico. Una sessione agente non può modificarlo (`403`), quindi un agente non può ampliare il pubblico di un valore da cui è escluso né aggiungere sé stesso. Chi gestisce i segreti del progetto continua a vedere i valori che non sono condivisi con lui, contrassegnati come **Non condiviso con te**, e può ampliarne di nuovo il pubblico.

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

### Condividere una sessione che contiene un valore personale

Un valore condiviso solo con te e reso disponibile nella tua sessione privata come **variabile d'ambiente** è in testo semplice all'interno di quella sandbox. Condividere la sessione permetterebbe a ogni nuovo visualizzatore di leggerlo e non è possibile rimuovere una variabile d'ambiente da una sandbox in esecuzione. Perciò Beeuni impedisce di condividere quella sessione o di crearne un link pubblico, indicando `409 PERSONAL_SECRET_REQUIRES_PRIVATE_SESSION` e i nomi dei valori presenti. Avvia una nuova sessione da condividere oppure condividi prima il valore con tutti. I valori resi disponibili tramite l'agente e quelli con egress vincolato o lato server (verificati a ogni richiesta) non impediscono la condivisione.

Quando restringi il pubblico, Beeuni invia di nuovo tutti i valori alle sandbox in esecuzione. Un valore già distribuito come variabile d'ambiente rimane nella sandbox fino al riavvio. Se potrebbe essere stato letto, ruotalo.

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

### Quando inserisci un valore tramite un link

Un agente che ha bisogno di un valore che non gli hai fornito invia un link. La pagina del link offre la scelta **Chi può usarlo**: tutti nel progetto (impostazione predefinita) oppure solo la persona che lo ha richiesto. Scegli la seconda opzione per qualsiasi dato personale, come un token per le buste paga o un accesso personale. La pagina mostra il nome visualizzato della persona che lo ha richiesto, mai l'email, perché chiunque abbia il link può aprirlo.

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

### Sostituzione personale

Una sostituzione personale è un tuo valore per un determinato nome, usato al posto del valore condiviso nelle sessioni che avvii. Al momento Beeuni la usa solo per una credenziale di accesso OAuth. Beeuni non permette mai di usare come sostituzione personale una chiave di un provider LLM, ad esempio `ANTHROPIC_API_KEY`.

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

## Aggiungere un segreto

### Imposta il valore dalla CLI
```bash
beeuni secrets set STRIPE_API_KEY=sk_live_...
```

Beeuni lo salva per tutti nel progetto. Aggiungi `--only-me` per renderlo utilizzabile solo da te. Per archiviare harness sperimentaleù valori con lo stesso nome, aggiungi `--identifier <id>`. I nomi non possono iniziare con `BEEUNI_`: Beeuni riserva questo prefisso ai valori della piattaforma.

Modifica in seguito chi può usarlo:

```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
```

### Oppure usa la dashboard
Apri la pagina Secrets del progetto, inserisci la chiave e il valore, scegli **Chi può usarlo** e salva. Beeuni crittografa subito il valore e imposta per ogni nuovo segreto **Tutti nel progetto** e l'esposizione **environment**: il valore effettivo viene caricato nella sandbox. La colonna **Chi può usarlo** mostra il pubblico di ciascun valore.

Per spostare un segreto all'esposizione con enforcement dell'egress, attiva prima il flag di funzionalità `secrets_egress` (Settings → Feature flags); è sperimentale. Con il flag attivo, la pagina Secrets mostra il controllo **"Il tuo codice può leggere questo valore?"**: rispondendo *no*, il segreto passa all'enforcement dell'egress e viene mostrato l'elenco degli host; rispondendo *sì*, mantiene l'esposizione environment. Con il flag disattivato, il segreto resta su environment.

### Concedi l'accesso a un agente
Scegli un agente nella pagina Secrets oppure aggiungi tu stesso l'identificatore all'elenco `secrets` dell'agente in `beeuni.yaml`. Una sessione riceve solo i segreti concessi al suo agente. Vedi [Concedere un segreto a un
agente](#grant-a-secret-to-an-agent).

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

## Concedere un segreto a un agente

Una sessione riceve un segreto solo quando l'agente che esegue include l'identificatore nel proprio elenco `secrets`. La corrispondenza si basa sull'identificatore, non sul nome, e ignora le maiuscole/minuscole.

> **L'utilizzo con enforcement dell'egress e quello dei servizi richiedono una concessione esplicita**
>
> `secrets: all` concede solo l'esposizione environment. Un segreto con enforcement dell'egress, così come qualsiasi segreto utilizzato da un servizio Beeuni, deve essere indicato nell'elenco di un agente. Un progetto privo del blocco `agents:` in `beeuni.yaml` non ne riceve mai uno. Un segreto non concesso viene ignorato senza avviso: la sessione si avvia normalmente e la prima chiamata all'host fallisce come se la credenziale fosse errata.

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

### Dalla dashboard

Nella pagina Secrets, accanto ai segreti che nessun agente può ricevere compare l'indicazione **Nessun agente può ricevere questo segreto**. Scegli un agente e conferma. Beeuni modifica `beeuni.yaml` e lo salva come `chore(agents): grant <IDENTIFIER> to <agent>`.

La concessione funziona sia che il manifest dichiari già l'agente, sia che non lo faccia. Se l'agente non è dichiarato nel manifest, viene aggiunta una nuova voce con questo unico elenco `secrets`. Se l'agente è già dichiarato, tutti gli altri campi — model, tools, connectors — rimangono invariati e l'identificatore viene aggiunto all'elenco esistente. Se l'agente ha già accesso all'identificatore, non serve alcun commit e Beeuni non ne esegue uno.

Un agente in `secrets: all` è un caso speciale. `all` non può contenere un segreto con enforcement dell'egress, quindi Beeuni scrive un elenco esplicito: tutti gli identificatori presenti oggi nel progetto, harness sperimentaleù questo. Nulla cambia per i segreti che l'agente riceve già. Ogni segreto aggiunto in seguito richiederà una concessione separata.

In due casi la concessione viene rifiutata:

- Un progetto con `beeuni_version: 1` (`beeuni.toml`) non ha una mappa degli agenti da modificare. La richiesta fallisce con `400` e `manifest_v1_unsupported`. Modifica il manifest manualmente oppure sposta il progetto su `beeuni_version: 2`.
- Un segreto **Disabilitato** non ha nulla da fornire. La richiesta fallisce con `409` e `secret_not_grantable`. Assegna prima un'esposizione al segreto.

Se il progetto non ha ancora un blocco `agents:`, leggi [Il primo blocco `agents:` modifica l'intero
progetto](#the-first-agents-block-changes-the-whole-project) prima di confermare.
Quella modifica cambia l'accesso ai segreti per tutti gli altri agenti.

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

### Manualmente

La stessa concessione, scritta direttamente:

```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>

### Quando una sessione richiede un segreto non concesso al suo agente

Un agente che necessita di una credenziale crea un link al segreto (`beeuni secrets request`).
Il valore inserito viene salvato anche se non è concesso all'agente della sessione. La sessione non lo riceve mai, quindi Beeuni lo segnala in ogni schermata:

- Il modulo del link mostra **Salvato, ma `<agent>` non può ancora leggerlo** e indica il nome del segreto.
- La risposta di creazione e il messaggio successivo alla sessione elencano i nomi `withheld` con le istruzioni per risolvere il problema.
- All'interno della sessione, `beeuni secrets ls` mostra una chiave dichiarata ma non inclusa nella concessione come `not granted`, non come `missing`.

L'agente non può ampliare da solo la propria concessione. Apri **Customize → Agents → `<agent>` → Secrets** e abilita il segreto. Al salvataggio, Beeuni applica la modifica alle sessioni dell'agente già in esecuzione. L'agente può anche recuperarla subito con `beeuni secrets sync` e ogni prompt sincronizza di nuovo i segreti della sessione. Non serve riavviare.

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

### Il primo blocco `agents:` modifica l'intero progetto

> **Dichiarare un agente esclude tutti gli altri**
>
> Un progetto senza un blocco `agents:` — oppure senza alcun `beeuni.yaml` — non è soggetto a restrizioni: ogni agente riceve tutti i segreti con esposizione environment e nessun agente riceve quelli con enforcement dell'egress.
>
> Nel momento in cui il progetto dichiara il primo agente, tutti gli agenti **non** elencati smettono di ricevere qualsiasi segreto del progetto, inclusi i segreti environment che funzionavano fino a un minuto prima. Elencare un agente revoca l'accesso a tutti gli altri.

Elenca quindi tutti gli agenti che hanno bisogno di segreti, non solo quello che stai correggendo. Ecco perché la dashboard ti chiede di confermare la prima volta: dopo quel commit, `agents:` diventa la lista di autorizzazione del progetto e qualsiasi agente che non vi compare viene eseguito senza segreti del progetto.

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

## Esporre funzionalità a utenti di terze parti

> **Le policy dei segreti di Beeuni non sono un sistema di autorizzazione multi-tenant**
>
> Una policy dei segreti protegge **l'agente del tuo progetto** dalla divulgazione delle tue credenziali. Non specifica quali utenti finali possano utilizzarle.

Se stai realizzando qualcosa in cui **utenti terzi non attendibili** possono accedere a una funzionalità — una chat pubblica, un'app condivisa, un agente a cui chiunque su Internet può inviare prompt — non affidare loro le policy dei segreti. Tutti gli utenti di quella superficie condividono un unico agente del progetto, un'unica concessione e un unico elenco di host. Beeuni non può distinguere un tuo cliente da un altro; quindi, se un prompt di qualsiasi utente può raggiungere un segreto con enforcement dell'egress, tutti gli utenti possono usare quella credenziale, fino ai limiti completi della chiave a monte.

Crea il confine di sicurezza di cui hai davvero bisogno, dal tuo lato:

1. Crea un tuo servizio di autorizzazione e proxy. Sarà questo a custodire la credenziale a monte.
2. Indirizza l'agente al tuo servizio, non al servizio a monte. Fornisci all'agente solo una credenziale per il tuo servizio: potrai applicarvi l'enforcement dell'egress limitandolo al tuo host.
3. Il tuo servizio identifica l'utente finale, applica le tue regole di autorizzazione e i limiti per utente, quindi effettua la chiamata a monte usando la credenziale che custodisce.

È nel tuo servizio che devono risiedere le regole per singolo utente: chi può chiamare cosa, con quale frequenza e per quali record. L'esposizione dei segreti di Beeuni opera a un livello inferiore e non la sostituisce.

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

## Elencare i segreti

Esegui `beeuni secrets ls` per vedere quali segreti dichiara un progetto e quali hanno un valore impostato.

L'elenco contiene metadati di configurazione, non restituisce mai i valori dei segreti. Un token con ambito limitato a un agente vede solo gli identificatori inclusi nella concessione dell'agente. Un `secrets_allowlist` specifico della sessione controlla la distribuzione dei segreti a quella sessione, ma non nasconde i metadati di configurazione accessibili in base alla concessione dell'agente.

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

## Ruotare un segreto

### Impostare un nuovo valore
Esegui lo stesso comando con il nuovo valore oppure impostalo di nuovo nella pagina Secrets del progetto:

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

### Beeuni lo invia alle sessioni in esecuzione
Beeuni invia la modifica a ogni sandbox con una sessione attiva per il
progetto, con il massimo impegno possibile. Per le credenziali del modello o del gateway, Beeuni
riavvia il processo di compatibilità di harness standard.

Per ruotare un secret con uscita vincolata non serve inviare il valore: la
sandbox conserva un riferimento e Beeuni legge il valore aggiornato alla
richiesta successiva.

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

## Rimuovere un secret

Esegui `beeuni secrets unset STRIPE_API_KEY` (o `unset <identifier>`), oppure
eliminalo dalla pagina Secrets del progetto.

> **Rimozione immediata, propagazione no**
>
> Beeuni elimina subito un secret condiviso. L'invio alle sandbox già in esecuzione
> è effettuato con il massimo impegno possibile, proprio come per la rotazione.

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

## Condividere un valore senza vederlo

Esegui `beeuni secrets request STRIPE_API_KEY` per creare un link. Chiunque abbia il
link può inserire il valore. Tu non lo vedrai mai. Per impostazione predefinita, i link restano validi per 7 giorni;
puoi modificare la durata con `--expires <minutes>` (massimo 30 giorni). Un link scaduto mostra
una pagina con l'indicazione chiara «scaduto»: crea un nuovo link con lo stesso comando.

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

## Fornire direttamente un valore a un agente

Se incolli una chiave in una sessione, l'agente la salva subito con
`beeuni secrets set`. Non ti invia un link. L'agente ha bisogno dell'autorizzazione del progetto per scrivere i secret. Senza questa autorizzazione, riceve
`403` e crea invece un link per il secret. Un agente può salvare un secret di ambiente
o un secret del connettore (`--scope connector`). L'invio vincolato e gli elenchi di host
restano funzioni riservate agli utenti.

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

## Esempio completo

`beeuni.yaml`:

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

Configurazione del secret. Il primo comando salva il valore con l'esposizione di ambiente predefinita. Il secondo lo imposta con l'esposizione vincolata all'uscita, una funzione sperimentale che richiede il flag `secrets_egress` (Settings → Feature flags); se il flag è disattivato, restituisce
`403` `feature_disabled`.

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

L'agente chiama quindi Stripe usando la variabile che gli è stata fornita:

```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` contiene un riferimento. Stripe riceve la chiave reale, perché
`api.stripe.com` è nell'elenco. La stessa richiesta a un host non presente nell'elenco invia il riferimento e il servizio a monte lo rifiuta.

La stessa richiesta da un agente il cui elenco `secrets` non include `STRIPE_API_KEY`
restituisce `401`. La sessione si avvia normalmente: un secret non autorizzato non genera un errore, semplicemente non viene mai fornito.

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

## Comandi CLI

| Comando | Funzione |
|---|---|
| `beeuni secrets ls` | Elenca i secret dichiarati e impostati per il progetto |
| `beeuni secrets set KEY=VALUE [--identifier <id>] [--scope runtime\|connector]` | Crea o aggiorna un secret. `KEY=-` legge il valore dallo standard input. `--scope connector` lo mantiene sul server |
| `beeuni secrets unset IDENTIFIER` | Rimuove un secret |
| `beeuni secrets delivery IDENTIFIER egress --allow-host <host>` | Imposta l'esposizione vincolata all'uscita per gli host indicati. Funzione sperimentale; richiede il flag `secrets_egress` |
| `beeuni secrets delivery IDENTIFIER runtime` | Esposizione di ambiente (predefinita) |
| `beeuni secrets delivery IDENTIFIER denied` | Disattivato |
| `beeuni secrets call IDENTIFIER URL` | Invia una richiesta HTTPS vincolata a una policy tramite Beeuni. Funzione sperimentale; richiede il flag `secrets_egress` |
| `beeuni secrets sync` | In una sessione di agente: recupera i secret di questa sessione e li autorizza subito. Come persona: invia nuovamente i secret a tutte le sandbox attive del progetto |
| `beeuni secrets request NAME [--scope runtime\|connector] [--expires <min>]` | Crea un link che consente a un'altra persona di inserire un valore |
| `beeuni env push --from <path>` | Carica un file `.env` come secret |
| `beeuni env pull [--out <path>] [--force]` | Esporta i nomi dei secret, non i valori, in un file `.env` |

La CLI mantiene la terminologia salvata: `runtime` indica l'esposizione di ambiente,
`egress` l'esposizione vincolata all'uscita e `denied` la disattivazione. Esegui
`beeuni secrets --help` per visualizzare tutti i flag.

Per impostazione predefinita, i link di configurazione usano `connector`. Usa `--scope runtime` solo se la shell dell'agente deve ricevere il valore. Un secret associato a un connettore resta sul server.

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

## Nomi e autorizzazioni

Regole di formato per i due nomi:

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

Per leggere o scrivere un secret servono l'autorizzazione `project.secret.read` o
`project.secret.write`. Un responsabile del progetto ha entrambe. Un ruolo personalizzato può solo aggiungere autorizzazioni: Beeuni non prevede regole di diniego, quindi nessun ruolo può negarne una a un responsabile. Per limitare un responsabile, rimuovi il ruolo di responsabile.

La consegna a una sessione dipende dal verdetto sui ruoli della persona che l'ha avviata, incrociato con le autorizzazioni del manifest dell'agente avviato. Entrambi devono consentire l'accesso al secret. Consulta
[Un vocabolario, due associazioni](/docs/it/accounts#one-vocabulary-two-bindings).

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

## Endpoint REST

Tutti gli endpoint si trovano sotto `/v1/projects/{projectId}`.

| Metodo | Percorso | Descrizione |
|---|---|---|
| GET | `/secrets` | Elenca i secret. Se il chiamante è un agente con token limitato, l'elenco rispetta le sue autorizzazioni. |
| POST | `/secrets` | Crea o aggiorna il valore condiviso. Corpo: `{name, identifier?, value}`, harness sperimentaleù una policy di consegna facoltativa. |
| PUT | `/secrets/{identifier}/strategy` | Modifica l'esposizione e il relativo elenco di host. |
| POST | `/secrets/{identifier}/grant` | Aggiunge l'identificatore all'elenco `secrets` di un agente in `beeuni.yaml`. Corpo: `{agent}`. |
| DELETE | `/secrets/{name}` | Elimina il valore condiviso. Le sostituzioni personali restano invariate. |
| PUT | `/secrets/{name}/personal` | Imposta o attiva la sostituzione personale del chiamante. |
| DELETE | `/secrets/{name}/personal` | Rimuove la sostituzione personale del chiamante. |

`POST /secrets` rifiuta i nomi che iniziano con `BEEUNI_`. Restituisce `409`
se `identifier` esiste già con un `name` diverso. Rifiuta il nome esatto `CODEX_AUTH_JSON` con `400`: Beeuni gestisce quel secret durante la procedura di attivazione dell'abbonamento ChatGPT.

Entrambi gli endpoint di scrittura restituiscono un oggetto `delivery_sync` quando la modifica deve essere propagata alle sandbox in esecuzione. `ok: false` significa che il valore è stato salvato, ma almeno una sessione attiva usa ancora quello precedente; le sessioni elencate lo acquisiranno al riavvio.

Un secret nell'elenco include `delivery_blocked_reason`. Il valore
`no_agent_grant` significa che nessun agente può ricevere il secret. `null` significa che il secret è autorizzato, che l'esposizione non richiede autorizzazioni o che Beeuni non è riuscito a leggere il manifest.

`POST /secrets/{identifier}/grant` elimina questo motivo. Restituisce
`already_granted: true` se l'elenco dell'agente include già l'identificatore; in tal caso, Beeuni non applica alcuna modifica. Restituisce `adopted_governance: true` se la modifica aggiunge il primo blocco `agents:` del progetto: la modifica [descritta sopra](#grant-a-secret-to-an-agent). Restituisce `400` `manifest_v1_unsupported` per un progetto `beeuni.toml` e `409` `secret_not_grantable` per un secret disattivato.

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

## Rotazione e propagazione

La scrittura di un secret non aspetta il riavvio della sessione. Beeuni invia la modifica a tutte le sandbox attive del progetto:

1. Beeuni crea un nuovo snapshot dell'ambiente usando le autorizzazioni `secrets` dell'agente in esecuzione.
2. La sandbox scrive lo snapshot nell'ambiente dell'agente attivo. Le nuove chiamate agli strumenti acquisiscono subito la modifica.
3. Se il secret modificato è una credenziale di un provider LLM, Beeuni riavvia harness standard.

L'invio viene effettuato con il massimo impegno possibile. La chiamata API che modifica il secret restituisce una risposta prima che l'invio sia completato. Gli invii non riusciti vengono registrati, ma non ritentati. Una sandbox per cui l'invio non è riuscito mantiene il vecchio valore fino al successivo invio riuscito o al riavvio della sessione.

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

## Credenziali del modello

Un progetto che usa l'accesso ai modelli gestito da Beeuni non ha bisogno di una propria chiave. Per usare le tue, imposta le variabili del provider a cui fa riferimento la configurazione del provider harness standard.
A una chiave di un modello riconosciuto viene assegnato l'utilizzo **gateway LLM**, che la usa sul server; non è necessario che sia presente nella sandbox.

Non considerare l'esito generico della verifica del provider una prova del funzionamento in fase di esecuzione. Non può verificare il modello selezionato, la regione, i diritti di accesso né il dialetto API. Invia un prompt reale usando esattamente quel modello.
