8 min

Accesso al database PostgreSQL per builder di app AI

Configura l'accesso a un database PostgreSQL per un builder di app AI con scoperta in sola lettura, credenziali limitate, migrazioni approvate e pooling sicuro.

Accesso al database PostgreSQL per builder di app AI

Un builder di app AI può collegarsi a un database PostgreSQL esistente senza possederne lo schema, ma solo se rendi concreto quel confine in PostgreSQL. Un prompt che dice "non modificare la produzione" non è un controllo. Un ruolo separato, impostazioni predefinite delle transazioni, una revisione esplicita delle migrazioni e controlli dello schema lo sono.

Il modello sicuro divide il lavoro sul database in tre corsie. La scoperta legge metadati e campioni di dati consentiti. L'applicazione legge e scrive solo le tabelle e le operazioni necessarie. Le modifiche allo schema passano attraverso un'identità di migrazione separata dopo che una persona ha approvato l'SQL esatto. Ho visto team riunire queste corsie in una comoda credenziale proprietaria, per poi scoprire che un agente aveva trattato un nome di colonna plausibile come il permesso di riprogettare una tabella attiva. La comodità è durata un pomeriggio, la pulizia molto più a lungo.

La scoperta deve essere in sola lettura per costruzione

Una connessione di scoperta deve avere accesso sufficiente per comprendere lo schema consentito, non per migliorarlo. Crea un ruolo di login che non possa creare database o ruoli, non possa aggirare la sicurezza a livello di riga e non possa ereditare privilegi inattesi da un gruppo ampio. PostgreSQL crea i nuovi ruoli senza questi poteri, ma dichiararli esplicitamente rende l'intento verificabile.

CREATE ROLE app_discovery
  LOGIN
  NOSUPERUSER
  NOCREATEDB
  NOCREATEROLE
  NOINHERIT
  NOBYPASSRLS
  CONNECTION LIMIT 3
  PASSWORD 'replace-through-secret-manager';

ALTER ROLE app_discovery SET default_transaction_read_only = on;
GRANT CONNECT ON DATABASE customer_portal TO app_discovery;
GRANT USAGE ON SCHEMA app TO app_discovery;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_discovery;

default_transaction_read_only blocca le normali scritture nelle sessioni che mantengono l'impostazione predefinita. È una cintura utile, non le bretelle. L'assenza di INSERT, UPDATE, DELETE, TRUNCATE, CREATE e della proprietà degli oggetti mantiene il ruolo confinato se un client cambia l'impostazione della transazione. Non concedere al ruolo l'appartenenza a un gruppo proprietario dell'applicazione e non renderlo proprietario di uno schema.

I permessi esistenti meritano un controllo prima che il builder si colleghi. La query seguente produce una riga per ogni privilegio di tabella, così chi esamina può individuare tutto ciò che va oltre SELECT:

SELECT table_schema, table_name, privilege_type
FROM information_schema.role_table_grants
WHERE grantee = 'app_discovery'
ORDER BY table_schema, table_name, privilege_type;

Un risultato corretto ha una forma come app | invoices | SELECT. Un risultato vuoto può indicare che la scoperta non vede una tabella necessaria; una riga che termina con UPDATE significa che il ruolo è troppo potente. Controlla anche i privilegi sullo schema con has_schema_privilege e quelli sul database con has_database_privilege, perché i permessi sulle tabelle non rivelano se il ruolo può creare oggetti altrove.

Non usare uno snapshot di produzione come pretesto per condividere una credenziale proprietaria. Una copia può comunque contenere dati dei clienti e un agente che ne possiede gli oggetti può modificarla a tal punto da rendere inutili i confronti successivi. Assegna alla scoperta un'identità dedicata in ogni ambiente.

L'ispezione del catalogo deve rimanere dentro un'allowlist

