8 min

Dostęp do bazy PostgreSQL dla twórców aplikacji AI

Skonfiguruj dostęp do bazy PostgreSQL dla kreatora aplikacji AI z wykrywaniem tylko do odczytu, poświadczeniami o ograniczonym zakresie, zatwierdzonymi migracjami i bezpieczną pulą połączeń.

Dostęp do bazy PostgreSQL dla twórców aplikacji AI

Kreator aplikacji AI może połączyć się z istniejącą bazą PostgreSQL, nie będąc właścicielem jej schematu, ale tylko wtedy, gdy tę granicę wymusisz w PostgreSQL. Prompt w rodzaju „nie zmieniaj produkcji” nie jest mechanizmem kontroli. Osobna rola, domyślne ustawienia transakcji, jawny przegląd migracji i kontrole schematu już nim są.

Bezpieczny model dzieli pracę z bazą na trzy ścieżki. Wykrywanie odczytuje metadane i próbki dozwolonych danych. Aplikacja odczytuje i zapisuje wyłącznie tabele oraz wykonuje operacje, których potrzebuje. Zmiana schematu przechodzi przez osobną tożsamość migracyjną dopiero po zatwierdzeniu dokładnego SQL przez człowieka. Widziałem zespoły, które łączyły te ścieżki w jedno wygodne poświadczenie właściciela, a potem odkrywały, że agent uznał wiarygodnie brzmiącą nazwę kolumny za zgodę na przebudowę działającej tabeli. Wygoda trwała jedno popołudnie, sprzątanie znacznie dłużej.

Wykrywanie powinno być tylko do odczytu już z założenia

Połączenie do wykrywania potrzebuje dostępu wystarczającego, by zrozumieć dozwolony schemat, ale niewystarczającego, by go ulepszać. Utwórz rolę z logowaniem, która nie może tworzyć baz ani ról, nie może omijać zabezpieczeń wierszy i nie dziedziczy nieoczekiwanych uprawnień z szerokiej grupy. PostgreSQL tworzy nowe role bez tych uprawnień, ale jawne deklaracje pozwalają zweryfikować intencję.

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 blokuje zwykłe zapisy w sesjach, które zachowują ustawienie domyślne. To przydatny pas bezpieczeństwa, ale nie szelki. Brak INSERT, UPDATE, DELETE, TRUNCATE, CREATE i własności utrzymuje rolę w granicach, jeśli klient zmieni ustawienie transakcji. Nie dodawaj tej roli do grupy właścicieli aplikacji i nie ustawiaj jej jako właściciela schematu.

Przed podłączeniem kreatora warto sprawdzić istniejące uprawnienia. Poniższe zapytanie zwraca jeden wiersz na każde uprawnienie do tabeli, dzięki czemu osoba sprawdzająca łatwo zauważy wszystko poza 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;

Prawidłowy wynik ma postać app | invoices | SELECT. Pusty wynik może oznaczać, że wykrywanie nie widzi potrzebnej tabeli. Wiersz kończący się na UPDATE oznacza, że rola ma zbyt duże uprawnienia. Sprawdź też uprawnienia do schematu przez has_schema_privilege i do bazy przez has_database_privilege, bo uprawnienia do tabel nie pokazują, czy rola może tworzyć obiekty w innym miejscu.

Nie wykorzystuj migawki produkcyjnej jako pretekstu do współdzielenia poświadczeń właściciela. Kopia nadal może zawierać dane klientów, a agent mający własność może zmienić ją tak gruntownie, że późniejsze porównania stracą sens. W każdym środowisku dawaj wykrywaniu osobną tożsamość.

Przegląd katalogu musi trzymać się listy dozwolonych elementów

Kreator powinien wykrywać wyłącznie zatwierdzone schematy i zapisywać to, co faktycznie zgłasza PostgreSQL. information_schema udostępnia przenośne widoki tabel, kolumn, ograniczeń i uprawnień. pg_catalog pokazuje szczegóły PostgreSQL, takie jak indeksy, typy, wyrażenia generowane i zabezpieczenia wierszy. Oba źródła są lepsze niż pamięć LLM o typowej tabeli klientów.

Zacznij od listy dozwolonych schematów, na przykład app i reporting. Odrzuć pg_catalog, information_schema, schematy tymczasowe, schematy rozszerzeń i każdy nieuwzględniony schemat najemcy jako cele aplikacji. Zapytanie powinno filtrować na poziomie bazy, roli i SQL. Lista dozwolonych elementów podana wyłącznie w prompcie może zniknąć w późniejszej rozmowie.

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;

