Il tuo agente AI presso Elevare Digital è rimasto inattivo perché una nuova policy di sicurezza a livello di riga (RLS) di PostgreSQL ha filtrato ogni riga di lavoro, facendo apparire la coda vuota. L'errore è passato inosservato finché i lavori non si sono accumulati, costringendo il team a riprogettare il modo in cui l'orchestratore rileva una coda vuota.
Il punto cieco nascosto
ARIA, il sistema AI autonomo di Elevare, interroga una tabella PostgreSQL per i lavori in sospeso. La query ha avuto successo, ha restituito zero righe e l'agente si è addormentato. In realtà, la tabella era piena. Una policy RLS limitava l'accesso SELECT a un set specifico di utenti. L'orchestratore si è connesso con un service role che non disponeva del privilegio di bypass, quindi il database ha rimosso silenziosamente ogni riga dal set di risultati. PostgreSQL tratta una lettura filtrata allo stesso modo di una tabella vuota, quindi non è apparso alcun errore, avviso o codice di errore. Un heartbeat regolare dall'agente inattivo non ha dato alcun indizio del problema.
Come l'RLS ha trasformato una coda piena in silenzio
L'RLS aggiunge un predicato a ogni riga durante una SELECT. Se il predicato è falso, la riga scompare dal risultato. Il client vede solo le righe che soddisfano la policy; non saprà mai che alcune righe sono state nascoste. Per un worker di coda, un set di risultati vuoto sembra esattamente una coda realmente vuota. L'orchestratore ha assunto che "nessuna riga = nessun lavoro" ed è entrato nel suo ciclo di inattività mentre i lavori si accumulavano dietro le quinte.
Il team ha scoperto che una policy destinata a limitare le letture ai singoli utenti aveva involontariamente coinvolto il service role stesso. Poiché il ruolo non possedeva l'attributo speciale "bypass RLS", la policy veniva applicata a ogni query emessa dall'orchestratore. Questo illustra un classico compromesso tra sicurezza e osservabilità: l'RLS protegge i dati dagli utenti non autorizzati, ma rimuove anche un utile segnale di errore per i componenti del sistema che si affidano alla visibilità.
Il pattern del canary-check
Per interrompere la dipendenza da un risultato vuoto e silenzioso, Elevare ha aggiunto un controllo "canary". Il nuovo flusso è:
- Interroga la tabella dei lavori in sospeso.
- Se vengono restituite delle righe, elaborale come prima.
- Se il risultato è vuoto, esegui una seconda query su una riga canary dedicata che deve sempre esistere.
- Se la query canary restituisce la riga prevista, la coda è realmente vuota; registra un heartbeat di inattività.
- Se anche la query canary non restituisce nulla, l'agente è cieco; genera un alert immediato.
Ora l'orchestratore distingue tre stati:
- Lavori trovati – elaborazione normale.
- Nessun lavoro, canary OK – periodo di inattività reale.
- Nessun lavoro, canary fallito – blocco RLS nascosto, attiva l'alert.
La tabella canary è una singola riga che non cambia mai. La sua configurazione ha richiesto circa un'ora, ma elimina un'intera classe di guasti silenziosi.
Cosa dovrebbero fare i team
Se gestisci worker di coda su PostgreSQL o un servizio ospitato basato su di esso (come Supabase), segui questi passaggi:
- Usa una credenziale di service-role con il flag "bypass RLS". Ciò consente ai componenti del sistema di vedere tutte le righe indipendentemente dalle policy a livello di utente.
- Audita le policy RLS per verificare la mancanza di permessi di bypass per i service role. Una policy che sembra corretta per gli utenti finali potrebbe involontariamente intrappolare i servizi interni.
- Aggiungi una tabella canary (o un equivalente riga sempre presente) e incorpora il controllo canary nella logica di inattività del worker. La query extra è economica e fornisce una rete di sicurezza chiara.
Il compromesso
L'RLS rimane uno strumento potente per imporre un accesso ai dati granulare. Previene perdite accidentali di dati e supporta architetture multi-tenant senza dover spargere filtri a livello applicativo in tutto il codice. L'aspetto negativo è che può nascondere i guasti ai componenti che si aspettano che un semplice segnale "nessuna riga" significhi "niente da fare". Il pattern canary non indebolisce l'RLS; aggiunge un passaggio di verifica leggero che ripristina l'osservabilità.
In sintesi
Una policy RLS nascosta può trasformare una coda trafficata in un vicolo cieco silenzioso, lasciando gli agenti AI inattivi mentre il lavoro si accumula. Concedi ai service role il corretto privilegio di bypass e affianca a ogni lettura di coda vuota un controllo canary; i team possono mantenere integri i propri worker autonomi ed evitare costosi punti ciechi.