Il builder deve scoprire solo gli schemi approvati e registrare ciò che PostgreSQL comunica davvero. information_schema offre viste portabili per tabelle, colonne, vincoli e privilegi. pg_catalog espone dettagli PostgreSQL come indici, tipi, espressioni generate e sicurezza a livello di riga. Sono entrambe fonti migliori della memoria di un LLM su una tipica tabella clienti.

Inizia con un'allowlist come app e reporting. Rifiuta pg_catalog, information_schema, gli schemi temporanei, gli schemi delle estensioni e ogni schema tenant non elencato come destinazione dell'applicazione. La query deve filtrare a livello di database, ruolo e SQL; un'allowlist solo nel prompt può sparire durante una conversazione successiva.

SELECT
  c.table_schema,
  c.table_name,
  c.ordinal_position,
  c.column_name,
  c.data_type,
  c.is_nullable,
  c.column_default
FROM information_schema.columns AS c
WHERE c.table_schema IN ('app', 'reporting')
ORDER BY c.table_schema, c.table_name, c.ordinal_position;

Salva il risultato come snapshot dello schema con l'ora di acquisizione e un identificatore del database. Lo snapshot dimostra ciò che il generatore ha visto. Non è una verità permanente. PostgreSQL può cambiare tra la scoperta e la generazione del codice, quindi confronta un'impronta aggiornata prima del deployment. Un'impronta pratica può calcolare un hash delle descrizioni ordinate di tabelle, colonne, tipi, nullabilità, valori predefiniti, vincoli e indici. Se l'impronta differisce, fermati e ripeti la scoperta invece di indovinare quale modifica sia innocua.

Il campionamento delle righe richiede una decisione sui permessi separata. I metadati delle colonne raramente contengono dati personali, mentre i campioni di righe spesso li contengono. Per la generazione del codice, preferisci non campionare righe. Se servono esempi, esponi una vista che rimuove o maschera segreti e identificatori diretti, poi concedi SELECT solo su quella vista. LIMIT 10 non rende sicura una query sensibile, riduce solo la dimensione della fuga di dati.

Anche il percorso di ricerca merita lo stesso trattamento. Impostalo sullo schema approvato più pg_catalog, qualifica i nomi delle tabelle generate e non fare mai affidamento sul primo oggetto che PostgreSQL risolve. Un attaccante o una migrazione distratta può creare un oggetto con lo stesso nome in uno schema scrivibile. Nomi qualificati come app.orders eliminano l'ambiguità.

Il ruolo runtime deve corrispondere alle azioni reali dell'utente

Scoperta e runtime sono lavori diversi. L'applicazione runtime può dover inserire un ordine, aggiornare una bozza o chiamare una funzione progettata con cura, ma questo non giustifica un accesso in scrittura ampio su tutto lo schema scoperto. Costruisci una matrice dei permessi a partire dalle azioni dell'utente, poi traduci ogni azione nel permesso PostgreSQL più limitato possibile.

Per esempio, un visualizzatore di fatture può richiedere SELECT su app.invoices e app.invoice_lines, mentre una funzione per le note richiede SELECT e INSERT su app.invoice_notes. Probabilmente non richiede DELETE sulle fatture, accesso ai record di reimpostazione delle password o creazione di schemi. Concedi l'uso delle sequenze solo quando un inserimento dipende davvero da quella sequenza. PostgreSQL tratta le sequenze come oggetti separati, cosa che sorprende i generatori testati con un account proprietario.

Viste e funzioni possono restringere ulteriormente la superficie. Una vista può esporre le colonne approvate nascondendo i campi interni. Una funzione SECURITY DEFINER può eseguire una singola operazione controllata che i normali permessi non riescono a esprimere, ma richiede un search_path fisso, controlli rigorosi sugli input e un proprietario senza poteri superflui. Tratta questa funzione come codice privilegiato, non come una scorciatoia per aggirare il modello dei permessi.

