Przejdź do głównej zawartości

Najlepsze praktyki prywatności i bezpieczeństwa

Jesteś trzy linijki w prośbie do agenta, by „zdebugował, czemu produkcyjna baza wciąż przekracza limit czasu”, a już wkleiłeś pełny DATABASE_URL — host, użytkownika i hasło — do czatu. Albo znajdujesz społecznościowy serwer MCP, który obiecuje dostęp do Postgresa jednym kliknięciem, i właśnie masz wycelować go w produkcyjną bazę swoimi poświadczeniami administratora. Oba ruchy w danej chwili wydają się nieszkodliwe. Oba mogą wyciec klucze do twojego biznesu.

Asystenci AI są bezpieczni przy własnościowym kodzie, o ile skonfigurujesz ich świadomie: włącz właściwe ustawienie przechowywania danych dla swojego narzędzia, nigdy nie dopuść, by sekret dotarł do modelu, i nadaj każdemu serwerowi MCP najmniejsze uprawnienia, jakich potrzebuje.

  • Gdzie w każdym narzędziu znajduje się ustawienie prywatności/przechowywania danych i co tak naprawdę gwarantuje
  • Prompt skanujący sekrety do uruchomienia na każdym diffie przed commitem
  • Prompt do przeglądu bezpieczeństwa kodu wygenerowanego przez AI (XSS, CSRF, SQLi, błędna autoryzacja)
  • Wzorzec minimalnych uprawnień dla serwerów MCP do baz danych, wraz z dokładnym GRANT

Znajdź ustawienie przechowywania danych w swoim narzędziu

Dział zatytułowany „Znajdź ustawienie przechowywania danych w swoim narzędziu”

„Tryb prywatności” nie jest uniwersalny — każdy dostawca ma własną kontrolę i własną gwarancję. Dowiedz się, która dotyczy ciebie, zanim wkleisz choć jedną własnościową linijkę.

Cursor ma jawny przełącznik Privacy Mode (Cursor Settings). Gdy jest włączony, twój kod nie jest przechowywany przez Cursora i nie jest używany do trenowania — gwarancja zerowego przechowywania danych (ZDR). Privacy Mode jest włączony domyślnie dla zespołów Enterprise, a administratorzy mogą wymusić go w całym zespole, tak by pojedyncze osoby nie mogły go wyłączyć. Indeksowanie wciąż wylicza embeddingi, ale w trybie Privacy Mode kod w postaci jawnej nie jest zatrzymywany po stronie serwera po zakończeniu żądania.

Zasada jest niezmienna względem zwykłej higieny bezpieczeństwa, ale powierzchnia jest szersza: klucze API, tokeny, hasła i stringi połączenia z bazą nigdy nie mogą pojawić się w promptcie. Odwołuj się do process.env.DATABASE_URL, a nie do dosłownej wartości. Najpewniejszym egzekwowaniem jest automatyzacja, nie silna wola — wepnij skanowanie sekretów w hook pre-commit (np. gitleaks), żeby wyciekłe poświadczenie zostało złapane, zanim w ogóle trafi do commita czy zostanie wklejone.

Uczyń samego agenta częścią kontroli:

Traktuj każdy blok, który napisze AI, jak pull request od zupełnie nowego współpracownika: może być funkcjonalnie poprawny, a i tak wdrożyć błąd typu injection lub brakujące sprawdzenie autoryzacji. Nie tylko przelatuj diff wzrokiem — zrób drugie przejście z modelem w roli specjalisty od bezpieczeństwa, a potem sam zweryfikuj jego ustalenia.

To dyscyplina nadzoru ludzkiego, która oddziela pracę produkcyjną od dem — zobacz Człowiek w pętli po pełny przepływ przeglądu.

Model Context Protocol pozwala twojemu agentowi łączyć się z zewnętrznymi narzędziami — bazą danych, GitHubem, przeglądarką. Każdy serwer MCP to wykonywalne oprogramowanie z dowolnymi uprawnieniami, jakie mu nadasz, więc zbyt uprzywilejowany lub niesprawdzony serwer to realna powierzchnia ataku. Dwie zasady pokrywają większość ryzyka.

Po pierwsze, sprawdź serwer, zanim go zainstalujesz. Preferuj oficjalne, ograniczone zakresem pakiety (np. @modelcontextprotocol/server-github, @modelcontextprotocol/server-postgres) nad nieznanym społecznościowym forkiem. Każ agentowi podsumować, co serwer faktycznie robi, zanim go podłączysz:

Po drugie, podłącz go z poświadczeniami o minimalnych uprawnieniach. W przypadku serwera MCP do Postgresa nigdy nie dawaj mu roli aplikacji ani administratora. Stwórz rolę tylko do odczytu, ograniczoną dokładnie do tego, czego agent potrzebuje:

CREATE ROLE ai_readonly LOGIN PASSWORD 'rotate-me';
GRANT CONNECT ON DATABASE app TO ai_readonly;
GRANT USAGE ON SCHEMA public TO ai_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO ai_readonly;
-- new tables inherit read-only access automatically
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO ai_readonly;

Następnie skieruj string połączenia serwera MCP na ai_readonly — identyczna konfiguracja w Cursorze, Claude Code i Codeksie, bo wszystkie trzy czytają ten sam blok mcpServers. Teraz halucynowany DROP TABLE zostaje odrzucony przez bazę danych, a nie przez nadzieję. Zobacz MCP do baz danych po pełną konfigurację oraz Bezpieczeństwo MCP po model zagrożeń.

Czytaj diff, nie podsumowanie

Przed zatwierdzeniem edycji pliku czytaj rzeczywisty diff, a nie jednolinijkowy opis agenta. Podsumowanie to to, co agent zamierzał; diff to to, co faktycznie zapisze.

Bramkuj polecenia destrukcyjne

Nigdy nie zatwierdzaj automatycznie poleceń terminala, które usuwają, wdrażają lub mutują dane. Uruchamiaj agentów w trybie ograniczonym (zatwierdzanie poszczególnych akcji w Cursorze, prompty uprawnień Claude Code, --ask-for-approval w Codeksie), tak by ryzykowne działania wymagały wyraźnego „tak”.

  • Zakładałeś tryb prywatności, ale byłeś na planie osobistym. Kolega z zespołu zalogował się na osobiste konto Cursora/ChatGPT na maszynie służbowej, omijając wymuszone w zespole ZDR. Naprawa: wymuś tryb prywatności na poziomie zespołu i ogranicz logowania do kont firmowych (Allowed Team IDs w Cursorze; SSO w ChatGPT Enterprise).
  • Sekret wyciekł przez logi serwera MCP. Model nigdy nie zobaczył poświadczenia, ale serwer wypisał pełny string połączenia na stderr przy błędzie połączenia. Naprawa: ogranicz zakres poświadczeń serwera (rola tylko do odczytu powyżej) i nigdy nie umieszczaj sekretów w args MCP — ładuj je ze środowiska.
  • Zbyt uprzywilejowane poświadczenia do bazy. Agent uruchomił eksploracyjny UPDATE, bo rola nadana serwerowi MCP mogła zapisywać. Naprawa: rola tylko do odczytu z GRANT powyżej; twórz osobną, świadomie wywoływaną rolę do zapisu dopiero wtedy, gdy faktycznie potrzebujesz mutacji.
  • Wrażliwe pliki trafiły do indeksu. Plik .env lub plik z kluczem został zaembeddowany, bo nie został zignorowany. Naprawa: dodaj go do .cursorignore (Cursor) i .gitignore; zrotuj każde poświadczenie, które zostało zaindeksowane.