Pipeline jako niewidoczna infrastruktura krytyczna
Większość organizacji technologicznych ma świadomość że aplikacja produkcyjna wymaga zabezpieczenia. Firewalle, WAF, monitoring anomalii, testy penetracyjne aplikacji — to tematy które trafiają na agendy zarządów i budżety bezpieczeństwa.
Pipeline CI/CD — system który buduje, testuje i deployuje tę aplikację — rzadko pojawia się w tym samym kontekście. A powinien. Pipeline ma bowiem dostęp do wszystkiego: kluczy API, tokenów chmury, sekretów baz danych, certyfikatów i uprawnień do wdrożeń na produkcję. Jest infrastrukturą krytyczną, traktowaną jak narzędzie pomocnicze.
Analogia jest prosta: to tak, jakby firma inwestowała w pancerne drzwi do biura, ale zostawiała klucze do wszystkich sejfów w niezamykanej szafce na zapleczu. Pipeline jest tą szafką.
Skąd wynika ta luka?
Pipeline CI/CD jest postrzegany jako wewnętrzne narzędzie deweloperów. W przeciwieństwie do aplikacji publicznych, nie jest “widoczny z internetu” — więc intuicyjnie wydaje się mniej ryzykowny. To błędne założenie z kilku powodów.
Po pierwsze, pipeline jest dostępny przez interfejsy webowe (GitHub, GitLab, Azure DevOps), które są dostępne publicznie. Po drugie, każde repozytorium kodu które ma dostęp do pipeline’u jest potencjalnym wektorem ataku. Po trzecie, zewnętrzne zależności — biblioteki, akcje, obrazy bazowe — są wykonywane w kontekście pipeline’u z jego pełnymi uprawnieniami.
Badania CNCF z 2024 roku pokazują, że ponad 60% incydentów bezpieczeństwa w organizacjach natywnych chmurowo ma swój początek w przejęciu dostępu do CI/CD lub tokenów z nim powiązanych — nie w podatności samej aplikacji. Raport GitGuardian z 2024 wskazuje, że na GitHubie wykryto ponad 12,8 miliona nowych wycieków sekretów w ciągu jednego roku — większość z pipeline’ów i plików konfiguracyjnych.
To nie jest problem teoretyczny. W 2024 roku firma Sisense — dostawca BI używany przez tysiące firm — padła ofiarą ataku, który rozpoczął się od przejęcia tokenu z repozytorium kodu. Atak na CodeCov w 2021 polegał na podmianie skryptu w pipeline, który eksfiltrował zmienne środowiskowe (w tym sekrety AWS) z pipeline’ów klientów. Podobny wektor wykorzystano w ataku na SolarWinds.
Anatomia ataku na pipeline — jak to wygląda w praktyce
Typowy atak na pipeline CI/CD nie wygląda jak scena z filmu. Nie ma włamania do serwera. Atakujący wykorzystuje to co już istnieje — nadmierne uprawnienia, statyczne tokeny, niezweryfikowane zależności.
Scenariusz 1: Przejęcie tokenu. Deweloper commituje plik .env lub token API do repozytorium. Nawet jeśli commit zostanie usunięty, token jest nadal widoczny w historii Git. Atakujący używa narzędzi do skanowania historii (TruffleHog, GitLeaks) i przejmuje token z pełnymi uprawnieniami do chmury. Czas od wycieku do wykorzystania: średnio 4 minuty wg raportu GitGuardian.
Scenariusz 2: Atak na supply chain. Pipeline używa zewnętrznej akcji GitHub Actions (np. actions/checkout@v3) pinowanej do tagu, nie do SHA. Autor akcji (lub ktoś kto przejął jego konto) podmienia kod pod tym samym tagiem. Pipeline wykonuje podmieniony kod z pełnymi uprawnieniami — w tym dostępem do GITHUB_TOKEN i wszystkich sekretów.
Scenariusz 3: Privilege escalation przez PR. W repozytoriach z workflow pull_request_target atakujący tworzy pull request z modyfikacją workflow. Jeśli workflow nie jest odpowiednio zabezpieczony, PR może uruchomić pipeline z uprawnieniami do zapisu w repozytorium docelowym — w tym do sekretów.
Każdy z tych scenariuszy jest eliminowalny. OIDC zastępuje statyczne tokeny tymczasowymi. Pinning SHA uniemożliwia podmianę akcji. Odpowiednia konfiguracja uprawnień GITHUB_TOKEN zamyka privilege escalation. Ale żadna z tych kontroli nie istnieje domyślnie — trzeba ją świadomie wdrożyć. To jest właśnie hardening.
Czym jest hardening w tym kontekście?
Hardening to systematyczne ograniczanie powierzchni ataku przez eliminację zbędnych uprawnień, wzmocnienie konfiguracji i wprowadzenie kontroli wykrywających anomalie. Nie jest to jednorazowe działanie — to stan ciągłej higieny bezpieczeństwa.
Hardening CI/CD różni się od hardeningu serwerów czy aplikacji. W przypadku pipeline’u powierzchnia ataku to: konfiguracja YAML, uprawnienia użytkowników i service accounts, mechanizmy przechowywania sekretów, zewnętrzne zależności, mechanizmy wyzwalania workflow, i konfiguracja artefaktów wyjściowych.
Kluczowa zasada: hardening nie dodaje nowych narzędzi do pipeline’u — on ogranicza to co pipeline może robić. Im mniej uprawnień, im mniej sekretów, im mniej niezweryfikowanych zależności — tym mniejsza powierzchnia ataku.
Cztery filary hardeningu CI/CD
W kontekście pipeline’u hardening dotyczy czterech wzajemnie powiązanych obszarów:
1. Tożsamość i dostęp. Kto i co może uruchamiać pipeline i modyfikować jego konfigurację. Obejmuje: ograniczenie uprawnień GITHUB_TOKEN do minimum (read-only jako default), wymuszenie branch protection rules z wymaganymi review, wdrożenie OIDC zamiast statycznych tokenów do autoryzacji wobec chmury (AWS, Azure, GCP), eliminacja kont serwisowych z nadmiernymi uprawnieniami.
2. Zarządzanie sekretami. Jak poświadczenia są przechowywane, przekazywane i rotowane. Obejmuje: przeniesienie sekretów z repozytorium do dedykowanego vault (HashiCorp Vault, AWS Secrets Manager), automatyczna rotacja tokenów, skanowanie historii Git pod kątem wyciekłych sekretów (TruffleHog), blokowanie commitów zawierających sekrety (pre-commit hooks).
3. Środowisko wykonania. Izolacja, uprawnienia sieciowe, zasoby. Obejmuje: runner isolation (ephemeral runners zamiast persistent), ograniczenie dostępu sieciowego pipeline’u, pinning zewnętrznych akcji i obrazów do SHA (nie tagów), minimalizacja uprawnień kontenerów budujących.
4. Integralność kodu i artefaktów. Weryfikacja że to co deployujesz jest tym co zaakceptował reviewer. Obejmuje: podpisywanie artefaktów (Cosign/Sigstore), generowanie SBOM (CycloneDX), weryfikacja provenance (SLSA framework), automatyczne skanowanie SAST/SCA (CodeQL, Trivy, Checkov).
Te cztery filary odpowiadają na cztery fundamentalne pytania: kto ma dostęp (tożsamość), czym się autoryzuje (sekrety), gdzie to się wykonuje (środowisko), i co z tego wychodzi (integralność).
Dlaczego organizacje nie robią tego same
Najczęstszy argument to “zajmiemy się tym gdy urośniemy”. Problem w tym, że incydenty bezpieczeństwa nie respektują roadmap produktu. Firmy padają ofiarą ataków na pipeline właśnie dlatego, że są w fazie wzrostu — mają wartościowe dane klientów i kod, ale jeszcze nie procesy bezpieczeństwa odpowiadające temu poziomowi ryzyka.
Drugi argument to brak kompetencji. Hardening CI/CD wymaga połączenia wiedzy z zakresu bezpieczeństwa, DevOps i konkretnych platform (GitHub Actions, GitLab CI, Azure DevOps). Taka kombinacja rzadko istnieje wewnętrznie w organizacjach skoncentrowanych na wytwarzaniu produktu. Security team (jeśli istnieje) zna zagrożenia, ale nie zna specyfiki GitHub Actions. DevOps team zna platformę, ale nie zna technik hardeningu. Luka kompetencyjna jest realna.
Trzeci argument to obawa przed spowalnianiem pracy. Źle wdrożone kontrole bezpieczeństwa rzeczywiście mogą blokować pracę zespołu. Właściwie zaprojektowane — działają w tle, niewidocznie dla większości deweloperów przez większość czasu. OIDC nie wymaga od dewelopera żadnej dodatkowej akcji — token tymczasowy jest generowany automatycznie. SBOM generuje się jako krok w pipeline. Skanowanie sekretów blokuje commit tylko gdy faktycznie zawiera sekret.
Co powinno być punktem wyjścia?
Przed jakimkolwiek działaniem naprawczym konieczna jest diagnostyka stanu faktycznego. Bez wiedzy o tym co istnieje — jakie konta mają dostęp, jakie sekrety i o jakim wieku są przechowywane, jakie zewnętrzne zależności są wykonywane w pipeline — priorytetyzacja działań jest niemożliwa.
Diagnostyka ujawnia też zwykle zaskakujące rzeczy: tokeny z datą utworzenia sprzed 3 lat bez rotacji, konta byłych pracowników z dostępem do pipeline’u, zewnętrzne akcje pinowane do tagów (które mogą być nadpisane), sekrety wyciekające do logów przez dynamiczne podstawianie zmiennych.
Dobrze przeprowadzona diagnostyka kończy się raportem z priorytetami: co jest krytyczne (narażenie na natychmiastowe przejęcie), co jest wysokie (narażenie na atak supply chain), co jest średnie (brak best practices, potencjalne problemy compliance). Na tej podstawie można zaplanować sprint hardeningu — nie zgadując co naprawić najpierw, ale opierając się na rzeczywistym obrazie ryzyka. Więcej o tym jak wygląda taki raport — w opisie naszej usługi Evidence Pack.
Checklist — minimum viable hardening
Jeśli chcesz ocenić stan swojego pipeline’u, zacznij od tych pytań:
Tożsamość i dostęp: Czy GITHUB_TOKEN ma uprawnienia read-only jako default? Czy branch protection wymaga minimum 1 review przed merge? Czy pipeline do chmury używa OIDC zamiast statycznych kluczy? Czy są konta byłych pracowników z aktywnym dostępem?
Sekrety: Czy w historii Git nie ma wyciekłych sekretów? Czy tokeny mają datę rotacji i są rotowane? Czy sekrety są przechowywane w dedykowanym vault, nie w ustawieniach repozytorium?
Środowisko: Czy zewnętrzne akcje GitHub Actions są pinowane do SHA (nie tagów)? Czy runnery są ephemeral (niszczone po każdym buildzie)? Czy pipeline ma ograniczony dostęp sieciowy?
Integralność: Czy artefakty są podpisywane kryptograficznie? Czy SBOM jest generowany automatycznie? Czy istnieje mechanizm weryfikacji provenance?
Jeśli odpowiedź na więcej niż 3 z tych pytań brzmi “nie” lub “nie wiem” — Twój pipeline wymaga hardeningu. To nie jest kwestia ambicji — to kwestia ryzyka operacyjnego i regulacyjnego.