Zapisz wynik jako migawkę schematu z czasem pobrania i identyfikatorem bazy. Migawka jest dowodem tego, co widział generator. Nie jest niezmienną prawdą. PostgreSQL może się zmienić między wykrywaniem a generowaniem kodu, dlatego przed wdrożeniem porównaj świeży odcisk. Praktyczny odcisk może haszować uporządkowane opisy tabel, kolumn, typów, wartości null, domyślnych, ograniczeń i indeksów. Jeśli odcisk się różni, zatrzymaj pracę i wykryj schemat ponownie zamiast zgadywać, która zmiana jest nieszkodliwa.

Próbkowanie wierszy to osobna decyzja o uprawnieniach. Metadane kolumn rzadko zawierają dane osobowe, za to próbki wierszy często je zawierają. Do generowania kodu najlepiej nie pobierać żadnych wierszy. Jeśli przykłady są konieczne, udostępnij widok, który usuwa lub maskuje sekrety i bezpośrednie identyfikatory, a następnie nadaj SELECT wyłącznie do tego widoku. LIMIT 10 nie czyni wrażliwego zapytania bezpiecznym, tylko zmniejsza skalę wycieku.

search_path wymaga równie uważnego podejścia. Ustaw go na zatwierdzony schemat oraz pg_catalog, kwalifikuj generowane nazwy tabel i nigdy nie polegaj na obiekcie, który PostgreSQL rozwiąże jako pierwszy. Atakujący lub niedbała migracja może utworzyć obiekt o tej samej nazwie w zapisywalnym schemacie. Kwalifikowane nazwy, takie jak app.orders, usuwają tę niejednoznaczność.

Rola uruchomieniowa powinna odpowiadać rzeczywistym działaniom użytkownika

Wykrywanie i działanie aplikacji to różne zadania. Aplikacja może potrzebować dodać zamówienie, zaktualizować szkic lub wywołać starannie zaprojektowaną funkcję, ale to nie uzasadnia szerokiego dostępu do zapisu w całym wykrytym schemacie. Zbuduj macierz uprawnień na podstawie działań użytkownika, a potem przełóż każde działanie na najmniejsze możliwe uprawnienie PostgreSQL.

Na przykład przeglądarka faktur może potrzebować SELECT do app.invoices i app.invoice_lines, a funkcja notatek potrzebuje SELECT oraz INSERT do app.invoice_notes. Najpewniej nie potrzebuje DELETE na fakturach, dostępu do rekordów resetowania haseł ani tworzenia schematu. Nadaj uprawnienie do użycia sekwencji tylko wtedy, gdy wstawianie rzeczywiście korzysta z tej sekwencji. PostgreSQL traktuje sekwencje jako osobne obiekty, co zaskakuje generatory testowane na koncie właściciela.

Widoki i funkcje mogą jeszcze bardziej zawęzić powierzchnię dostępu. Widok może pokazywać zatwierdzone kolumny, ukrywając pola wewnętrzne. Funkcja SECURITY DEFINER może wykonać jedną kontrolowaną operację, której nie da się wyrazić zwykłymi uprawnieniami, ale potrzebuje stałego search_path, ścisłej kontroli danych wejściowych i właściciela bez zbędnych uprawnień. Traktuj taką funkcję jak uprzywilejowany kod, a nie skrót omijający model uprawnień.

Zabezpieczenia na poziomie wierszy dodają granicę danych we wspólnej tabeli. Nie zastępują uprawnień do tabel. PostgreSQL najpierw sprawdza, czy rola może wykonać operację, a następnie stosuje polityki bezpieczeństwa wierszy, gdy są włączone i mają zastosowanie. Testuj na dokładnie tej roli uruchomieniowej, ponieważ właściciele tabel i role z BYPASSRLS mogą omijać polityki. Test wykonany przez właściciela migracji prawie nic nie mówi o tym, co zobaczy użytkownik końcowy.

Nie umieszczaj sekretów w promptach, wygenerowanym kodzie źródłowym, paczkach przeglądarkowych, logach kompilacji ani zrzutach ekranu. Umieść poświadczenia uruchomieniowe w magazynie sekretów środowiska hostingowego i wstrzykuj je wyłącznie do procesu serwerowego. Aplikacje mobilne i przeglądarkowe nie potrafią zachować hasła PostgreSQL w tajemnicy, dlatego powinny wywoływać API serwera, zamiast łączyć się bezpośrednio. Rotuj poświadczenia do wykrywania, działania aplikacji i migracji niezależnie. Wyciek w jednej ścieżce nie powinien otwierać dwóch pozostałych.

