Vai al contenuto

least-privilege

Permesso vs osservato: la deriva come risultato di prima classe

Scritto da Olivares AI 11 min di lettura

Un post complementare ha introdotto la deriva del privilegio minimo come gap tra ciò che un agente AI è autorizzato a fare e ciò che viene osservato fare. Quel post copriva il concetto: perché i moduli gap, come l’osservazione di prima lettura produce una differenza consentita rispetto a quella osservata e come la policy-as-code la chiude al momento dell’accesso. Questo post va ancora più in profondità: spiega come la deriva diventa un risultato strutturato, classificato e valutabile all’interno del modulo di sicurezza e cosa gli succede una volta che esiste.

La versione breve: la deriva non è una metrica del cruscotto o una linea di registro. È un’entità persistente con una classificazione, una gravità, un livello di confidenza e un ciclo di vita di triage. Alimenta la coda delle anomalie, arricchisce le tempistiche forensi ed è onesto su ciò che può e non può dimostrare.

Le tre sorgenti di segnale

Ogni bordo nella mappa di accesso registra una relazione di accesso tra un’origine (un agente, un’identità, una sessione) e una risorsa. Ciascun bordo porta due flag booleani: Permesso e Osservato. I bordi interessanti sono quelli in cui i flag non sono d’accordo.

Ma le bandiere non compaiono dal nulla. Provengono da fonti di segnale distinte, ciascuna con un profilo di fiducia diverso:

Politica (consentita). Un edge con signal_source=policy o signal_source=scoped_grant rappresenta una concessione dichiarata: qualcosa che una credenziale, un ruolo IAM o il piano di ambito origine della piattaforma indica che questo agente è autorizzato a fare. Questi bordi sono permitted=true, observed=false finché la telemetria non li conferma. Sono il soffitto. I connettori di identità (emittenti WIF, elenchi di chiavi API, ruoli dell’area di lavoro) alimentano questo lato. Un account di servizio federato che ha consentito l’ambito OAuth della sua regola in un’area di lavoro è uno di questi vantaggi.

Telemetria (osservata). Segnali cooperativi da tracce OpenTelemetry, log pgAudit, record CloudTrail, annotazioni MCP, osservazioni del protocollo A2A e webhook GitHub/GitLab. Questi producono bordi dove observed=true. La loro sicurezza dipende dalla fonte: una classificazione pgAudit READ è attributed (il database sa chi ha eseguito la query e se si è trattato di una lettura o di una scrittura); uno MCP readOnlyHint è approximate per specifica: la specifica MCP stessa afferma che le annotazioni dello strumento non sono attendibili.

Kernel (ground Truth). Il backstop eBPF (signal_source=ebpf) osserva a livello di chiamata di sistema. È il segnale che un agente non può aggirare. Quando il livello eBPF vede uno connect() o uno write() che la telemetria cooperativa non ha segnalato, non si tratta di un gap di registrazione: è un segnale anti-evasione. Il modulo di sicurezza unisce le osservazioni lato kernel e lato cooperativo in un’anomalia correlata, quindi un agente che silenzia la propria telemetria diventa una scoperta, non un punto cieco.

La mappa di accesso è una query su questi bordi, non uno schema separato. La deriva del privilegio minimo è il sottoinsieme in cui i due flag non sono d’accordo.

Come la deriva diventa una scoperta

Un disaccordo tra Permitted e Observed è il segnale grezzo. Il motore lo classifica in uno dei due tipi di deriva prima che entri nella coda delle anomalie:

// DriftKind classifica una deriva del privilegio minimo tra consentito e osservato.
type DriftKind string

const (
    // DriftUnusedGrant è un accesso consentito mai osservato (overprovisioning).
    DriftUnusedGrant DriftKind = "unused_grant"
    // DriftViolation è un accesso osservato che non è consentito.
    DriftViolation DriftKind = "violation"
)