La sicurezza a livello di riga aggiunge un confine sui dati dentro una tabella condivisa. Non sostituisce i permessi sulle tabelle. PostgreSQL prima controlla se il ruolo può eseguire l'operazione, poi applica le policy di sicurezza delle righe quando sono abilitate e pertinenti. Esegui i test con l'esatto ruolo runtime, perché i proprietari delle tabelle e i ruoli con BYPASSRLS possono sfuggire alle policy. Un test eseguito con il proprietario della migrazione dimostra ben poco su ciò che un utente finale può vedere.

Tieni i segreti fuori dai prompt, dal codice generato, dai bundle del browser, dai log di build e dagli screenshot. Metti la credenziale runtime nel gestore di segreti dell'ambiente di hosting e iniettala solo nel processo server. Le applicazioni mobili e web non possono mantenere segreta una password PostgreSQL, quindi devono chiamare un'API server anziché collegarsi direttamente. Ruota indipendentemente le credenziali di scoperta, runtime e migrazione: una fuga in una corsia non deve aprire le altre due.

Il potere di migrazione appartiene a un percorso di approvazione separato

Un builder di app può proporre migrazioni, ma non deve eseguirle con la propria sessione di scoperta o runtime. Assegna il lavoro di migrazione a un ruolo separato oppure lascia che un sistema di deployment consolidato assuma quel ruolo per un job approvato. Mantieni la sua credenziale indisponibile durante le normali sessioni di chat e anteprima.

L'approvazione deve coprire l'SQL esatto, l'identità del database di destinazione, l'impronta dello schema usata per prepararla e il comportamento previsto in termini di lock o riscritture. Approvare una frase in linguaggio naturale come "aggiungi lo stato del cliente" lascia troppo spazio. La modifica eseguibile potrebbe aggiungere una colonna di testo nullable, ricostruire una tabella grande, inventare un enum o aggiornare tutte le righe esistenti. Sono operazioni diverse, con modalità di errore diverse.

Uso un pacchetto di migrazione compatto:

  1. Il motivo della modifica e la versione dell'applicazione che la richiede.
  2. L'SQL esatto di avanzamento e, quando è realistico, l'SQL esatto di annullamento.
  3. Oggetti, privilegi e righe che i comandi possono influenzare.
  4. Query preliminari, risultati attesi e un'impronta aggiornata dello schema.
  5. Timeout dei lock, timeout delle istruzioni, riferimento a backup o snapshot e responsabile del rilascio.

Uno script di annullamento non è sempre un rollback. Eliminare una colonna appena aggiunta può invertire la modifica al catalogo, ma distrugge anche i dati scritti dopo il rilascio. Il DDL transazionale di PostgreSQL aiuta con molte operazioni sul catalogo, tuttavia una transazione non può ripristinare effetti esterni o dati eliminati da un comando successivo. Etichetta chiaramente gli annullamenti distruttivi invece di trattare DOWN come una parola magica.

Imposta lock_timeout affinché una migrazione fallisca invece di attendere dietro una transazione occupata bloccando nuovo lavoro. Imposta statement_timeout in base all'operazione esaminata. Esegui di nuovo le query preliminari nella finestra di modifica. Se dimensione della tabella, oggetti in conflitto, conteggi di valori null o impronta dello schema differiscono dalle ipotesi approvate, interrompi. L'agente deve restituire un rapporto sulle discrepanze, non improvvisare una nuova migrazione contro la produzione.

Non approvare automaticamente una migrazione perché i test generati sono passati. I test di solito vengono eseguiti su uno schema piccolo e pulito e non rilevano code di lock, vecchi valori null, vincoli insoliti, estensioni e versioni dell'applicazione ancora in servizio. L'approvazione è il momento in cui una persona riconcilia l'intento generato con il sistema attivo.

Il pooling delle connessioni cambia il calcolo della sicurezza

Controlla il codice prima dell'accesso al database
Esporta il codice generato e controlla ogni query PostgreSQL rispetto allo schema approvato.