Uprawnienia do migracji wymagają osobnej ścieżki zatwierdzania

Kreator aplikacji może proponować migracje, ale nie powinien ich wykonywać w sesji wykrywania ani działania aplikacji. Daj pracy migracyjnej osobną rolę lub pozwól sprawdzonemu systemowi wdrożeniowemu przyjąć tę rolę dla jednego zatwierdzonego zadania. Nie udostępniaj jej poświadczeń podczas zwykłych rozmów i sesji podglądu.

Zatwierdzenie musi obejmować dokładny SQL, tożsamość docelowej bazy, odcisk schematu użyty do przygotowania zmiany oraz oczekiwane zachowanie blokad i przepisywania danych. Zatwierdzenie zdania w języku naturalnym, takiego jak „dodaj status klienta”, pozostawia zbyt wiele swobody. Wykonywalna zmiana może dodać nullable kolumnę tekstową, przebudować dużą tabelę, wymyślić enum albo zaktualizować każdy istniejący wiersz. To różne operacje o różnych sposobach awarii.

Stosuję zwięzły pakiet migracyjny:

  1. Powód zmiany i wersja aplikacji, która jej wymaga.
  2. Dokładny SQL do wykonania oraz, jeśli da się go uczciwie podać, dokładny SQL odwracający.
  3. Obiekty, uprawnienia i wiersze, na które mogą wpłynąć polecenia.
  4. Zapytania wstępne, oczekiwane wyniki i świeży odcisk schematu.
  5. Limit czasu blokady, limit czasu instrukcji, odwołanie do kopii zapasowej lub migawki oraz właściciel wydania.

Skrypt odwracający nie zawsze jest wycofaniem zmian. Usunięcie świeżo dodanej kolumny może cofnąć zmianę katalogu, ale niszczy też dane zapisane po wydaniu. Transakcyjne DDL PostgreSQL pomaga przy wielu operacjach na katalogu, lecz transakcja nie przywróci zewnętrznych skutków ani danych usuniętych przez późniejsze polecenie. Jasno oznaczaj niszczące odwrócenia, zamiast traktować DOWN jak magiczne słowo.

Ustaw lock_timeout, aby migracja kończyła się błędem zamiast czekać za zajętą transakcją i blokować nową pracę. Ustaw statement_timeout zgodnie z ocenioną operacją. Uruchom zapytania wstępne ponownie w oknie zmian. Jeśli rozmiar tabeli, konfliktujące obiekty, liczba wartości null albo odcisk schematu różnią się od zatwierdzonych założeń, przerwij pracę. Agent powinien zwrócić raport o niezgodności, a nie improwizować nową migrację przeciwko produkcji.

Nigdy nie zatwierdzaj automatycznie migracji tylko dlatego, że przeszły wygenerowane testy. Testy zwykle działają na małym, czystym schemacie i nie wykrywają kolejek blokad, starych wartości null, nietypowych ograniczeń, rozszerzeń ani wersji aplikacji, które nadal obsługują ruch. Zatwierdzenie to moment, w którym człowiek uzgadnia wygenerowany zamiar z działającym systemem.

Pula połączeń zmienia ocenę bezpieczeństwa

Sprawdź żądania danych w React
Wyeksportuj kod React i sprawdź, czy żądania klienta udostępniają wyłącznie pola potrzebne użytkownikom.

Pula ponownie wykorzystuje sesje bazy, więc stan sesji może przetrwać żądanie, które go utworzyło. Jeśli jedno żądanie uruchomi SET search_path, zmieni rolę, utworzy obiekt tymczasowy albo wyłączy limit czasu, kolejny użytkownik połączenia może odziedziczyć ten stan. Aplikacja musi unikać zmiennego stanu sesji albo niezawodnie go resetować, gdy połączenie wraca do puli.

Pula transakcyjna jeszcze bardziej zaostrza granicę. Po każdej transakcji klient może otrzymać inną sesję serwerową, co łamie założenia dotyczące przygotowanych instrukcji sesji, tabel tymczasowych, blokad doradczych i ustawień na poziomie sesji. Kreatory często generują kod, który działa przez bezpośrednie połączenie, lecz zawodzi za pulą, ponieważ nie uwzględniają tej różnicy. Zdecyduj, czy pula działa w trybie sesji, czy transakcji, a potem uwzględnij ten tryb w generowaniu i testach.

