Zarządzanie sekretami w projektach IT
Zarządzanie sekretami w IT: najczęstsze błędy, Vault, rotacja tokenów, skanowanie repozytoriów i procedura reakcji na wyciek klucza API.
Większość wycieków danych nie zaczyna się od zaawansowanego ataku. Zaczyna się od pliku .env wypchniętego na GitHuba, klucza API w historii commitów albo hasła zakodowanego na stałe w skrypcie, który “tylko na chwilę” trafił do repozytorium. Ta “chwila” często trwa miesiącami.
Sekrety (tokeny, klucze API, hasła, certyfikaty, dane dostępowe do baz danych) to jedna z najczęściej pomijanych klas ryzyka w projektach IT. Nie dlatego, że ludzie nie wiedzą, że to problem, tylko dlatego, że pod presją czasu, przy wdrożeniu na produkcję o trzeciej w nocy albo podczas szybkiego prototypowania, te zasady idą na bok.
Jak wygląda problem w praktyce
GitHub automatycznie i bezpłatnie skanuje publiczne repozytoria pod kątem wykrytych sekretów i wysyła powiadomienia do właścicieli kont: tylko w pierwszych ośmiu tygodniach 2024 roku wykrył w ten sposób ponad milion ujawnionych sekretów [1]. Repozytoria prywatne i wewnętrzne w organizacjach też mogą korzystać z tej ochrony (GitHub Secret Protection), ale wymaga to jej aktywacji i licencji. Problemem nie jest więc to, że prywatnych repozytoriów “się nie skanuje”, tylko że skanowanie trzeba świadomie włączyć.
Narzędzie takie jak truffleHog albo gitleaks potrafi w ciągu kilku minut przeszukać całą historię commitów repozytorium i wyciągnąć z niej tokeny, hasła czy ciągi znaków przypominające klucze — to dokładnie ten mechanizm wykorzystuje git-scanner, narzędzie, które zbudowałem do cyklicznego skanowania repozytoriów pod kątem takich wycieków. Atakujący robi dokładnie to samo. Co gorsza, usunięcie pliku z repozytorium nie usuwa go z historii: sekret wciąż tam jest, dostępny po prostym git log.
Osobna kategoria to repozytoria firm przejętych przez inne podmioty albo porzucone projekty open source. Kod żyje długo po tym, jak nikt już o nim nie myśli. Sprawdzenie takich porzuconych śladów to jeden z elementów szerszego rekonesansu OSINT infrastruktury, nie tylko samego repozytorium.
Czym jest sekret i gdzie się ukrywa
Sekret to każda wartość, która daje dostęp do zasobu i nie powinna być znana nikomu poza uprawnionym systemem lub osobą. W praktyce to:
- klucze API do zewnętrznych serwisów (AWS, Stripe, SendGrid, OpenAI),
- hasła do baz danych,
- tokeny JWT i klucze do ich podpisywania,
- prywatne klucze SSH i prywatne klucze certyfikatów TLS,
- dane dostępowe do wewnętrznych systemów,
- zmienne środowiskowe z danymi uwierzytelniającymi.
Sam publiczny certyfikat TLS nie jest sekretem, bo z założenia jest jawny i widoczny dla każdego, kto łączy się z serwerem. Sekretem jest dopasowany do niego klucz prywatny.
Sekrety pojawiają się w miejscach, w których nikt ich nie szuka: w logach aplikacji, w metadanych obrazów Dockera, w plikach konfiguracyjnych commitowanych razem z kodem, w historii shella na serwerze, w eksportach bazy danych zostawionych na dysku. Dlatego przegląd sekretów często warto połączyć z audytem i hardeningiem serwerów Linux, szczególnie gdy dostęp administracyjny, deployment i backupy nie były dawno porządkowane.
Najczęstsze błędy
Plik .env w repozytorium. Klasyk. Plik tworzony lokalnie do konfiguracji środowiska deweloperskiego, który przez przypadek lub z braku odpowiedniego .gitignore trafia do repozytorium. Czasem prywatnego, czasem nie.
Hardcoding w kodzie źródłowym. Klucz API wpisany bezpośrednio w kodzie, bo “to tylko do testów”. Testy się kończą, kod zostaje.
Sekrety w zmiennych środowiskowych bez żadnej kontroli. Samo używanie zmiennych środowiskowych to dobra praktyka, ale jeśli nie ma żadnej kontroli nad tym, kto i skąd je czyta, problem pozostaje, tylko mniej widoczny.
Brak rotacji. Token wygenerowany dwa lata temu, używany nieprzerwanie, nigdy nieodwołany. Jeśli gdzieś wyciekł, atakujący ma cierpliwość.
Zbyt szerokie uprawnienia. Klucz do S3 z pełnym dostępem do wszystkich bucketów, bo “tak było łatwiej skonfigurować”. W przypadku wycieku oznacza to dostęp do wszystkiego, nie tylko do tego, czego potrzebuje aplikacja.
Jak to robić poprawnie
Vault i dedykowane systemy do zarządzania sekretami. HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Secret Manager to narzędzia zaprojektowane właśnie do tego. Ich rola to centralizacja: kontrola dostępu, audyt i cykl życia sekretu w jednym miejscu, zamiast rozproszonych po kodzie i plikach konfiguracyjnych. Sposób dostarczenia sekretu do aplikacji zależy od konkretnego wdrożenia, może to być zapytanie do API w momencie startu, plik, sidecar, zamontowany wolumen, a czasem również zmienna środowiskowa wstrzyknięta z zewnętrznego źródła. Nie ma tu jednego uniwersalnego mechanizmu, ważne jest to, że sekret nie leży na stałe zapisany w kodzie ani w pliku konfiguracyjnym w repozytorium.
Pełny Vault bywa nadmiarowy dla małego zespołu albo freelancera obsługującego kilka projektów. W takiej skali sensowną alternatywą są lżejsze narzędzia, na przykład Doppler, Infisical albo mechanizmy do zarządzania sekretami wbudowane w menedżery haseł zespołowych, takie jak 1Password czy Bitwarden. Kluczowa zasada zostaje ta sama: sekret trzymany w jednym kontrolowanym miejscu, nie rozproszony po plikach .env na dyskach poszczególnych osób.
Zasada minimalnych uprawnień. Klucz API dla mikroserwisu odpowiedzialnego za wysyłkę e-maili powinien mieć dostęp wyłącznie do wysyłki e-maili, nie do historii płatności, nie do bazy użytkowników, nie do niczego innego. To ogranicza zasięg szkód w przypadku wycieku.
Rotacja sekretów. Sekrety powinny mieć określony czas życia i być wymieniane regularnie, a niektóre systemy robią to automatycznie. SOC 2 i ISO 27001 nie narzucają wprost sztywnej reguły w stylu “każdy sekret co X dni”, wymagają za to odpowiednich mechanizmów kontroli dostępu i zarządzania poświadczeniami, a okresowa rotacja bywa jednym ze sposobów spełnienia tego wymogu w ramach polityki organizacji. Coraz częstszym, nowocześniejszym kierunkiem jest zresztą zastępowanie długowiecznych sekretów krótkotrwałymi poświadczeniami i tożsamością nadawaną workloadowi zamiast bezrefleksyjnej rotacji tych samych statycznych kluczy w kółko.
Skanowanie przed wdrożeniem. gitleaks, truffleHog, detect-secrets to narzędzia, które można włączyć jako pre-commit hook albo krok w CI/CD. Sekret wykryty przed commitem nie trafia do historii.
Oddzielne sekrety dla każdego środowiska. Klucz do bazy deweloperskiej to nie ten sam klucz co do produkcji. Brzmi oczywiście, ale w praktyce nagminnie się to miesza.
Sekrety w obrazach Docker. Przekazanie klucza jako ENV albo ARG w Dockerfile zapisuje go na stałe w warstwie obrazu, widoczną nawet po jego usunięciu w kolejnym kroku budowania, bo docker history i eksport warstw wciąż go pokażą. Sekret potrzebny tylko podczas budowania powinien trafić przez --secret w BuildKit, a sekret potrzebny w działającym kontenerze przez zmienne środowiskowe albo zamontowany plik wstrzyknięty w czasie uruchomienia, nie zapisany w samym obrazie.
Co zrobić, gdy sekret już wyciekł
Pierwsza reakcja ma znaczenie. Jeśli klucz trafił do publicznego repozytorium, należy założyć, że został już przechwycony, bo boty skanujące GitHuba działają w czasie niemal rzeczywistym.
Kolejność działań:
- Odwołaj sekret natychmiast.
- Wygeneruj nowy.
- Zaktualizuj wszystkie miejsca, gdzie był używany.
- Przejrzyj logi pod kątem nieautoryzowanych operacji.
- Wyczyść historię repozytorium narzędziami typu
git filter-repo(niegit filter-branch, który jest przestarzały). - Jeśli wymagają tego przepisy lub umowy, poinformuj odpowiednie osoby.
Samo usunięcie pliku committem “ups, usuwam klucze” nie wystarczy, a czyszczenie historii repozytorium jest tu czynnością drugorzędną wobec odwołania sekretu. Sekret raz ujawniony trzeba traktować jako bezpowrotnie skompromitowany niezależnie od tego, czy później zniknie z historii Git, bo nie ma pewności, kto zdążył go skopiować, zanim historia została wyczyszczona.
Higiena, nie dziedzina specjalistyczna
Podobna dyscyplina dotyczy zresztą n8n i innych narzędzi do automatyzacji — poświadczenia w workflow wymagają tej samej ostrożności co sekrety w kodzie. Zarządzanie sekretami to nie zaawansowana dziedzina bezpieczeństwa zarezerwowana dla dużych organizacji, tylko podstawa higieny każdego projektu IT, niezależnie od tego, czy chodzi o startup z trzema mikroserwisami, czy o aplikację korporacyjną. Za większością takich incydentów stoi nie wyrafinowany atak, lecz pośpiech, brak nawyków i założenie, że “przecież to prywatne repozytorium”. Atakujący wiedzą o tym dokładnie tyle samo co Ty i liczą na to, że o tym zapomnisz.