Dlaczego DevSecOps ma sens nawet w małych projektach
DevSecOps w wersji dla solo‑deva i małego zespołu
DevSecOps w dużym skrócie oznacza, że bezpieczeństwo jest częścią tego samego przepływu pracy, co development i operacje – zamiast osobnego „działu bezpieczeństwa”, który blokuje releasy. W małych projektach nie ma osobnych działów, ale problemy bezpieczeństwa są dokładnie takie same jak w korporacjach: wycieki sekretów, dziurawe biblioteki, błędne konfiguracje serwera czy chmury.
Różnica polega na tym, że w małym projekcie nikt nie ma czasu siedzieć pół dnia w panelu skanera i analizować raportów. Dlatego sensowny DevSecOps dla małego projektu to przede wszystkim lekka automatyzacja: kilka narzędzi, które podpinają się pod Git/CI, działają same i odzywają się tylko wtedy, kiedy naprawdę warto przerwać pracę.
Dobrze skonfigurowany zestaw darmowych narzędzi DevSecOps jest rozszerzeniem unit testów i lintów – ma pracować w tle, nie wymuszać wielkich zmian procesu, nie potrzebować osobnego „security engineer”. Przy małym zespole każde narzędzie, które wymaga ręcznego klikania w UI po każdym pushu, będzie martwe po tygodniu.
Mit: DevSecOps jest tylko dla wielkich organizacji
Popularna rada brzmi: „Zacznij od funkcjonalności, bezpieczeństwem zajmiesz się, kiedy projekt urośnie”. W praktyce to działa odwrotnie – im większy system, tym droższe jest łatanie dziur i przepinanie pipeline’ów. Minimalne elementy DevSecOps dużo łatwiej wdrożyć na początku, kiedy repo jest małe, a pipeline CI/CD prosty.
DevSecOps w wydaniu korporacyjnym to wielkie platformy, mnogość dashboardów, compliance i polityki. W małym projekcie taki model się po prostu nie utrzyma. Dla zespołów 1–5 osobowych sens ma raczej:
- statyczna analiza kodu zintegrowana z Git lub CI,
- automatyczne skanowanie zależności i generowanie PR-ów z aktualizacjami,
- prosty skaner obrazów Docker, jeśli używany jest konteneryzowany deployment,
- monitorowanie sekretów i podstawowe narzędzia do DAST uruchamiane cyklicznie.
Czyli DevSecOps „po cichu” – bez całego ceremoniału znanego z enterprise. Paradoksalnie, w małych projektach dużo łatwiej wdrożyć sensowne praktyki, bo nie ma politycznych konfliktów i wieloletniego długu procesowego.
Co się realnie psuje w małych projektach
W małych repozytoriach rzadko występują zaawansowane ataki łańcuchowe. Znacznie częstsze są proste, bolesne błędy:
- Wycieki sekretów – klucze API, tokeny, hasła do baz danych w commitach, często „na chwilę” wklejone do kodu i zapomniane.
- Dziurawe zależności – frameworki i biblioteki, które mają znane podatności, ale nikt ich nie aktualizuje, bo „działa, to nie ruszaj”.
- Błędna konfiguracja – otwarte porty, brak HTTPS, publicznie dostępne panele administracyjne, zbyt szerokie uprawnienia w Docker/Kubernetes/chmurze.
- Brak widoczności – brak SBOM, brak świadomości, jakie komponenty w ogóle są w produkcji.
Większość tych problemów da się znacząco ograniczyć darmowymi narzędziami, o ile zostaną naprawdę wpięte w przepływ pracy. Manualne, „od święta” skanowanie rzadko daje trwały efekt – po miesiącu nikt już nie pamięta, jakie ostrzeżenia były ważne.
Minimalny cel: bezpieczeństwo, które nie przeszkadza
Najczęstsze nieporozumienie wokół DevSecOps w małych projektach dotyczy poziomu ambicji. Zbyt agresywny zestaw narzędzi blokujących każdy build z powodu drobnych ostrzeżeń zabije adopcję. Minimalny realistyczny cel to:
- Automatyczne ostrzeganie przy pull requestach o nowych podatnościach w kodzie lub zależnościach.
- Blokada tylko w przypadku poważnych problemów (np. krytyczne CVE w obrazie produkcyjnym, oczywisty SQL injection, wyciek sekretu).
- Raporty w tym samym miejscu, co wyniki testów – w CI, w komentarzach do PR, bez dodatkowych paneli do logowania.
Bezpieczeństwo w takim modelu jest „cichym strażnikiem”: w tle skanuje, komentuje w miejscach, gdzie developer i tak patrzy, i nie zmusza do otwierania osobnych narzędzi. To właśnie ten poziom automatyzacji daje największy zwrot z inwestycji przy minimalnym nakładzie pracy.
Kryteria porównania darmowych narzędzi DevSecOps dla małych zespołów
Koszt wdrożenia, a nie tylko cena licencji
Darmowe narzędzie DevSecOps to nie tylko „zero na fakturze”. Realny koszt to:
- Czas wdrożenia – ile godzin zajmuje pierwsza integracja z CI i sensowne odfiltrowanie szumu.
- Czas utrzymania – update’y, poprawki customowych reguł, pilnowanie nowych wersji.
- Obciążenie developera – jak często musi reagować na fałszywe alarmy i ręcznie oznaczać je jako „ignore”.
Przykład kontrariański: często polecany SonarQube Community jest świetny jakościowo, ale postawienie własnego serwera, integracja z repo i utrzymanie mogą być za ciężkie dla solo‑deva. Dla małego projektu lepszy bywa Semgrep odpalany w GitHub Actions – mniej rozbudowany, ale lekki i prosty w integracji.
„Gadatliwość” narzędzia i fałszywe alarmy
Narzedzia SAST/DAST mają tendencję do generowania długich raportów. W dużej organizacji tym zajmuje się osobny zespół. W małym projekcie zbyt „gadatliwe” narzędzie szybko ląduje w koszu. Dlatego ważne kryterium:
- Domyślna ilość false positive – czy out‑of‑the‑box raport jest w miarę znośny.
- Możliwość łatwego wyciszenia reguł – na poziomie pliku konfiguracyjnego, bez klikania po UI.
- Powiązanie wyników z konkretnymi commitami/PR – aby komentarze dotyczące bezpieczeństwa były przy konkretnych zmianach, a nie w osobnym raporcie.
Typowa pułapka to włączenie wszystkiego, co oferuje dane narzędzie, „żeby było bezpieczniej”. Efekt: zalew ostrzeżeń o niskim priorytecie, ignorowanie całości, łącznie z tymi naprawdę istotnymi. W małym projekcie lepiej zacząć od wąskiego, ale dobrze dopracowanego zestawu reguł i stopniowo go rozszerzać.
Developer‑first vs security‑first – co jest strawne na co dzień
Narzędzia „security‑first” są często projektowane z myślą o specjalistach bezpieczeństwa. Interfejsy i raporty są bogate w szczegóły, ale mogą być trudne do przełożenia na konkretne zmiany w kodzie. Narzędzia „developer‑first” stawiają na integrację z IDE, prosty output w CI i łatwość dodawania wyjątków.
Dla małego zespołu praktycznie zawsze lepiej zacząć od narzędzi bliskich developerom:
- Semgrep – reguły w YAML, integracja z GitHub/GitLab, proste outputy.
- ESLint z pluginami security – dla JavaScript/TypeScript.
- Bandit – dla Pythona, output w stylu „lint”.
- GitHub Dependabot / GitLab Dependency Scanning – komunikacja w formie PR/MR.
Zaawansowane platformy z bogatymi panelami (np. komercyjne edycje Snyk, Veracode, Checkmarx) potrafią dać świetny wgląd w bezpieczeństwo, ale w małym projekcie szybko stają się ciężarem: wymagają osobnej uwagi, szkoleń, konfiguracji polityk. Przy darmowych wersjach SaaS bardzo łatwo też wejść w vendor lock‑in.
Prywatność i vendor lock‑in w darmowych SaaS
GitHub Actions, GitHub CodeQL, GitLab Ultimate (część funkcji dostępna w wersjach darmowych/community), Snyk Free – to niezwykle wygodne narzędzia, jednak trzeba świadomie wyważyć:
- Co wysyłasz do zewnętrznego SaaS – czy narzędzie działa lokalnie, czy kod jest wysyłany do skanowania do chmury.
- Jak łatwo migrować – czy raporty i konfiguracje można wynieść do innego narzędzia, jeśli projekt urośnie i zmienią się wymagania licencyjne.
- Ograniczenia darmowych planów – liczba projektów, liczba skanów miesięcznie, brak wsparcia dla prywatnych repo.
Dla projektów open source korzystanie z narzędzi SaaS bywa wręcz naturalnym wyborem – kod i tak jest publiczny, a „darmowe” funkcje bywają bogatsze (np. GitHub Code Scanning dla publicznych repo). Dla prywatnych projektów biznesowych warto rozważyć narzędzia, które można uruchamiać w CI lokalnie, bez wysyłania kodu na zewnątrz (Semgrep w trybie self‑hosted, Trivy, Syft, OWASP ZAP w kontenerze).
Podstawowe kategorie narzędzi DevSecOps – mapa przed wyborem
Co oznaczają SAST, SCA, DAST, IaC scanning i SBOM
Żeby sensownie dobrać darmowe narzędzia DevSecOps, dobrze jest rozróżniać kilka kluczowych kategorii:
- SAST (Static Application Security Testing) – analiza bezpieczeństwa kodu źródłowego lub bytecode. Przykłady: Semgrep, CodeQL, Bandit, Brakeman.
- SCA (Software Composition Analysis) – skanowanie zależności open source pod kątem znanych podatności w bibliotekach. Przykłady: OWASP Dependency-Check, Trivy, GitHub Dependabot.
- DAST (Dynamic Application Security Testing) – testowanie działającej aplikacji „z zewnątrz”, przez symulację ataków HTTP. Przykłady: OWASP ZAP, Nikto, Nuclei (web templates).
- Skanowanie kontenerów – analiza obrazów Docker (i czasem konfiguracji) pod kątem podatnych pakietów i błędnej konfiguracji. Przykłady: Trivy, Grype, Dockle.
- IaC scanning – analiza plików Infrastructure as Code (Terraform, CloudFormation, Kubernetes YAML) pod kątem błędnych ustawień bezpieczeństwa. Przykłady: Checkov, Terrascan, kube-score.
- Sekrety – wyszukiwanie przypadkowo zacommitowanych kluczy/hasel. Przykłady: TruffleHog, Gitleaks.
- SBOM (Software Bill of Materials) – lista komponentów (pakietów, bibliotek, obrazów) wchodzących w skład aplikacji. Przykłady generatorów: Syft, narzędzia CycloneDX.
Każda z tych kategorii odpowiada za inny etap cyklu życia aplikacji. W DevSecOps nie chodzi o to, by używać wszystkiego naraz, tylko by mieć minimalny, sensowny pokrycie kluczowych ryzyk.
Must‑have vs nice‑to‑have dla małego projektu webowego/API
Dla typowego małego projektu webowego lub API, który używa popularnego stosu (Node.js, Python, Java, .NET), można przyjąć takie priorytety:
- Must‑have:
- SCA – automatyczne skanowanie zależności (Dependabot, GitLab, OWASP Dependency-Check, Trivy).
- Podstawowe SAST – przynajmniej jedno narzędzie statyczne dopasowane do języka (Semgrep, Bandit, ESLint security).
- Skanowanie sekretów – Gitleaks/TruffleHog przy commitach lub w CI.
- Silne „warto mieć”:
- Skanery obrazów Docker – Trivy/Grype, jeśli aplikacja jest opakowana w kontenery.
- SBOM – Syft/CycloneDX dla lepszej widoczności i ewentualnych wymagań klienta.
- Nice‑to‑have:
- DAST – OWASP ZAP, Nikto, Nuclei na środowisku testowym.
- IaC scanning – Checkov/kube-score, jeśli infrastruktura jest zautomatyzowana i używany jest Terraform/Kubernetes.
Da się żyć bez DAST i rozbudowanego IaC scanningu na samym początku, ale brak choćby podstawowego SCA szybko mści się w postaci przestarzałych frameworków z publicznymi CVE.
Minimalne kombinacje dla różnych typów małych projektów
Inny zestaw narzędzi będzie optymalny dla SPA, inny dla narzędzia CLI czy mikroserwisu w kontenerze. Kilka przykładów:
Frontend SPA (React, Vue, Angular)
- Linting + pluginy bezpieczeństwa (ESLint z regułami security).
- SCA poprzez npm/yarn + Dependabot lub analogiczne boty.
- Skany sekretów w repo (Gitleaks).
- Opcjonalnie – Semgrep z rulesetami dla JS/TS.
Backend API (Node.js, Python, Java, .NET)
- SCA (Dependabot / OWASP Dependency-Check / Trivy).
- SAST (Semgrep lub narzędzia specyficzne dla języka: Bandit, Brakeman, SpotBugs itp.).
- Skany sekretów (Gitleaks lub TruffleHog).
- Docker? – Trivy/Grype do skanowania obrazów, Dockle do podstawowego hardeningu.
Monolity vs mikroserwisy – jak to zmienia dobór narzędzi
Popularna rada brzmi: „używaj tych samych narzędzi wszędzie, będzie prościej”. Działa to przy jednolitym monolicie, ale przy mikroserwisach łatwo kończy się tym, że każdy pipeline trwa wieczność. Mały zespół nie ma czasu czekać po 20 minut na pełen zestaw skanów dla drobnego serwisu pomocniczego.
Dla prostego monolitu webowego sensowne jest spięcie większości skanów w jednym pipeline (SAST, SCA, skan sekretów, skan obrazu Docker). Dla rozbudowanego zestawu mikroserwisów efektywniejsze bywa:
- minimalny „baseline” bezpieczeństwa dla wszystkich serwisów (SCA, skan sekretów),
- a dodatkowe skanery (ZAP, rozbudowane SAST) tylko dla tych, które wystawiają interfejs publiczny lub przetwarzają dane wrażliwe.
Inaczej mówiąc: nie każdy mikroserwis zasługuje na tę samą ilość uwagi. Serwis cronowy obrabiający dane z kolejki nie wymaga takiego samego DAST jak publiczne API logowania.
Jak priorytetyzować, gdy nie stać cię na „pełny pakiet”
Małe projekty często słyszą: „powinniście mieć SAST, DAST, SCA, IaC scanning, SBOM, testy penetracyjne…”. W praktyce kończy się to paraliżem decyzyjnym. Zamiast tego można przyjąć prostą, kontrariańską zasadę: najpierw zabezpiecz to, co najszybciej „wybucha” przy realnym ataku.
Kolejność inwestycji (czasowej, niekoniecznie finansowej) bywa wtedy inna niż w korporacyjnych checklistach:
- Zależności i sekrety – aktualne biblioteki i brak kluczy w repo poprawiają bezpieczeństwo najbardziej „tu i teraz”.
- Podstawowy SAST/linting – usuwa oczywiste błędy, które i tak przeszkadzają w developmentcie (np. potencjalne SQL injection w newralgicznych miejscach).
- Konfiguracja kontenerów/IaC – zamknięcie portów, brak kontenerów z rootem, sensowne polityki w Kubernetes.
- DAST – gdy powyższe są ogarnięte i masz stabilne środowisko testowe.
Popularna rada „zacznij od SAST, bo jest najdojrzalszy” nie zawsze działa przy projekcie utrzymującym stary framework. W takiej sytuacji większy zysk przyniesie agresywne SCA i generowanie SBOM, niż walka z setkami ostrzeżeń z narzędzia statycznego, które i tak wskazują na kod w bibliotece, a nie u ciebie.
Darmowe narzędzia SAST – jak dobrać zestaw pod mały projekt
Prosty schemat wyboru SAST według stosu technologicznego
Zamiast porównywać dziesiątki nazw, lepiej zacząć od stosu technologicznego i trybu pracy repozytorium. Dla większości małych projektów wystarczy schemat:
- Python: Bandit + (opcjonalnie) Semgrep z regułami Python.
- JavaScript/TypeScript: ESLint z pluginami security + (opcjonalnie) Semgrep.
- Ruby on Rails: Brakeman jako pierwszy wybór, Semgrep jako uzupełnienie.
- Java/Kotlin: SpotBugs/FindSecBugs lub Semgrep, jeśli i tak integrujesz go dla innych komponentów.
- .NET: Roslyn Analyzers (wbudowane) + dodatkowe reguły security, ewentualnie Semgrep.
Semgrep jest kuszący jako „jedno narzędzie do wszystkiego”, ale przy bardzo prostych projektach sensowniejsze bywa zostanie przy linterze, który i tak jest już w CI (ESLint, flake8 itp.), rozbudowanym o reguły bezpieczeństwa. Mniej narzędzi – mniej punktów awarii.
Integracja SAST w CI – minimalny, ale sensowny pipeline
Mały zespół nie potrzebuje wyszukanej orkiestracji. Ważne jest, by pipeline nie zabijał szybkości feedbacku. Rozsądny szkielet wygląda często tak:
# pseudokod dla GitHub Actions/GitLab CI
jobs:
test_and_lint:
steps:
- run: npm test / pytest / mvn test
- run: eslint ... / bandit ...
sast:
needs: test_and_lint
steps:
- run: semgrep --config "p/owasp-top-ten" --error
Dwie decyzje robią różnicę:
- Czy SAST blokuje merge? – na początku lepiej, żeby tylko ostrzegał (status „soft fail”), szczególnie jeśli kod jest już spory i spodziewasz się wielu historycznych błędów.
- Czy skanujesz cały kod przy każdym PR? – w małych repo tak, ale przy większych przydaje się skanowanie przyrostowe (tylko zmienione pliki), które oferuje m.in. Semgrep.
Dobrym kompromisem bywa ustawienie zasady: PR może wejść mimo ostrzeżeń, ale nie może podnosić ogólnej liczby „high severity” w projekcie. Daje to presję na naprawę problemów, ale nie blokuje gorących fixów.
Darmowe SAST a języki „niszowe”
Nie każdy ma luksus pracy w mainstreamie. Przy Go, Rust czy PHP wybór darmowych SAST jest nieco inny:
- Go: GoSec, a w prostych przypadkach – rozsądne użycie wbudowanego
go vet. - Rust: Clippy z naciskiem na reguły bezpieczeństwa, dodatkowo manualny przegląd użycia
unsafe. - PHP: Psalm lub PHPStan rozszerzone o reguły bezpieczeństwa, ewentualnie narzędzia z rodziny RIPS/open-source forks.
Przy językach, gdzie SAST dopiero raczkuje, bardziej opłaca się zainwestować w dobre testy jednostkowe wokół newralgicznych fragmentów (np. walidacja danych wejściowych) i podstawowe DAST, niż walczyć z narzędziem, które ma słabe reguły.
Skanowanie zależności (SCA) i SBOM – jak ujarzmić biblioteki bez armii ludzi
Dependabot i spółka – kiedy automatyczne PR z aktualizacjami mają sens
Popularna rada: „włącz Dependabot i zapomnij”. W małym projekcie to działa tylko wtedy, gdy:
- masz testy automatyczne, które wychwycą regresje po aktualizacji,
- stos technologiczny nie jest egzotyczny (czyli biblioteki sensownie trzymają semver),
- ktoś faktycznie przegląda PR-y bota, a nie klika bezrefleksyjnie „merge”.
Jeżeli testów jest mało albo brak, lepiej ograniczyć Dependabota do aktualizacji bezpieczeństwa (security-only) oraz bibliotek w warstwie „brzegowej” (framework webowy, ORM, klient HTTP). Biblioteki niskiego poziomu, ściśle powiązane z twoim kodem, czasem bezpieczniej aktualizować ręcznie co kilka tygodni, przy świadomym testowaniu.
Lokalne SCA: OWASP Dependency-Check, Trivy, Syft
Dla projektów, które nie chcą wysyłać nic poza własną infrastrukturę, rozsądne opcje to:
- OWASP Dependency-Check – klasyk dla JVM, JavaScript, .NET; dobre raporty HTML, gotowe integracje z Maven/Gradle.
- Trivy – oprócz kontenerów potrafi skanować zależności w repo (np.
trivy fs .), co bywa użyteczne przy prostych projektach. - Syft + Grype – Syft generuje SBOM, Grype na jego podstawie wyszukuje podatności.
Przy małym projekcie wygodnym wzorcem jest: Syft jako generator SBOM + Grype jako skaner. Dzięki temu łatwo będzie później dołączyć SBOM do dokumentacji dla klienta lub do procesu audytu, nie zmieniając całego ekosystemu narzędzi.
Pragmatyczne podejście do SBOM w małych zespołach
SBOM kojarzy się z dużymi firmami i regulacjami, ale dla małego zespołu bywa prostym ubezpieczeniem na przyszłość. Wygodny, lekki schemat wygląda tak:
- generowanie SBOM przy zbudowaniu releasu (np. tag w Git),
- trzymanie SBOM w artefaktach CI lub w osobnym repo „compliance”,
- uruchamianie skanu podatności na podstawie istniejących SBOM bez ingerencji w sam proces builda.
Kontrariańska uwaga: generowanie SBOM na każdym PR często nie ma sensu przy małym projekcie – koszt obliczeniowy i szum w pipeline są wysokie, za to korzyść marginalna. Wystarczy robić to przy releasach lub nocnych buildach.
Bezpieczeństwo kontenerów i środowiska uruchomieniowego w wersji „light”
Minimalny hardening obrazów Docker
Najczęstsza rada brzmi: „używaj minimalnych obrazów i nie uruchamiaj niczego jako root”. Problem w tym, że wielu developerów przy małym projekcie po prostu bierze node:latest i stawia na tym całą aplikację. Zamiast walczyć z tym na siłę, można wprowadzić kompromisy:
- zamiast
latestużywać konkretnej wersji obrazu bazowego, - dodawać prosty etap skanowania (Trivy/Dockle) tylko dla obrazów oznaczonych jako „release”,
- ustawić użytkownika nie-root dopiero jako osobne, świadome zadanie, gdy projekt trochę okrzepnie.
Podejście „wszystko od razu zgodne z CIS Benchmarks” rzadko działa w małych zespołach. Często bardziej opłaca się ustalić krótką listę zasad (nie root, nie latest, regularne skany) i dopiero potem iść w stronę bardziej zaawansowanych polityk.
Trivy, Grype, Dockle – sensowny zestaw dla startu
Dla prostych aplikacji kontenerowych sprawdza się kombinacja:
- Trivy – podstawowe skanowanie obrazów i systemu plików; łatwe uruchomienie z poziomu CI.
- Grype – alternatywa lub uzupełnienie, przydatna szczególnie w duecie z Syft.
- Dockle – narzędzie do sprawdzania dobrych praktyk Dockerfile (exposed porty, użytkownik, konfiguracja logów).
Nie trzeba mieć wszystkich narzędzi jednocześnie. Jeżeli pipeline już jest rozbudowany, sensowne jest zaczęcie tylko od Trivy i dopiero w kolejnym kroku dorzucenie Dockle z limitem „tylko high severity łamie build”. To ogranicza liczbę konfliktów między „musimy wypuścić” a „narzędzie nie przepuszcza obrazu”.
Lightweight security w Kubernetes
Dla małych instalacji Kubernetesa, szczególnie managed (EKS, GKE, AKS), pełne zestawy jak kube-bench, falco, cały CNF stack bywają przesadą. Zamiast tego można wykorzystać:
- kube-score – analiza manifestów YAML pod kątem podstawowych błędów (brak
resources,livenessProbe, zbyt szerokie uprawnienia). - policies w CI (np. Checkov dla Terraform + skan manifestów) zamiast zaawansowanego runtime enforcementu.
Dla małego projektu większy zysk daje wyłapywanie złej konfiguracji na etapie pull requestu niż stawianie rozbudowanego systemu monitoringu produkcji, którego nikt nie ma czasu doglądać.