Zaplanuj liczbę połączeń przed wdrożeniem. Zacznij od liczby połączeń dozwolonych przez bazę, zarezerwuj miejsce na administrację, migracje, monitoring i inne usługi, a następnie podziel resztę między instancje aplikacji. Jeśli dziesięć instancji otwiera po dwadzieścia połączeń, PostgreSQL widzi dwieście potencjalnych sesji, nawet przy niewielkim ruchu. Niewielka, ostrożna pula z kolejką jest zwykle bezpieczniejsza niż mnożenie połączeń, aż baza zacznie je odrzucać.

Używaj limitów czasu po stronie serwera jako zabezpieczeń: statement_timeout ogranicza długie instrukcje, lock_timeout ogranicza oczekiwanie na blokady, a idle_in_transaction_session_timeout usuwa sesje, które utrzymują otwartą transakcję bez pracy. Ustawiaj wartości dla każdej roli, zamiast ufać, że każdy wygenerowany klient o nich pamięta. Zweryfikuj je poleceniem SHOW na rzeczywistej roli i przez rzeczywistą pulę.

Kontrole zdrowia powinny być tanie. SELECT 1 potwierdza komunikację, ale nie potwierdza, że aplikacja dociera do zatwierdzonej tabeli ani że jej ścieżka wyszukiwania jest prawidłowa. Kontrola gotowości może odpytywać niewielki, stabilny widok przez rolę uruchomieniową. Nie uruchamiaj migracji przy starcie aplikacji. Instancje równocześnie próbujące zmienić schemat tworzą dokładnie to powiązanie, które ten projekt ma usunąć.

Wymyślone kolumny powinny powodować błąd, zanim ruszy zapytanie

LLM-y wymyślają wiarygodnie brzmiące identyfikatory. Jeśli prompt mówi o nazwie wyświetlanej klienta, wygenerowany kod może sięgnąć po customers.display_name, choć baza przechowuje given_name i family_name. Baza odrzuci takie zapytanie, co jest lepsze niż ciche odczytanie niewłaściwego pola, ale błąd na produkcji nadal jest słabą strategią walidacji schematu.

Wygeneruj typowany artefakt schematu z zatwierdzonej migawki katalogu i uczyń go jedynym źródłem do budowania zapytań. Tabela lub kolumna nieobecna w tym artefakcie powinna powodować błąd generowania. Nie pozwalaj modelowi naprawiać błędu przez dodanie migracji, chyba że zadanie wyraźnie przechodzi na ścieżkę migracyjną. Brakujący identyfikator może oznaczać nieaktualne wykrywanie, literówkę, niewłaściwe środowisko albo rzeczywistą potrzebę produktu. Każda z tych sytuacji wymaga innej reakcji.

Kontrole statyczne powinny parsować SQL i rozwiązywać każdą relację oraz kolumnę względem migawki. Następnie przygotuj instrukcje względem jednorazowej bazy albo transakcji, która nie może zapisywać. Parser PostgreSQL wykrywa nieznane kolumny, niejednoznaczne odwołania, błędy typów operatorów i wiele błędnych rzutowań bez potrzeby poprawnych danych biznesowych. Uruchamiaj testy integracyjne na roli uruchomieniowej, aby brały w nich udział uprawnienia i polityki wierszy.

Raport o błędzie powinien zawierać dość informacji, by człowiek mógł podjąć decyzję. Uwzględnij pozycję w SQL, nierozwiązany identyfikator, pobliskie prawidłowe identyfikatory, odcisk migawki i tożsamość docelowej bazy. Sugestie są pomocne, ale automatyczna zamiana z przybliżonym dopasowaniem jest niebezpieczna. Zmiana billing_address_id na shipping_address_id tylko dlatego, że nazwy są podobne, może dać poprawny SQL o błędnym znaczeniu biznesowym.

W przypadku dynamicznych filtrów i sortowań mapuj publiczne nazwy API na zamknięty zestaw kwalifikowanych wyrażeń SQL. Nigdy nie wklejaj identyfikatora dostarczonego przez model do SQL, nawet obok parametru wartości. Parametry chronią wartości, nie nazwy tabel ani kolumn. Jeśli użytkownicy mogą wybrać pole sortowania, tłumacz created na znane wyrażenie, takie jak app.orders.created_at, i odrzucaj każdy nieznany token.