Un pool riutilizza le sessioni del database, quindi lo stato della sessione può sopravvivere alla richiesta che l'ha creato. Se una richiesta esegue SET search_path, cambia ruolo, crea un oggetto temporaneo o disabilita un timeout, il successivo utilizzatore può ereditarne il risultato. L'applicazione deve evitare lo stato di sessione modificabile oppure reimpostarlo in modo affidabile quando una connessione torna nel pool.

Il pooling delle transazioni rende il confine più rigido. Un client può ricevere una sessione server diversa dopo ogni transazione, spezzando le ipotesi su istruzioni preparate di sessione, tabelle temporanee, advisory lock e impostazioni a livello di sessione. I builder spesso generano codice che funziona con una connessione diretta e fallisce dietro un pool perché non modellano mai questa differenza. Decidi se il pool usa la modalità sessione o transazione, poi includi tale modalità nella generazione e nei test.

Definisci il budget delle connessioni prima del deployment. Parti dalle connessioni consentite dal database, riserva capacità per amministrazione, migrazioni, monitoraggio e altri servizi, quindi dividi il resto tra le istanze dell'applicazione. Se dieci istanze aprono ciascuna venti connessioni, PostgreSQL vede duecento sessioni potenziali anche quando il traffico è tranquillo. Un pool piccolo e prudente con una coda è di solito più sicuro che moltiplicare le connessioni finché il database non le rifiuta.

Usa i timeout lato server come protezioni aggiuntive: statement_timeout limita le istruzioni lunghe, lock_timeout limita l'attesa dei lock e idle_in_transaction_session_timeout rimuove le sessioni che tengono aperta una transazione senza fare nulla. Imposta valori per ogni ruolo invece di confidare che ogni client generato se ne ricordi. Verificali con SHOW usando il ruolo effettivo e attraverso il pool effettivo.

I controlli di integrità devono essere economici. SELECT 1 conferma un viaggio di andata e ritorno, ma non che l'applicazione possa raggiungere una tabella approvata o che il suo percorso di ricerca sia corretto. Un controllo di disponibilità può interrogare una piccola vista stabile con il ruolo runtime. Tieni le migrazioni fuori dall'avvio dell'applicazione: istanze simultanee che gareggiano per modificare lo schema creano proprio l'accoppiamento che questo progetto vuole eliminare.

Le colonne inventate devono fallire prima che una query venga eseguita

Gli LLM inventano identificatori plausibili. Se un prompt parla del nome visualizzato di un cliente, il codice generato potrebbe cercare customers.display_name anche quando il database memorizza given_name e family_name. Il database rifiuterà la query, meglio che leggere silenziosamente il campo sbagliato, ma un errore di produzione resta una pessima strategia di convalida dello schema.

Genera un artefatto tipizzato dello schema dallo snapshot approvato del catalogo e rendilo l'unica fonte per la costruzione delle query. Una tabella o una colonna assente dall'artefatto deve causare un errore di generazione. Non lasciare che il modello ripari l'errore aggiungendo una migrazione, a meno che l'attività non entri esplicitamente nella corsia delle migrazioni. Un identificatore mancante può indicare una scoperta non aggiornata, un errore ortografico, l'ambiente sbagliato o un reale requisito di prodotto. Ognuno richiede una risposta diversa.

I controlli statici devono analizzare l'SQL e risolvere ogni relazione e colonna rispetto allo snapshot. Poi prepara le istruzioni su un database usa e getta o in una transazione che non può scrivere. Il parser di PostgreSQL intercetta colonne sconosciute, riferimenti ambigui, errori nei tipi degli operatori e molti cast errati senza richiedere dati aziendali validi. Esegui i test di integrazione con il ruolo runtime affinché partecipino anche permessi e policy sulle righe.

Il rapporto di errore deve fornire abbastanza dettagli per una decisione umana. Includi posizione nell'SQL, identificatore irrisolto, identificatori validi vicini, impronta dello snapshot e identità del database di destinazione. I suggerimenti sono utili, ma la sostituzione automatica approssimativa è pericolosa. Cambiare billing_address_id in shipping_address_id perché i nomi si assomigliano può produrre SQL valido con un significato aziendale falso.