DAST i bezpieczeństwo aplikacji webowych bez budżetu na komercyjne skanery
OWASP ZAP w trybie „headless” – jak nie przegiąć z konfiguracją
ZAP to domyślna odpowiedź na pytanie o darmowy DAST. Typowa rada mówi: „odpalaj full scan na każdym buildzie”. Przy małym zespole prowadzi to do szybkiego wyłączenia joba – skany trwają długo, wyniki są obszerne, a pipeline zaczyna przekraczać sensowne limity czasu.
Bardziej praktyczne podejście:
- quick scan przy PR – ograniczony czasowo i zakresem (sprawdza tylko najprostsze problemy, np. XSS, podstawowe misconfigi),
- full scan jako job nocny – uruchamiany np. raz na dobę na środowisku testowym, z wynikami w formie raportu HTML.
Kontrariańska uwaga: w wielu małych projektach sensowne jest wręcz zrobienie skanu ad-hoc przed większym releasem, zamiast trzymać ZAP w każdym pipeline. Szczególnie gdy aplikacja jest prosta i zmiany rzadkie, a utrzymywanie stałego joba generuje tylko dodatkową pracę.
Automatyczne vs ręczne DAST – kiedy wystarczy kilka komend curl
DAST jest często utożsamiany z rozbudowanymi skanerami. Tymczasem przy prostym API REST kilka dobrze dobranych testów ręcznych (a właściwie półautomatycznych) potrafi dać lepszy sygnał niż domyślny profil ZAP:
- sprawdzenie, czy API poprawnie waliduje typy i zakresy (skrypty w Pythonie lub Postman/Insomnia),
- testy autoryzacji – czy użytkownik A może odczytać zasoby B po zmianie ID w URL,
- symulacja prostych ataków typu „SQL injection string” w polach wejściowych.
Nie chodzi o zastąpienie DAST, lecz o rozsądne uzupełnienie. Przy bardzo małych projektach, gdzie wdrożenie ZAP jest ponad siły, taki „manualny DAST” realizowany raz na sprint już podnosi poziom bezpieczeństwa powyżej standardu „nic nie sprawdzamy, bo nie mamy narzędzia”.
Nuclei, Nikto i inne lekkie skanery HTTP
Nuclei i Nikto jako „czujki dymu”, a nie pełna straż pożarna
Skanery HTTP typu Nuclei czy Nikto kuszą prostotą: jedno polecenie, lista URL-i i gotowe. Problem zaczyna się, gdy potraktuje się je jak magiczny przycisk „sprawdź mi bezpieczeństwo”. Domyślne szablony Nuclei potrafią być bardzo szerokie, a Nikto bywa hałaśliwy i generuje sporo false positive na niestandardowych aplikacjach.
Rozsądne zastosowanie w małym projekcie to rola „czujek dymu”, które:
- odpalane są okresowo (np. raz na tydzień) na środowisku testowym lub staging,
- mają ograniczony zestaw szablonów – np. tylko kategoria
cvesimisconfigurationw Nuclei, - służą do szybkiego wyłapania oczywistych problemów (stare panele admina, katalogi listujące zawartość, znane podatne wersje paneli/serwerów).
Zamiast „odpalamy całą galerię szablonów Nuclei po każdym deployu”, lepszy jest mały, kuratorowany zestaw, który rzeczywiście ktoś będzie analizował. Z czasem można dodawać kolejne szablony, gdy zespół oswoi się z wynikami i wypracuje sposób na ich triage.
Nikto sensownie sprawdza się głównie jako szybki sanity-check konfiguracji klasycznych serwerów HTTP (Apache, Nginx) albo legacy-API. Jeżeli infrastruktura to w większości serverless + managed API gateway, korzyść z Nikto spada, a lepszą inwestycją czasu jest testowanie reguł WAF i polityk autoryzacji.
Łączenie DAST z testami integracyjnymi zamiast osobnego „potwora” w CI
Popularny wzorzec to osobny, ciężki job DAST, który odpala się po wszystkich testach i buildach. Przy małym zespole tafia to na listę „pierwszy kandydat do wyłączenia, gdy pipeline przekracza 20 minut”. Alternatywa: wczepienie lekkich testów DAST w istniejące testy integracyjne.
Przykładowo:
- testy integracyjne uruchamiają lokalne środowisko (np. docker-compose),
- w ramach tych samych testów wywoływany jest krótki profil ZAP lub seria skryptów curl/postmanowych z prostymi payloadami atakującymi walidację danych i autoryzację,
- wynik jest traktowany jak zwykły test – zielony/czerwony, bez ogromnych raportów do analizy.
Z czasem, jeżeli okaże się, że takie podejście działa, można dołożyć osobny, pełniejszy skan tylko dla branchy release lub tagów. Inaczej mówiąc – DAST jako rozszerzenie istniejących testów, a nie jako nowa, osobna kategoria obciążeń dla CI.
Monitorowanie i logowanie bezpieczeństwa w wersji „nie boli”
Minimalne logi bezpieczeństwa – co logować, żeby nie utonąć
Rada „loguj wszystko” jest kusząca, dopóki pierwszy raz nie przyjdzie analizować 2 GB logów z jednego dnia. W małym projekcie lepsza jest precyzyjna selekcja zdarzeń, które faktycznie pomagają przy wykrywaniu incydentów i analizie po fakcie.
Sensowny, mały zestaw to:
- nieudane logowania (z adresem IP, user-agentem, czasem, ale bez przesady z danymi osobowymi),
- próby dostępu do zasobów bez autoryzacji (HTTP 401/403 na wrażliwych endpointach),
- operacje „wysokiego ryzyka” – zmiana hasła, adresu e-mail, danych rozliczeniowych, uprawnień użytkownika,
- wewnętrzne błędy aplikacji (5xx) z krótkim identyfikatorem korelacji, żeby można było je śledzić między usługami.
Rozsądne jest rozdzielenie logów „operacyjnych” (wydajność, biznes) od „bezpieczeństwa” już na poziomie struktury – choćby poprzez osobne indeksy w systemie logowania czy osobne pliki, jeżeli korzystasz z prostych rozwiązań. To później oszczędza czas przy szukaniu konkretnego typu zdarzeń.
Alerty bez SIEM-u – co da się zrobić na darmowych narzędziach
Pełnoprawny SIEM, reguły korelacji, ML do wykrywania anomalii – to zwykle za duży kaliber dla małego projektu. Da się jednak wyciągnąć sensowne alerty z tego, co już istnieje: systemu logowania, Prometheusa, a nawet zwykłych cronów.
Praktyczne przykłady prostych alertów:
- skok liczby nieudanych logowań w krótkim czasie (np. Prometheus + alertmanager lub funkcja agregująca w narzędziu typu Loki/Elasticsearch),
- wzorzec „5xx na jednym endpointcie rośnie nagle kilkukrotnie” – często sygnał błędu logicznego lub próby ataku,
- powtarzające się próby dostępu do nieistniejących zasobów o „podejrzanych” nazwach (np.
wp-admin,phpmyadmin) na aplikacji, która nie jest WordPressem.
Często wystarczy jedna-dwie proste reguły alertów, które przychodzą na Slacka lub e-mail. Lepszy skromny, ale czytany alert niż rozbudowany system, którego notyfikacje lądują w osobnym, nigdy nieotwieranym kanale.
Open-source’owe „mini-SIEM” dla projektów bez budżetu
Jeżeli projekt mimo wszystko generuje już sporo logów, można sięgnąć po lekkie, darmowe klocki zamiast od razu budować pełny SOC. Popularne kombinacje to:
- Grafana + Loki + Promtail – centralne logowanie, proste zapytania i alerty; dobry „entry-level” bez licencji,
- Elasticsearch/OpenSearch + Kibana – gdy logów jest więcej i potrzebne są bogatsze możliwości filtrowania; koszt to głównie czas na konfigurację,
- Wazuh – krok dalej, już bliżej SIEM, ale przy małej skali da się to uruchomić za darmo i wykorzystać podstawowe reguły.
Kontrariańskie spojrzenie: nie zawsze sens ma centralizacja wszystkiego od razu. Dla prostego projektu monolitycznego czasem wystarczy uporządkowany system logów na jednej maszynie lub jednej usłudze PaaS, ale z sensownymi poziomami (INFO/WARN/ERROR) i filtrowaniem po polu „security_event = true”.
Polityki bezpieczeństwa jako kod – lekkie podejście do „governance”
Checkov, Conftest, OPA – reguły, które nie zamieniają PR-ów w pole bitwy
„Polityki jako kod” brzmią jak domena korporacji z osobnym działem compliance. W praktyce pojedynczy plik z kilkoma regułami potrafi zdjąć z małego zespołu sporo manualnej kontroli. Problem zaczyna się, gdy zestaw reguł jest skopiowany w całości z szablonu „enterprise” – efekt jest prosty: większość PR-ów jest na czerwono, więc narzędzie ląduje w koszu.
Bardziej sensowna droga:
- zacząć od 3–5 kluczowych reguł – np. „żaden bucket S3 nie może być publiczny”, „żaden security group nie może mieć 0.0.0.0/0 na porcie bazy”,
- oznaczyć te reguły jako warning lub „niełamące builda” przez pierwsze 2–3 tygodnie,
- dopiero po ustabilizowaniu konfiguracji podnieść ich status na „blocker”.
Checkov dobrze sprawdza się dla Terraform/CloudFormation, Conftest/OPA – dla dowolnych YAML-i/JSON-ów (np. manifesty K8s, polityki CI). Dzięki temu polityki nie są już dokumentem w Confluence, którego nikt nie czyta, tylko realnym, automatycznym sprawdzeniem przy każdym PR.
Mały zestaw „reguł zdrowego rozsądku” zamiast pełnych benchmarków
CIS Benchmark dla Kubernetesa, AWS czy Docker to dziesiątki punktów. Ślepe wdrażanie wszystkich na raz przy małym zespole kończy się tym, że developerzy spędzają więcej czasu na walce z regułami niż na rozwijaniu produktu. Zamiast tego da się zbudować mini-benchmark dopasowany do realiów projektu.
Przykładowy zestaw startowy:
- brak haseł i tokenów na stałe w Terraform/Helm (wymuszone np. przez reguły Checkov/OPA),
- obowiązkowe tagi/labelki bezpieczeństwa (np.
owner,environment,data_sensitivity) przy zasobach chmurowych, - zakaz tworzenia publicznych endpointów bez WAF/proxy (prosta reguła na podstawie konfiguracji load balancera lub ingressa).
Taki mini-benchmark można zapisać w README projektu i w kilku regułach narzędzia, zamiast od razu implementować pełny zestaw. Jeżeli zespół rośnie, nic nie stoi na przeszkodzie, żeby stopniowo zbliżać się do pełnych benchmarków.
Praktyczne łączenie narzędzi – przykładowe „zestawy startowe”
Monolit webowy w jednym repo – minimalny, ale sensowny zestaw
Dla małej aplikacji webowej (np. Django, Laravel, Spring Boot) w jednym repozytorium da się zbudować lekki, przewidywalny pipeline DevSecOps bez dziesiątek narzędzi. Przykładowa konfiguracja „na start”:
- SAST: Semgrep z kilkoma profilami bezpieczeństwa + ewentualnie językowy lint (ESLint, PHPStan, Pylint) z regułami security,
- SCA: Dependabot (tylko security) + okresowy (np. tygodniowy) skan OWASP Dependency-Check lub Trivy FS,
- Kontenery: Trivy na obrazie release + Dockle jako „warning only” w pierwszym etapie,
- DAST: szybki profil ZAP lub Nuclei na staging przed głównym releasem (np. raz na sprint),
- Logi: podstawowe logowanie bezpieczeństwa z prostym alertem na skok nieudanych logowań.
Kluczowy element to nie „jak wiele narzędzi”, tylko „jakie kryteria sprawiają, że bug blokuje releas”. Dobrze zdefiniowany próg (np. „High z CVSS >= 7 blokuje, Medium tylko raportujemy”) ogranicza chaos decyzji przy każdym pipeline’ie na czerwono.
Mały zestaw mikrousług – jak nie zwariować przy wielu repozytoriach
Przy kilku-kilkunastu serwisach w osobnych repozytoriach największym ryzykiem jest rozjazd konfiguracji: każdy serwis ma inny zestaw narzędzi, inne wersje, inne poziomy ostrzeżeń. Szybko robi się z tego „zoo”, którego nikt nie panuje.
Lepsza strategia to prosty, wspólny szablon pipeline’u bezpieczeństwa, np. w formie:
- wspólnego pliku
.gitlab-ci.ymlalbo GitHub Actions Reusable Workflow, - małego „meta-repo” z definicjami reguł Semgrep, Checkov czy OPA, importowanych do wszystkich projektów,
- wspólnych skryptów CLI (np. w Pythonie/Go) do uruchamiania SAST/SCA/DAST z predefiniowaną konfiguracją.
Z punktu widzenia małego zespołu ważniejsze jest, żeby każdy nowy serwis „z automatu” miał ten sam poziom zabezpieczeń, niż żeby jeden wybrany serwis miał idealnie dopieszczony pipeline. Utrzymanie szablonu w jednym miejscu jest po prostu tańsze niż dłubanie konfiguracji w każdej usłudze osobno.
Projekty typu „proof of concept” – gdzie postawić minimalną granicę
POC-e i wewnętrzne prototypy bywają usprawiedliwieniem dla zupełnego braku bezpieczeństwa („to tylko demo, nikt tego nie zobaczy”). Problem w tym, że część z nich nigdy nie doczeka się „porządnego przepisywania”, tylko po prostu trafia na produkcję, bo „działa”. Dlatego nawet POC zasługuje na pewne minimum.
Pragmatyczna granica:
- brak twardo zaszytych sekretów – nawet jeżeli używasz prostego pliku
.envlokalnie, nie powinien trafić do repozytorium, - chociaż jeden skan SCA (np. Trivy FS) przed wystawieniem POC-a na publiczny adres,
- podstawowy SAST (choćby lekki profil Semgrep) i testy autoryzacji na najbardziej wrażliwych endpointach.
To dalekie od „pełnego” DevSecOps, ale zdecydowanie lepsze niż standard „nic, bo to tylko POC”. Zwłaszcza że część narzędzi można uruchomić lokalnie jednym poleceniem, bez budowy pełnego pipeline’u CI.
Organizacja pracy z darmowymi narzędziami – jak nie utonąć w ostrzeżeniach
Triage podatności – kto decyduje, co naprawić najpierw
Narzędzia SAST/SCA/DAST lubią produkować długie listy problemów. Bez jasnego procesu kończy się na tym, że każdy patrzy na inny raport albo ignoruje wszystkie. W małym zespole workflow nie musi być skomplikowany, ale powinien być konkretny.
Prosty schemat:
- raz w tygodniu lub sprint przegląd raportów (30–45 minut),
- oznaczenie kilku najważniejszych problemów jako zadania w backlogu (Jira, GitHub Issues, cokolwiek jest używane),
- zdefiniowanie „service level” – np. „High fixujemy w ciągu 7 dni, Medium w kolejnym sprincie, Low tylko gdy jest łatwa poprawka”.
Najważniejsze wnioski
- DevSecOps ma sens także w jednoosobowych i małych zespołach, bo skala organizacji nie zmienia rodzaju problemów bezpieczeństwa – różni się tylko ilość czasu, który można poświęcić na ich ogarnianie.
- Lekka, zautomatyzowana integracja z Git/CI (jak unit testy i linty w tle) działa lepiej niż „wielkie platformy bezpieczeństwa”; narzędzie, które wymaga ciągłego klikania w UI, w małym projekcie umiera po tygodniu.
- Popularna rada „bezpieczeństwem zajmiemy się później” jest kosztowna: im większy system i bardziej skomplikowany pipeline, tym droższe łatanie dziur i przepinanie procesów – najłatwiej wdrożyć minimum DevSecOps na starcie.
- Realne problemy małych projektów to głównie wycieki sekretów, dziurawe zależności, błędne konfiguracje i brak widoczności komponentów, a nie zaawansowane ataki; te typowe błędy da się znacząco ograniczyć darmowymi narzędziami wpiętymi w codzienny workflow.
- Minimalny sensowny cel to „bezpieczeństwo, które nie przeszkadza”: automatyczne ostrzeganie przy PR-ach, blokowanie tylko krytycznych przypadków (np. wycieki sekretów, poważne CVE) i raporty w tym samym miejscu, gdzie wyniki testów.
- Przy wyborze darmowych narzędzi kluczowy jest koszt wdrożenia i utrzymania (czas integracji, szum, false positive), a nie tylko brak faktury; często prostsze rozwiązania typu Semgrep w CI dają wyższy zwrot niż ciężkie platformy pokroju własnego SonarQube.
Bibliografia
- DevSecOps: Integrating Security into DevOps. National Institute of Standards and Technology (NIST) (2022) – Opis koncepcji DevSecOps i integracji bezpieczeństwa z CI/CD
- NIST Secure Software Development Framework (SSDF) SP 800-218. National Institute of Standards and Technology (NIST) (2022) – Ramy bezpiecznego wytwarzania oprogramowania, w tym automatyzacja
- OWASP DevSecOps Guidelines. OWASP Foundation – Praktyczne wytyczne wdrażania DevSecOps w różnych skalach projektów
- DevSecOps: A Leader’s Guide to Producing Secure Software. U.S. Department of Defense, Enterprise DevSecOps Initiative (2021) – Opis filozofii DevSecOps i korzyści z wczesnego wdrożenia
- Software Composition Analysis (SCA) Explained. Cloud Native Computing Foundation (CNCF) – Omówienie skanowania zależności i roli SBOM w bezpieczeństwie
- Supply-chain Levels for Software Artifacts (SLSA) Framework. OpenSSF (Open Source Security Foundation) (2023) – Model do oceny bezpieczeństwa łańcucha dostaw oprogramowania
- GitHub Advanced Security: Code Scanning and Secret Scanning Overview. GitHub – Opis automatycznego SAST i wykrywania sekretów w workflow GitHub
- GitLab DevSecOps Overview. GitLab – Dokumentacja integracji SAST, DAST i skanowania zależności w CI/CD
- Semgrep Documentation – CI Integration and Rules. Semgrep – Opis lekkiej integracji Semgrep z pipeline’ami GitHub/GitLab