Dryf schematu powinien zatrzymać wydanie, a nie uruchamiać kreatywne uzgadnianie. Wygeneruj migawkę ponownie, pokaż różnicę i powtórz testy. To opóźnienie może wydawać się drobiazgowe, ale kosztuje mniej niż wdrożenie kodu, którego rozumienie bazy istnieje wyłącznie w zapisie rozmowy.

Niszczący SQL potrzebuje polityki blokowania i dowodów

Wybierz miejsce działania aplikacji
Koder.ai może uruchamiać aplikacje w wybranym kraju, gdy zasady lokalizacji danych wpływają na wdrożenie.

Kreator powinien klasyfikować SQL, zanim ktokolwiek będzie mógł go wykonać. Blokuj DROP, TRUNCATE, szerokie DELETE lub UPDATE bez sprawdzonego predykatu, zmiany własności, eskalację uprawnień, zmiany rozszerzeń i polecenia skierowane poza zatwierdzone schematy. Traktuj ALTER TABLE jako wymagające przeglądu, a nie automatycznie bezpieczne. Zmiana typu kolumny lub nowe ograniczenie nonnull może skanować lub przepisywać dane oraz utrzymywać istotne blokady.

Samo dopasowywanie tekstu jest słabe, ponieważ SQL ma komentarze, cytowane identyfikatory, funkcje i wiele sposobów wyrażania skutków ubocznych. Parsuj instrukcje parserem znającym PostgreSQL, sprawdzaj ich drzewa składniowe i jednocześnie polegaj na roli bazy, która odmawia zakazanych działań. Klasyfikator usprawnia przegląd, uprawnienia wymuszają granicę. Żaden z tych mechanizmów nie powinien dźwigać całego ciężaru.

Użyj bazy testowej odtworzonej z aktualnej, odpowiednio chronionej migawki, gdy migracja zależy od rzeczywistych kształtów tabel lub rozkładu danych. Zastosuj tam dokładny pakiet migracyjny, zapisz czas trwania i obserwacje blokad, uruchom testy aplikacji z poświadczeniami uruchomieniowymi, a potem usuń środowisko. Nie zmieniaj po cichu SQL między testami a produkcją. Każda zmiana tworzy nowy artefakt, który wymaga nowego odcisku i zatwierdzenia.

Logi powinny łączyć propozycję z wykonaniem bez zapisywania sekretów ani wrażliwych wierszy. Zapisuj, kto zatwierdził niezmienny artefakt migracji, jego skrót, tożsamość celu, status rozpoczęcia i zakończenia oraz szczegóły błędu PostgreSQL. Zachowuj wygenerowaną różnicę i wyniki kontroli wstępnych. Rozmowa z agentem jest użytecznym kontekstem, lecz nie jest zapisem audytowym, ponieważ użytkownicy mogą rozgałęziać, ponawiać i parafrazować instrukcje.

Migawki i mechanizmy wycofywania skracają czas odzyskiwania, ale nie czynią niszczącego SQL akceptowalnym. Migawka może przywrócić całą bazę do wcześniejszego punktu, choć faktycznie trzeba odzyskać jedną usuniętą kolumnę, a odtwarzanie może usunąć prawidłowe zapisy dokonane po wykonaniu migawki. Testuj odzyskiwanie osobno i dokumentuj, kto może je uruchomić.

Gdy używam Koder.ai do aplikacji, która dotyka istniejącej bazy, pozostawiam pracę w trybie planowania, dopóki nie przejrzę wyeksportowanego kodu źródłowego i proponowanej granicy bazy. Migawki i cofanie zmian to mechanizmy odzyskiwania, a nie zgoda na pominięcie tego przeglądu. Ta sama zasada dotyczy każdego kreatora: wygoda produktu musi działać za egzekwowanymi przez bazę granicami.

Zmiany schematu muszą tolerować mieszane wersje aplikacji

Sprawdź kod przed dostępem do bazy
Wyeksportuj wygenerowany kod źródłowy i sprawdź każde zapytanie PostgreSQL względem zatwierdzonego schematu.

Migracja jest bezpieczna tylko wtedy, gdy podczas okna wydania może działać zarówno stara, jak i nowa aplikacja. Produkcja rzadko przełącza się z jednej wersji na drugą w jednej chwili. Żądania mogą trafiać do starych instancji, gdy startują nowe, zadania w kolejce mogą przenosić starsze dane wejściowe, a wycofanie może uruchomić wczorajszy kod względem dzisiejszego schematu. Kreator aplikacji, który waliduje jedynie końcowy kod względem końcowego schematu, pomija to nakładanie się wersji.