unused_grant significa che una policy dice che l’agente può fare qualcosa che non è mai stato visto fare. Questo è un privilegio morto: rischio portato senza alcun beneficio. È il segnale di pulizia per le revisioni periodiche degli accessi: revocare quanto non esercitato.

violation significa che l’agente è stato osservato mentre faceva qualcosa senza alcuna policy o autorizzazione. Questo è il risultato attivo. È la riga nella tabella delle differenze che riporta “scrittura non revisionata” - il limite che conta, quello a cui dà priorità la coda delle anomalie.

La classificazione non è binaria tra “fine” e “problematico”. La struttura PrivilegeDrift accoppia il vantaggio offensivo con il suo tipo:

// PrivilegeDrift è una discrepanza di privilegio minimo: un arco i cui flag Permitted
// e Observed non coincidono.
type PrivilegeDrift struct {
    Edge AccessEdge
    Kind DriftKind
}

Il bordo stesso riporta l’intera provenienza: l’origine (quale agente), la risorsa, la modalità di lettura/write, la sorgente del segnale che lo ha prodotto, la fiducia nell’attribuzione e la finestra di osservazione (FirstSeen, LastSeen, OccurrenceCount). Una scoperta di deriva non è mai “qualcosa non va da qualche parte”. Indica un agente specifico, una risorsa specifica, una modalità di accesso specifica, osservata da un raccoglitore specifico, con un intervallo di tempo.

La coda delle anomalie: non solo “diverse”, ma classificate

Quando il modulo di sicurezza crea la vista delle anomalie (l’endpoint GET /v1/m/security/anomalies), estrae la deriva dall’archivio del limite di accesso e classifica ogni violation in un’anomalia con priorità. La classificazione aggiunge contesto che il bordo grezzo non contiene:

Deriva dell’accesso. Lo scenario di base: un accesso osservato ma non consentito. L’anomalia è intitolata “Accesso imprevisto: osservato ma non consentito”, con gravità media e contrassegnata con confidence=approximate perché la deriva a livello di negozio è il segnale grezzo, non ancora riconciliato con il grafico completo da agente a identità. La vista riconciliata risiede nell’endpoint /drift della mappa di accesso; la coda delle anomalie consuma il segnale grezzo e lo etichetta onestamente.