Per filtri e ordinamenti dinamici, mappa i nomi dell'API pubblica a un insieme chiuso di espressioni SQL qualificate. Non inserire mai in SQL un identificatore fornito dal modello, nemmeno tramite un parametro di valore. I parametri proteggono i valori, non i nomi di tabelle o colonne. Se gli utenti possono scegliere un campo di ordinamento, traduci created in un'espressione nota come app.orders.created_at; rifiuta ogni token sconosciuto.

La deriva dello schema deve fermare un rilascio, non attivare una riconciliazione creativa. Rigenera lo snapshot, mostra le differenze e ripeti i test. Il ritardo può sembrare pignolo, ma costa meno che distribuire codice la cui comprensione del database esiste solo in una trascrizione di conversazione.

L'SQL distruttivo richiede una policy di blocco e prove

Pianifica prima il perimetro del database
La modalità di pianificazione di Koder.ai ti permette di definire i limiti dello schema prima di iniziare a generare l'applicazione.

Un builder deve classificare l'SQL prima che chiunque possa eseguirlo. Blocca DROP, TRUNCATE, DELETE o UPDATE ampi senza un predicato esaminato, cambi di proprietà, escalation dei privilegi, modifiche alle estensioni e comandi rivolti fuori dagli schemi approvati. Considera ALTER TABLE come operazione che richiede revisione, non automaticamente sicura. Un cambio di tipo di colonna o un nuovo vincolo non nullo può eseguire scansioni o riscritture dei dati e mantenere lock rilevanti.

La sola corrispondenza testuale è debole perché l'SQL contiene commenti, identificatori tra virgolette, funzioni e molti modi per esprimere effetti collaterali. Analizza le istruzioni con un parser che conosca PostgreSQL, ispeziona i loro alberi sintattici e affidati anche al ruolo del database per negare le azioni vietate. Il classificatore migliora la revisione; i privilegi applicano il confine. Nessuno dei due deve portare da solo tutto il peso.

Usa un database di staging ripristinato da uno snapshot recente e adeguatamente protetto quando una migrazione dipende dalle forme reali delle tabelle o dalle distribuzioni dei dati. Applica lì l'esatto pacchetto di migrazione, registra durata e osservazioni sui lock, esegui i test dell'applicazione con le credenziali runtime, poi elimina l'ambiente. Non modificare silenziosamente l'SQL tra staging e produzione. Ogni modifica crea un nuovo artefatto che richiede una nuova impronta e approvazione.

I log devono collegare una proposta alla sua esecuzione senza registrare segreti o righe sensibili. Registra chi ha approvato l'artefatto immutabile della migrazione, il suo digest, l'identità della destinazione, lo stato di inizio e fine e i dettagli dell'errore PostgreSQL. Conserva le differenze generate e i risultati preliminari. Una chat con un agente è contesto utile, ma non è una traccia di audit perché gli utenti possono ramificare, riprovare e riformulare le istruzioni.

Snapshot e controlli di rollback riducono il tempo di recupero, ma non rendono accettabile l'SQL distruttivo. Uno snapshot può ripristinare un intero database a un punto precedente quando serve invece una sola colonna eliminata, e il ripristino può scartare scritture legittime avvenute dopo lo snapshot. Prova il recupero separatamente e documenta chi può avviarlo.

Quando uso Koder.ai per un'app che tocca un database consolidato, mantengo il lavoro in modalità di pianificazione finché non ho esaminato il codice esportato e il confine del database proposto; snapshot e rollback sono controlli di recupero, non il permesso per saltare quella revisione. La stessa regola vale per qualunque builder: la comodità del prodotto deve stare dietro l'applicazione dei controlli del database.

Le modifiche allo schema devono tollerare versioni miste dell'applicazione

Esamina le richieste dati di React
Esporta il codice React e controlla che le richieste del client espongano solo i campi necessari agli utenti.