Najpierw wybieraj zmiany addytywne. Dodaj kolumnę dopuszczającą null, nową tabelę albo indeks bez usuwania starej ścieżki. Wdróż kod, który potrafi odczytać obie reprezentacje i zapisuje nową tam, gdzie to właściwe. Uzupełniaj istniejące wiersze w osobno sprawdzonym zadaniu, obserwuj błędy i opóźnienie, a potem uczyń nowe pole autorytatywnym. Usuń starą kolumnę lub ograniczenie w późniejszym wydaniu, gdy dowody pokażą, że żaden działający kod już z nich nie korzysta.

Ta sekwencja trwa dłużej niż wygenerowanie jednej instrukcji ALTER TABLE, ale izoluje awarie. Jeśli nowy kod zachowuje się nieprawidłowo przed usunięciem starej ścieżki, nadal ona istnieje. Jeśli uzupełnianie danych się opóźnia, może zostać wstrzymane bez wstrzymywania wydania aplikacji. Jeśli wdrożenie zostanie wycofane, stara aplikacja nadal rozumie bazę. Dodatkowe wydanie jest tańsze niż odkrycie podczas wycofywania, że poprzednia wersja pyta o kolumnę, którą migracja już usunęła.

Zmiany nazw wymagają szczególnej ostrożności, ponieważ PostgreSQL zmienia nazwę natychmiast. Generator może zaproponować zmianę customer_ref na customer_id, bo nowa nazwa brzmi lepiej. Stare instancje przestaną działać, gdy tylko migracja zostanie zatwierdzona. Dodaj customer_id, utrzymuj oba pola w synchronizacji w kodzie aplikacji lub przez wąsko sprawdzony trigger, przenieś odczyty, a customer_ref usuń dopiero po zniknięciu starych zapisów. Tymczasowe powielenie to widoczny dług z warunkiem usunięcia. Natychmiastowa zmiana nazwy to niewidoczne powiązanie wersji.

Wartości domyślne i ograniczenia nonnull także mogą ukrywać pracę. Przed zatwierdzeniem SET NOT NULL policz istniejące wartości null i udowodnij, że każdy aktywny zapisujący proces podaje wartość. W przypadku dużych lub obciążonych tabel sprawdź, jak dana wersja PostgreSQL waliduje ograniczenie i jakie blokady zakłada. Kreator powinien raportować te warunki wstępne, a nie wyciągać wnioski ze schematu bez reprezentatywnego ruchu.

Uzupełnianie danych nie powinno działać wewnątrz nieograniczonej transakcji schematu. Aktualizuj wiersze w odmierzonych partiach przez zatwierdzony proces roboczy, zapisuj postęp stabilnym kursorem i dbaj, by ponowienia były idempotentne. Ponowienie jest idempotentne, gdy dwukrotne zastosowanie daje zamierzony stan, a nie tylko wtedy, gdy PostgreSQL akceptuje drugie zapytanie. Dla wartości pochodnych zapisz wersję sposobu wyliczenia, jeśli późniejszy kod mógłby liczyć je inaczej.

Pakiet wydania powinien wskazywać cztery punkty zgodności:

  1. Najstarszą wersję aplikacji, która może działać przed migracją.
  2. Stan schematu akceptowany przez stare i nowe wersje.
  3. Sygnał pozwalający na wydanie usuwające stare elementy.
  4. Ścieżkę odzyskiwania, jeśli nowy kod zostanie wycofany po zmianie danych.

Generowane zapytania powinny unikać SELECT * podczas tych przejść. Dodanie kolumny może zmienić koszt skanowania, dekodowanie wyników, mapowanie pozycyjne i ekspozycję danych, nawet gdy stare SQL nadal się parsuje. Wymieniaj kwalifikowane kolumny jawnie i generuj dekodery z tej samej migawki schematu. Dzięki temu przegląd kodu pokazuje dokładnie, jakie dane przekraczają granicę bazy.

Przygotowane narzędzia migracyjne często zapisują zastosowaną wersję w tabeli, ale sam numer wersji nie dowodzi zgodności. Zapisuj skrót dokładnego artefaktu SQL, ponieważ dwa pliki o tej samej przyjaznej nazwie mogą zawierać różne polecenia. Wykonawca powinien odrzucić już zapisaną wersję z innym skrótem. Powinien też odrzucić późniejszą migrację, gdy brakuje wymaganego poprzednika.