Egress/exfiltration sospetto. Quando la risorsa sul drift edge è un endpoint di rete verso una destinazione esterna non privata (il connettore eBPF li emette come URI tcp://host:port), l’anomalia viene riclassificata in egress_exfil_suspected e promossa a gravità alta. Un agente che scrive su un endpoint esterno a cui non è mai stato concesso l’accesso rappresenta una forma di ricerca diversa rispetto a un agente che legge una tabella di database per la quale non era compreso.

Escalation di sensibilità. Quando la risorsa presenta un’etichetta di sensibilità (high o secret), la gravità viene aumentata indipendentemente dal fatto che l’accesso sia in uscita. Uno violation contro una risorsa ad alta sensibilità garantisce un triage più rapido anche se la destinazione è interna.

Ogni anomalia porta una mappa evidence con i dettagli grezzi:

ev := map[string]any{
    "origin_kind":      edge.OriginKind,
    "origin_id":        edge.OriginID.String(),
    "resource_id":      edge.ResourceID.String(),
    "mode":             string(edge.Mode),
    "signal_source":    string(edge.SignalSource),
    "occurrence_count": edge.OccurrenceCount,
    "reconciled":       false,
}

Lo reconciled: false è intenzionale. Indica al consumatore che questo è il segnale grezzo a livello di negozio, non la vista riconciliata agente-identità della mappa di accesso. La coda delle anomalie non attende che la riconciliazione emerga violation, ma non pretende che l’attribuzione sia ferma quando non lo è.

Livelli di fiducia: cosa si può dimostrare

Ogni bordo nella mappa di accesso porta un livello di confidenza. Il prodotto ne utilizza due:

  • Attribuito (confidence=attributed): l’accesso è saldamente legato alla provenienza da testimonianze proprie del collezionista. Un record pgAudit che nomina il ruolo del database dell’agente, un evento CloudTrail legato alle credenziali IAM dell’agente, un’osservazione eBPF legata a un ID processo che il runtime ha risolto a un agente. La catena di attribuzione è end-to-end.

  • Approssimativo (confidence=approximate): l’attribuzione è desumibile e potrebbe essere in perdita. Il segnale proviene da un account di servizio condiviso in cui più agenti utilizzano la stessa credenziale, da un archivio con perdita di dati (un’istanza Redis che non registra l’identità per connessione) o da un’annotazione MCP che le specifiche ritengono non attendibile. Il bordo è ancora un segnale, ma l’operatore sa che la prova è più debole.

Il livello di confidenza influisce sul punteggio di priorità dell’anomalia. La funzione di priorità (priorityFor) assegna a ciascuna anomalia un punteggio da 0 a 100 e viene scontata una deriva di confidenza approximate:

if confidence == string(sdkmodel.ConfidenceApproximate) {
    // sconto: la deriva non riconciliata è rumorosa
}

Ciò impedisce a un segnale rumoroso di identità condivisa di spostare saldamente da parte un attributed violation. Entrambi compaiono in coda; quello approximate si colloca più in basso. È lo stesso principio applicato dall’arricchimento forense: quando viene trovata un’identità condivisa (SharedIdentity: true, AgentCount > 1), la sequenza temporale rileva che “l’attribuzione per agente può essere ambigua” anziché fingere che l’attribuzione sia esatta.

Il prodotto non falsifica mai la certezza. Un bordo di sola annotazione MCP non ha lo stesso peso di uno bordo corroborato eBPF. Un risultato di deriva da un account di servizio condiviso non ha lo stesso peso di uno da un’identità per agente. L’operatore vede la differenza e valuta di conseguenza.

Deriva nella sequenza temporale forense

I risultati della deriva non esistono solo nella coda delle anomalie. Quando viene aperto un caso forense e la sua sequenza temporale viene ricostruita dal registro di audit concatenato, il modulo di sicurezza arricchisce la ricostruzione con la deriva del soggetto:

out.Drift = subjectDrift(r.Context(), sc, c.SubjectRef)

La funzione subjectDrift interroga l’access-edge store per la deriva di tipo violation in cui l’oggetto è l’origine e restituisce un elenco di voci driftRefDTO, ciascuna contenente l’origine, la risorsa, la modalità di accesso, la sorgente del segnale, il conteggio delle occorrenze e il timestamp dell’ultimo accesso. Questi vengono letti dal calcolo della deriva del negozio, non ricalcolati dal modulo di sicurezza.

La sequenza temporale riporta anche l’attribuzione dell’identità del soggetto e la provenienza dei dati, quindi un investigatore che esamina un caso vede il quadro completo: come agisce l’agente (e se tale identità è condivisa), a cosa ha avuto accesso e che non dovrebbe avere e da quali dati ha derivato le risposte. Ciascuno di questi arricchimenti è tollerante nei confronti dei vicini assenti: se il modulo di conoscenza non è installato, il lignaggio viene omesso anziché falsificato; se l’identità non ha alcun legame con l’agente risolto, l’attribuzione dice “non ancora vincolato” anziché inventarne uno.

Il ciclo di vita del triage

Un risultato originato dalla deriva entra nel sistema con lo stato open. Da lì segue il ciclo di vita del triage di ricerca standard:

  • aperto: il rilievo esiste, nessuno ha ancora preso provvedimenti.
  • triage: un operatore lo ha riconosciuto, assegnandolo per la revisione.
  • risolto: la causa sottostante è stata risolta (la sovvenzione è stata revocata, la polizza è stata inasprita, l’agente è stato rivisto).
  • respinto: l’operatore lo ha esaminato e ha stabilito che non si tratta di un rischio reale (un comportamento noto, un falso positivo di attribuzione approximate).

Ogni cambiamento dello stato di triage viene sottoposto a verifica autonoma da parte del preside reale. L’atto di respingere una scoperta viene esso stesso registrato nel registro degli elementi di prova di manomissione, in modo che un revisore possa vedere non solo quale deriva si è verificata, ma anche chi l’ha esaminata e cosa ha deciso. Le prove del risultato (tipo, gravità e hash dei dettagli) sono immutabili dopo la creazione; il triage modifica solo lo stato del flusso di lavoro.

Cosa significa in pratica

A un agente viene assegnata una chiave API con ambito a uno spazio di lavoro Claude. Il connettore di identità legge l’elenco dell’area di lavoro ed emette un policy edge: a questa chiave è consentito chiamare l’API in questo spazio di lavoro. L’agente dura tre settimane. La telemetria mostra che chiama l’API in quell’area di lavoro: nessuna deriva. Quindi una modifica della distribuzione fornisce all’agente l’accesso alla chiave di una seconda area di lavoro. La telemetria osserva l’agente che chiama entrambe le aree di lavoro. Il secondo spazio di lavoro non ha alcun vantaggio politico. Viene creato un risultato di deriva del tipo violation: osservato ma non consentito. Entra nella coda delle anomalie come access_drift, gravità media, confidenza approximate (il bordo non è stato ancora riconciliato con il grafico di identità). Se la risorsa nella seconda area di lavoro presenta un’etichetta di riservatezza high, la gravità aumenta. Il risultato rimane nella coda dell’operatore finché qualcuno non lo valuta.

Questa è la differenza tra registrazione e deriva strutturata: il risultato è classificato, attributed (in tutta onestà), prioritario e valutabile. Persiste finché qualcuno non lo risolve o lo respinge. Appare nella sequenza temporale forense se l’agente è successivamente oggetto di un caso di incidente. E ogni azione intrapresa su di esso viene registrata in una catena di cui il prodotto può dimostrare l’integrità.


La deriva non è una metrica da minimizzare. È un risultato da triage. Lo gap tra ciò che un agente è autorizzato a fare e ciò che viene osservato fare è la superficie di segnale più alta per l’applicazione del privilegio minimo, ma solo quando gap è strutturato, classificato e onesto su ciò che può dimostrare.

Per visualizzare la mappa di accesso e la superficie di drift su una tenuta di corsa, visitare la pagina del prodotto della mappa di accesso o la panoramica del prodotto.

Articoli correlati

Domande frequenti

Qual è la differenza tra una deriva unused_grant e una deriva violation?

Un unused_grant è un accesso consentito che non è mai stato osservato: privilegio morto che l'agente detiene ma non esercita. A violation è il contrario: un accesso osservato che nessuna politica o concessione consente. Entrambi sono alla deriva, ma comportano diversi profili di rischio e diverse aspettative di risposta. Uno unused_grant è un obiettivo di pulizia; a violation è un reperto attivo che potrebbe richiedere un triage immediato.

Perché la confidenza dello sconto approximate della coda delle anomalie si sposta?

Quando un bordo di deriva viene contrassegnato come approximate, la sua attribuzione è dedotta anziché provata. Potrebbe provenire da un account di servizio condiviso in cui l'attribuzione per agente crolla o da una fonte di segnale con perdita. Scontarlo nel punteggio di priorità impedisce che una deriva non riconciliata e potenzialmente rumorosa metta da parte i risultati con maggiore fiducia. La deriva appare ancora in coda; si posiziona più in basso finché l'attribuzione non si rafforza o un operatore non lo valuta.

Scopri cosa possono raggiungere i tuoi agenti

Olivares AI è la piattaforma aperta e in self-hosting per il tuo parco AI. Distribuiscila sulla tua infrastruttura e ottieni la mappa degli accessi che i tuoi team security e platform richiedono.