Una migrazione è sicura solo quando sia la vecchia sia la nuova applicazione possono funzionare durante la finestra di rilascio. La produzione raramente passa da una versione all'altra in un solo istante. Le richieste possono raggiungere vecchie istanze mentre ne iniziano di nuove, i job in coda possono trasportare payload più vecchi e un rollback può riportare il codice di ieri contro lo schema di oggi. Un builder di app che convalida solo il codice finale rispetto allo schema finale non considera questa sovrapposizione.

Privilegia prima le modifiche additive. Aggiungi una colonna nullable, una nuova tabella o un indice senza rimuovere il percorso precedente. Distribuisci codice che sa leggere entrambe le rappresentazioni e scrive nella nuova quando opportuno. Popola le righe esistenti con un job esaminato separatamente, osserva errori e ritardo, poi rendi autorevole il nuovo campo. Rimuovi la vecchia colonna o il vincolo in un rilascio successivo dopo aver verificato che nessun codice in esecuzione lo usi.

Questa sequenza richiede più tempo che generare una sola istruzione ALTER TABLE, ma isola gli errori. Se il nuovo codice si comporta male prima della rimozione, il vecchio percorso esiste ancora. Se un popolamento rimane indietro, può fermarsi senza tenere in ostaggio il rilascio dell'applicazione. Se il deployment viene annullato, la vecchia applicazione riconosce ancora il database. Il rilascio aggiuntivo costa meno che scoprire durante il rollback che il binario precedente interroga una colonna già eliminata dalla migrazione.

Le rinomine richiedono particolare cura perché PostgreSQL cambia il nome immediatamente. Un generatore può proporre di rinominare customer_ref in customer_id perché il nuovo nome suona meglio. Le vecchie istanze falliranno appena la migrazione viene confermata. Aggiungi customer_id, mantieni sincronizzati entrambi i campi nel codice dell'applicazione o con un trigger esaminato in modo mirato, sposta i lettori e rimuovi customer_ref solo dopo che i vecchi scrittori non esistono più. La duplicazione temporanea è un debito visibile con una condizione di rimozione; una rinomina immediata è un accoppiamento di rilascio invisibile.

Anche valori predefiniti e vincoli non null possono nascondere lavoro. Prima di approvare SET NOT NULL, conta i valori null esistenti e dimostra che ogni writer attivo fornisce un valore. Per tabelle grandi o molto usate, esamina come la versione di PostgreSQL convalida il vincolo e quali lock acquisisce. Un builder deve riportare queste precondizioni invece di dedurle da uno schema senza traffico rappresentativo.

I popolamenti dei dati non devono viaggiare dentro una transazione dello schema senza limiti. Aggiorna le righe in batch misurati tramite un worker approvato, registra l'avanzamento con un cursore stabile e rendi idempotenti i tentativi. Un tentativo è idempotente quando applicarlo due volte produce lo stato previsto, non solo quando PostgreSQL accetta la seconda query. Per valori derivati, registra la versione della derivazione se il codice successivo potrebbe calcolarli diversamente.

Il pacchetto di rilascio deve indicare quattro punti di compatibilità:

  1. La versione più vecchia dell'applicazione autorizzata a funzionare prima della migrazione.
  2. Lo stato dello schema accettato sia dalla vecchia sia dalla nuova versione.
  3. Il segnale che consente il rilascio di pulizia distruttivo.
  4. Il percorso di recupero se il nuovo codice viene annullato dopo che i dati sono cambiati.

Le query generate devono evitare SELECT * durante queste transizioni. Aggiungere una colonna può cambiare il costo della scansione, la decodifica dei risultati, la mappatura posizionale e l'esposizione dei dati anche se il vecchio SQL continua a essere analizzabile. Elenca esplicitamente le colonne qualificate e genera i decoder dallo stesso snapshot dello schema. In questo modo la revisione del codice mostra anche con precisione quali dati attraversano il confine del database.