Nie pozwalaj każdej instancji aplikacji uruchamiać migracji przy starcie. Nawet gdy narzędzie migracyjne używa blokady doradczej, uruchomienie zależy teraz od uprzywilejowanych poświadczeń i od zakończenia prac nad schematem przed upływem kontroli zdrowia. Wykonuj migrację w jednym zadaniu wydania, poczekaj na zapisany wynik, a instancje uruchomieniowe startuj z tożsamością, która nie może zmieniać schematu. Jeśli system wydawania nie umie rozdzielić tych faz, napraw go przed nadaniem aplikacji uprawnień właściciela.

Testuj ten harmonogram, a nie tylko stan końcowy: stary kod na starym schemacie, stary kod na rozszerzonym schemacie, nowy kod na rozszerzonym schemacie i wycofany kod po nowych zapisach. Czyszczenie ma później osobny test. Ta macierz wychwytuje zmiany poprawne składniowo, lecz operacyjnie niemożliwe do odwrócenia.

Udowodnij granicę negatywnymi testami

Projekt bezpieczeństwa jest niepełny, dopóki zakazane działania nie zawodzą w testach. Połącz się jako rola wykrywania i spróbuj wstawienia, utworzenia tabeli oraz SET TRANSACTION READ WRITE. Połącz się jako rola uruchomieniowa i spróbuj dostępu do nieprzyznanej tabeli, odczytu między najemcami objętego zabezpieczeniami wierszy oraz zmiany schematu. Oczekiwanym wynikiem jest błąd uprawnień PostgreSQL, a nie obietnica w logu agenta.

Uruchamiaj też testy pozytywne. Wykrywanie nadal musi odczytywać każdy dozwolony wpis katalogu. Aplikacja musi wykonywać przez pulę każde zatwierdzone działanie użytkownika. Wykonanie migracji ma działać wyłącznie przez ścieżkę zatwierdzania. Granica, która blokuje normalną pracę produktu, zachęci kogoś do zastąpienia jej poświadczeniami właściciela podczas incydentu.

Trzymaj niewielki kontrakt dostępu obok kodu źródłowego aplikacji. Powinien wymieniać bazę, dozwolone schematy, zakres wykrywania, operacje uruchomieniowe, tryb puli, politykę limitów czasu, osoby zatwierdzające migracje, metodę odcisku schematu i zakazane instrukcje. Porównuj rzeczywiste uprawnienia z tym kontraktem w ciągłych kontrolach. Dryf uprawnień PostgreSQL to dryf konfiguracji, nawet jeśli nikt nie zmienił kodu aplikacji.

Sprawdzaj ponownie po zmianach ról, nowych tabelach, odtworzeniach baz, aktualizacjach puli i zmianach hostingu. Domyślne uprawnienia mają znaczenie dla przyszłych obiektów: przyznanie SELECT ON ALL TABLES obejmuje obecne tabele, nie tabele utworzone później. Zdecyduj, czy nowe obiekty powinny pozostać niewidoczne do czasu przeglądu, czy być dodawane przez wąsko skonfigurowane domyślne uprawnienia. Wolę niewidoczność domyślnie, ponieważ jawne nadanie uprawnienia wprowadza nową tabelę do rozmowy o dostępie.

Uwzględnij odwoływanie uprawnień w planie testów. Wyłącz poświadczenia wykrywania i potwierdź, że ruch aplikacji nadal działa. Wyłącz poświadczenia uruchomieniowe i potwierdź, że narzędzie migracyjne nie zastępuje ich po cichu silniejszą tożsamością. Następnie rotuj każdy sekret przy aktywnych połączeniach i obserwuj, czy pula wycofuje stare sesje w zamierzonym czasie. Zmiana hasła nie kończy już uwierzytelnionych sesji, dlatego procedury rotacji potrzebują jawnego odświeżenia puli albo polityki kończenia sesji PostgreSQL.

Podczas tych testów sprawdzaj komunikaty błędów pod kątem przypadkowego ujawniania informacji. Błędy PostgreSQL mogą zawierać nazwy relacji, fragmenty SQL, nazwy ograniczeń i podane wartości. Wysyłaj szczegółowe błędy do ograniczonych logów serwera, klientom zwracaj stabilny publiczny błąd i nigdy nie przekazuj całego strumienia błędów produkcyjnych z powrotem do rozmowy z agentem. Kreator potrzebuje pozycji instrukcji i oczyszczonej odpowiedzi bazy, aby naprawić kod. Nie potrzebuje wartości klientów.

Ostatni test wychwytuje zaskakująco wiele niebezpiecznych integracji: całkowicie usuń poświadczenia migracyjne i uruchom zestaw testów aplikacji. Jeśli normalne uruchomienie, kontrole zdrowia, podglądy albo obsługa żądań zawodzą, własność schematu przedostała się do ścieżki uruchomieniowej. Usuń to powiązanie przed podłączeniem kreatora do produkcji. Kreator aplikacji AI może działać z bazą, której nie posiada, ale PostgreSQL musi umieć powiedzieć „nie”, gdy wygenerowany kod zapomni o ustalonych zasadach.

Często zadawane pytania

Czy kreator aplikacji AI może korzystać z mojej istniejącej bazy PostgreSQL?

Tak, jeśli kreator łączy się przez dedykowane role i odkrywa wyłącznie zatwierdzone schematy. Rozdziel wykrywanie, zapytania wykonywane przez aplikację i migracje na osobne ścieżki uprawnień, aby podłączenie narzędzia nie dawało mu własności schematu.

Czy użytkownik PostgreSQL tylko do odczytu gwarantuje, że dane się nie zmienią?

Rola mająca tylko SELECT i niebędąca właścicielem obiektów to główna kontrola. default_transaction_read_only daje dodatkową ochronę, ale nie powinno rekompensować zbyt szerokich uprawnień ani odziedziczonego członkostwa.

Czy powinienem przekazać kreatorowi hasło właściciela bazy danych?

Nie. Poświadczenia właściciela znoszą granice i pozwalają wygenerowanemu SQL zmieniać uprawnienia, tabele oraz dane. Utwórz osobne poświadczenia do wykrywania, działania aplikacji i kontrolowanego zadania migracyjnego.

Jak kreator aplikacji może bezpiecznie poznać mój schemat?

Pozwól mu odpytywać zatwierdzone widoki information_schema i pg_catalog przez rolę o ograniczonym zakresie, a następnie zapisz migawkę z odciskiem schematu. Unikaj próbkowania wierszy, chyba że przygotowano do tego zamaskowany widok.

Co się stanie, gdy AI wymyśli kolumnę PostgreSQL?

Generowanie powinno zakończyć się błędem względem typowanej migawki schematu przed wdrożeniem. Zgłoś nieznaną nazwę i podobne prawidłowe nazwy, lecz decyzję, czy potrzebna jest poprawka kodu, świeże wykrywanie czy zatwierdzona migracja, pozostaw człowiekowi.

Czy aplikacja może łączyć się bezpośrednio z przeglądarki lub aplikacji mobilnej?

Nie powinna łączyć się z PostgreSQL bezpośrednio, ponieważ te klienty nie potrafią zachować hasła do bazy w tajemnicy. Umieść dostęp do bazy w procesie serwerowym, a przeglądarka lub aplikacja mobilna powinna wywoływać jego API.

Czy potrzebuję puli połączeń dla generowanych aplikacji?

Zwykle tak, lecz skonfiguruj pulę świadomie. Ogranicz łączną liczbę sesji, wybierz tryb sesji lub transakcji, resetuj zmienny stan i testuj wygenerowany kod przez tę samą pulę, która działa na produkcji.

Czy migracje PostgreSQL można bezpiecznie cofnąć?

Część zmian w katalogu można czysto odwrócić w transakcji, ale utraty danych i skutków zewnętrznych już nie. Osobno przejrzyj SQL do wykonania i SQL odwracający, a migawki traktuj jako narzędzia odzyskiwania, a nie dowód bezpieczeństwa zmiany.

Jak powstrzymać kreator przed zmianą niezatwierdzonych tabel?

Stosuj listy dozwolonych schematów, kwalifikowane nazwy, wąskie uprawnienia, politykę SQL opartą na parsowaniu oraz negatywne testy uprawnień. Rola PostgreSQL musi odrzucić operację, nawet gdy model lub sprawdzanie polityki popełni błąd.

Jak często kreator aplikacji powinien ponownie wykrywać schemat?

Wykrywaj schemat ponownie, gdy zapisany odcisk się zmieni, oraz po migracjach, odtworzeniach i zmianach środowiska. Nie odświeżaj go po cichu podczas wydania, pokaż różnicę i ponownie uruchom walidację względem nowej migawki.

Related posts