Gli strumenti di migrazione preparati spesso registrano una versione applicata in una tabella, ma un numero di versione da solo non dimostra la compatibilità. Registra il digest dell'artefatto SQL esatto, perché due file con lo stesso nome descrittivo possono contenere comandi diversi. L'esecutore deve rifiutare una versione già registrata con un digest differente. Deve anche rifiutare una migrazione successiva quando manca un predecessore richiesto.

Non lasciare che ogni istanza dell'applicazione esegua le migrazioni all'avvio. Anche quando uno strumento di migrazione usa un advisory lock, l'avvio dipende ora da una credenziale privilegiata e dal completamento del lavoro sullo schema prima che scadano i controlli di integrità. Esegui la migrazione in un solo job di rilascio, attendi il risultato registrato e avvia le istanze runtime con un'identità che non può modificare lo schema. Se il sistema di rilascio non riesce a separare queste fasi, correggilo prima di assegnare all'applicazione poteri da proprietario.

Prova questa sequenza temporale, non solo la destinazione: vecchio codice su vecchio schema, vecchio codice su schema esteso, nuovo codice su schema esteso e codice annullato dopo nuove scritture. La pulizia riceve un test separato più tardi. Questa matrice intercetta modifiche sintatticamente valide ma operativamente impossibili da annullare.

Dimostra il confine con test negativi

Un progetto di sicurezza è incompleto finché le azioni vietate non falliscono nei test. Collegati come discovery e tenta un inserimento, una creazione di tabella e un SET TRANSACTION READ WRITE. Collegati come runtime e tenta l'accesso a una tabella senza permessi, una lettura tra tenant coperta dalla sicurezza a livello di riga e una modifica dello schema. Il risultato atteso è un errore di autorizzazione PostgreSQL, non una promessa nel log di un agente.

Esegui anche test positivi. La scoperta deve comunque leggere ogni voce consentita del catalogo. Il runtime deve eseguire ogni azione utente approvata attraverso il pool. L'esecuzione della migrazione deve funzionare solo attraverso il percorso di approvazione. Un confine che blocca il normale lavoro del prodotto inviterà qualcuno a sostituirlo con una credenziale proprietaria durante un incidente.

Conserva un piccolo contratto di accesso accanto al codice sorgente dell'applicazione. Deve indicare il database, gli schemi consentiti, l'ambito della scoperta, le operazioni runtime, la modalità del pool, la policy dei timeout, gli approvatori delle migrazioni, il metodo di impronta dello schema e le istruzioni vietate. Confronta i permessi reali con quel contratto nei controlli continui. La deriva dei permessi PostgreSQL è deriva di configurazione, anche quando nessuno ha modificato il codice dell'applicazione.

Ricontrolla dopo modifiche ai ruoli, nuove tabelle, database ripristinati, aggiornamenti del pool e modifiche dell'hosting. I privilegi predefiniti contano per gli oggetti futuri: concedere SELECT ON ALL TABLES copre le tabelle attuali, non quelle create in seguito. Decidi se i nuovi oggetti devono rimanere invisibili fino alla revisione o essere inclusi tramite privilegi predefiniti configurati in modo restrittivo. Preferisco che siano invisibili per impostazione predefinita, perché un permesso esplicito porta la nuova tabella nella discussione sull'accesso.

Includi la revoca nel piano di test. Disabilita la credenziale di scoperta e verifica che il traffico runtime continui; disabilita il runtime e verifica che gli strumenti di migrazione non sostituiscano silenziosamente la loro identità più potente. Poi ruota ogni segreto mentre le connessioni sono attive e osserva se il pool ritira le vecchie sessioni entro la finestra prevista. Un cambio di password non termina le sessioni già autenticate, quindi le procedure di rotazione richiedono un riciclo esplicito del pool o una policy di terminazione delle sessioni PostgreSQL.

Esamina i messaggi di errore per rilevare divulgazioni accidentali durante questi test. Gli errori PostgreSQL possono includere nomi di relazioni, frammenti di SQL, nomi di vincoli e valori forniti. Invia gli errori dettagliati ai log server con accesso limitato, restituisci un errore pubblico stabile ai client e non inoltrare mai un intero flusso di errori di produzione in una conversazione con un agente. Al builder servono la posizione dell'istruzione e una risposta del database ripulita per correggere il codice; non gli servono i valori dei clienti.

Un ultimo test intercetta un numero sorprendente di integrazioni non sicure: rimuovi completamente la credenziale di migrazione ed esegui la suite di test dell'applicazione. Se l'avvio normale, i controlli di integrità, le anteprime o la gestione delle richieste falliscono, la proprietà dello schema si è infiltrata nel percorso runtime. Correggi questo accoppiamento prima di collegare il builder alla produzione. Un builder di app AI può lavorare con un database che non possiede, ma PostgreSQL deve poter dire no quando il codice generato dimentica l'accordo.

Domande frequenti

Un builder di app AI può usare il mio database PostgreSQL esistente?

Sì, se il builder si collega tramite ruoli dedicati e analizza solo gli schemi approvati. Mantieni scoperta, query a runtime e migrazioni su percorsi di autorizzazione distinti, così collegare lo strumento non gli assegna la proprietà dello schema.

Un utente PostgreSQL in sola lettura garantisce che i dati non cambieranno?

Un ruolo con solo SELECT e senza proprietà di oggetti è il controllo principale. default_transaction_read_only aggiunge protezione, ma non deve compensare permessi troppo ampi o appartenenze ereditate.

Devo dare al builder la password del proprietario del database?

No. Una credenziale proprietaria annulla il perimetro e consente al codice generato di modificare privilegi, tabelle e dati. Crea credenziali separate per scoperta, runtime e job di migrazione controllato.

Come può un builder di app apprendere il mio schema in sicurezza?

Permettigli di interrogare le viste approvate di information_schema e pg_catalog tramite un ruolo con permessi limitati, poi salva uno snapshot con impronta. Evita di campionare righe, a meno che non sia stata preparata una vista mascherata per questo scopo.

Cosa succede quando l'AI inventa una colonna PostgreSQL?

La generazione dovrebbe fallire rispetto a uno snapshot tipizzato dello schema prima del deployment. Segnala il nome sconosciuto e i nomi validi vicini, ma lascia a una persona decidere se la correzione richiede codice, una nuova scoperta o una migrazione approvata.

L'applicazione può collegarsi direttamente da browser o app mobile?

Non dovrebbe collegarsi direttamente a PostgreSQL, perché questi client non possono mantenere segreta una password del database. Inserisci l'accesso al database in un processo server e lascia che browser o app mobile chiamino la sua API.

Mi serve un pool di connessioni per le applicazioni generate?

Di solito sì, ma va configurato con attenzione. Limita le sessioni totali, scegli la modalità sessione o transazione, reimposta lo stato modificabile e prova il codice generato attraverso lo stesso pool usato in produzione.

Le migrazioni PostgreSQL possono essere annullate in sicurezza?

Alcune modifiche al catalogo si annullano senza problemi dentro una transazione, mentre la perdita di dati e gli effetti esterni no. Esamina separatamente l'SQL di avanzamento e quello di annullamento, e considera gli snapshot strumenti di recupero, non una prova che una modifica sia sicura.

Come impedisco al builder di modificare tabelle non approvate?

Usa allowlist degli schemi, nomi qualificati, permessi limitati, una policy SQL analizzata e test negativi sui permessi. Il ruolo PostgreSQL deve rifiutare l'operazione anche se il modello o il controllo della policy sbaglia.

Con quale frequenza il builder deve ripetere la scoperta dello schema?

Ripeti la scoperta ogni volta che l'impronta salvata cambia e dopo migrazioni, ripristini o modifiche dell'ambiente. Non aggiornare silenziosamente durante un rilascio: mostra le differenze e riesegui la convalida sul nuovo snapshot.

Related posts