Videt omnia. Meminit omnia. Iudicat omnia.
Adwersarz, który sądzi
Jedna pętla: polowanie w granicach prawa, domknięcie detekcji na SIEM klienta, dowód zapieczętowany pod DORA. Nic nie opuszcza Twojej infrastruktury.
The adversary that judges
One loop: hunting within legal scope, detection closed on the client's SIEM, evidence sealed for DORA. Nothing leaves your infrastructure.
Wybierz ścieżkę czytaniaPick a reading path
Czym się różnimy
Narzędzia, które znasz, dają zwykle jedną warstwę: skaner zwraca listę podatności, platforma BAS odgrywa gotowy scenariusz, pentest kończy się raportem, a usługa red-team to wynajęta para rąk. CYRBER łączy sześć rzeczy w jedną rządzoną pętlę i to ich połączenie, a nie żadna z osobna, stanowi różnicę.
Rozumuje, zamiast odgrywać skrypt. MENS prowadzi misję jak agent: na każdej iteracji przechodzi OBSERVE, THINK, ACT, LEARN i sam wybiera następny ruch, więc operator nie pisze playbooka pod konkretny cel, lecz obserwuje rozumowanie i pieczętuje wnioski. Skaner odpala stałą listę wtyczek, a platforma BAS odgrywa z góry ułożony scenariusz. MAMY ścieżka: modules/mind_agent.py (pętla agentowa MENS)
Celuje w realny dostęp, nie w listę CVE. Misja dąży do udowodnienia, że łańcuch da się przejść, a nie do wydrukowania rejestru podatności, przy czym domyślnie zatrzymuje się na udowodnionym dostępie, a ekstrakcję czy exfiltrację włączasz osobnym, bramkowanym trybem. MAMY ścieżka: playbooki demonstrują dostęp; tryb impact opt-in, bramkowany licencją, LEX oraz zgodą (modules/secretsdump_scan.py prove_impact, modules/lex.py)
Domyka detekcję na SIEM klienta. Wynik ataku trafia na Wazuh stawiany osobno dla każdej organizacji, więc atak i obrona uczą się na tym samym zdarzeniu, a luka w detekcji się zamyka. To purple, czyli czerwony i niebieski w jednej pętli, a nie sam czerwony, który zostawia raport. MAMY ścieżka: Wazuh per-org, metryka standing-purple; hook detekcji po misji (modules/integrations/wazuh.py)
Zostawia dowód, nie obietnicę. Każdy finding jest zahashowany, zamknięty w drzewie Merkle i zakotwiczony w łańcuchu Bitcoina, więc werdykt sprawdzisz sam, bez dostępu do naszej bazy. Raport, któremu trzeba zaufać, zastępujemy dowodem, który przeliczysz. MAMY ścieżka: backend/proof.py SHA-256 + HMAC na liściu + kotwica OpenTimestamps; rozdział Glass House
Należy do klienta. Platforma stoi u klienta on-prem, dane oraz przebieg misji zostają na jego infrastrukturze, a my nie trzymamy żadnej kopii; do pełnego odcięcia od sieci brakuje jeszcze lokalnego modelu rozumowania. On-prem MAMY, pełny air-gap DOŁOŻYMY. ścieżka: deployment on-prem; model lokalny air-gap w planie, patrz Suwerenność
Żyje, zamiast stać. Organizm sam leczy własny stan działania, uczy się z każdej zamkniętej misji i pilnuje, żeby jego własny opis pozostawał prawdziwy, więc nie jest statycznym narzędziem, lecz systemem, który nieustannie doprowadza się do porządku. MAMY ścieżka: samoleczenie MEDICUS oraz pętla immunologiczna; rozdział Samoleczenie (modules/organism_medicus_plenus.py, modules/organism_feedback.py)
Żadna z tych sześciu rzeczy z osobna nie jest nowa. Nowa jest jedna rządzona pętla, która wiąże je razem: od polowania w granicach prawa, przez domknięcie detekcji, aż po dowód pod regulację, i to w całości pod kontrolą klienta.
CYRBER jest przy tym dokładnie tym, co dziś potrafimy uzasadnić kodem, ani mniej, ani więcej, i właśnie dlatego znaczniki DOŁOŻYMY zostawiamy widoczne, zamiast je chować. To jednak nie jest system zamrożony, ponieważ przez FORUM zgłaszasz własny postulat, brak albo potrzebę, a jeśli obroni się technicznie, biznesowo oraz logicznie, trafia do decyzji i go dokładamy. Lista DOŁOŻYMY nie jest więc naszą zamkniętą obietnicą, lecz kierunkiem, który współtworzysz. FORUM z panelem postulatów i decyzji MAMY ścieżka: static/forum.html + forum-admin.html, backend/routers/forum_uploads.py, modules/forum_models.py ForumPostulatum, modules/capabilities/forum.py
How we differ
The tools you know usually give one layer: a scanner returns a list of vulnerabilities, a BAS platform replays a canned scenario, a pentest ends in a report, and a red-team service is a pair of hired hands. CYRBER binds six things into one governed loop, and it is their combination, not any single one, that makes the difference.
It reasons instead of replaying a script. MENS runs a mission as an agent: on every iteration it walks OBSERVE, THINK, ACT, LEARN and picks its own next move, so the operator writes no per-target playbook and instead watches the reasoning and seals the conclusions. A scanner fires a fixed list of plugins; a BAS platform replays a scenario laid out in advance. MAMY path: modules/mind_agent.py (the MENS agent loop)
It aims at real access, not a CVE list. A mission works to prove that the chain can be walked, not to print a register of vulnerabilities, and by default it stops at proven access; you turn extraction or exfiltration on through a separate, gated mode. MAMY path: playbooks demonstrate access; impact mode is opt-in, gated by license, LEX and consent (modules/secretsdump_scan.py prove_impact, modules/lex.py)
It closes detection on the client's SIEM. The result of an attack lands on a Wazuh stack stood up separately for each organization, so attack and defense learn from the same event and the detection gap closes. This is purple: red and blue in one loop, not red alone leaving a report. MAMY path: per-org Wazuh, standing-purple metric; post-mission detection hook (modules/integrations/wazuh.py)
It leaves a proof, not a promise. Every finding is hashed, closed inside a Merkle tree and anchored to the Bitcoin chain, so you check the verdict yourself, without access to our database. We replace a report you must trust with a proof you can recompute. MAMY path: backend/proof.py SHA-256 + per-leaf HMAC + OpenTimestamps anchor; the Glass House chapter
It belongs to the client. The platform stands at the client's site on-prem, the data and the mission run stay on their infrastructure, and we keep no copy; a full cut-off from the network still needs the local reasoning model. On-prem is MAMY; a full air-gap is DOŁOŻYMY. path: on-prem deployment; local air-gap model planned, see Sovereignty
It lives instead of sitting still. The organism repairs its own running state, learns from every mission that closes, and keeps its own account of itself true, so it is not a static tool but a system that keeps setting itself right. MAMY path: MEDICUS self-healing and the immune loop; the Self-healing chapter (modules/organism_medicus_plenus.py, modules/organism_feedback.py)
None of these six on its own is new. What is new is the one governed loop that binds them: from hunting within legal scope, through closing detection, to a proof fit for regulation, and all of it under the client's control.
CYRBER is exactly what we can justify in code today, no more and no less, which is why we leave the DOŁOŻYMY markers visible instead of hiding them. Yet it is not a frozen system, because through FORUM you raise your own postulate, a gap or a need, and if it holds up technically, in business terms and in logic, it goes to a decision and we build it. The DOŁOŻYMY list is therefore not a closed promise of ours but a direction you help shape. FORUM, with its postulate and decision panel, is MAMY path: static/forum.html + forum-admin.html, backend/routers/forum_uploads.py, modules/forum_models.py ForumPostulatum, modules/capabilities/forum.py
Filozofia
Łacina kompresuje koncept w jedno słowo i nie pozwala marketingowi go rozmyć. MENS to umysł, SPECULUM zwierciadło, TESTIMONIUM świadectwo, ANNALES kroniki, UMBRA cień. Trzymamy się tych nazw, a pierwsze użycie tłumaczy ich sens.
Pod tymi nazwami stoi pięć zasad, z których żadna nie jest metaforą doklejoną dla efektu, ponieważ każda pokrywa się z konkretnym miejscem w kodzie.
Agent rozumuje na bieżąco. CYRBER prowadzi misję jak agent: na każdej iteracji przechodzi cykl OBSERVE, THINK, ACT, LEARN i sam decyduje o następnym ruchu. Operator nie pisze playbooków pod cel; obserwuje rozumowanie i pieczętuje wnioski. MAMY ścieżka: modules/mind_agent.py (pętla agentowa MENS v2)
Organy mają puls, bo potrafią zasnąć. Niezmiennik I-9 jest jednoznaczny: każdy z … unikalnych komponentów, czyli dwunastu organów, pięciu filarów i dwóch głów, musi wysłać puls w ciągu doby, a kto milczy dłużej, ten liczy się już jako martwy. Puls jest przy tym mechanizmem utrzymania, ponieważ powierzchnia rośnie szybciej, niż jedna osoba zdoła ją dogonić, więc organizm sam melduje, co właśnie usnęło. MAMY ścieżka: modules/organ_pulse.py, endpoint GET /api/organism/liveness
Filary żywią się nawzajem w łańcuchu. Kiedy misja MENS się domyka, rusza łańcuch hooków: SPECULUM liczy genom, TESTIMONIUM zakłada pieczęć, UMBRA odświeża twin, ANNALES stawia prognozę, CORTEX mierzy trafność, dalej FATUM, COMES, LIBER i ITERUM. Filary tworzą łańcuch pokarmowy: każdy zjada wynik poprzedniego, a po sukcesie bije własny puls. MAMY ścieżka: run_hook() w modules/mind_agent.py (auto-fire w całym łańcuchu hooków po misji, z retry i circuit breakerem)
Sygnał jednego organu uruchamia łuk odruchowy. Capability bus jest układem nerwowym: … zdolności w jednym rejestrze, a szyna organism_feedback przenosi zdarzenia między organami. Kaskady biegną wieloma hopami, ponieważ exploit_available budzi risk_spike, ten z kolei wywołuje drift_detected, a następnie dimension_stale, aż decide_and_act zamyka odruch, a autonomiczny krok pieczętuje liść w TESTIMONIUM, co w sumie daje do sześciu hopów od bodźca aż do dowodu. MAMY ścieżka: modules/organism_feedback.py, scripts/reflex_arc_walk.py, modules/testis/reflex_arc_seal.py
Autonomia to pokrętło, nie przełącznik. Operator nie wybiera między trybem ręcznym a w pełni automatycznym, lecz kręci pokrętłem po macierzy klas ryzyka i ustawia, co system robi samodzielnie, co wymaga zgody, a co zostaje zablokowane, a jest to wola świadoma, sprawowana pod prawem LEX oraz pod polityką zapisaną osobno dla każdego celu. MAMY ścieżka: modules/autonomy_policy.py (AutonomyPolicy), strona /organism
Tych pięć zasad składa się w jedną tezę. Jedna rządzona pętla, od polowania po zapieczętowany werdykt: realna eksploatacja, zamknięcie luki w detekcji na własnym SIEM klienta, kryptograficznie zapieczętowany dowód pod DORA TLPT, oraz ani jeden bajt nie opuszcza murów klienta. Część tej pętli już bije, część dokładamy DOŁOŻYMY; pełny obraz akt po akcie znajdziesz w rozdziale Rytuał misji. CYRBER każe weryfikować zamiast wierzyć na słowo, więc tę samą miarę stosujemy do dokumentacji: każda zasada wskazuje miejsce w kodzie, a znaczniki MAMY i DOŁOŻYMY oddzielają to, co już bije, od tego, co dopiero powstaje.
Philosophy
Latin compresses a concept into a single word and keeps marketing from watering it down. MENS is the mind, SPECULUM the mirror, TESTIMONIUM the witness, ANNALES the chronicles, UMBRA the shadow. The docs keep these names throughout, and every first use spells out what it means.
Five rules sit under those names, and none of them is a metaphor glued on for effect, because each maps to a specific place in the code.
The agent reasons as it goes. CYRBER runs a mission as an agent: on every iteration it walks OBSERVE, THINK, ACT, LEARN and picks its own next move. The operator writes no per-target playbook, but instead watches the reasoning and seals the conclusions. MAMY path: modules/mind_agent.py (MENS v2 agent loop)
Organs carry a pulse because they can fall asleep. Invariant I-9 is unambiguous: each of the … unique components, twelve organs, five pillars and two heads, must emit a pulse within a day, and one that stays quiet longer counts as dead. The pulse is a maintenance mechanism: the attack surface grows faster than one person can chase it, so the organism reports on its own what went dark. MAMY path: modules/organ_pulse.py, endpoint GET /api/organism/liveness
The pillars feed on one another in a chain. When a MENS mission closes, a hook chain fires: SPECULUM scores the genome, TESTIMONIUM sets the seal, UMBRA refreshes the twin, ANNALES casts the forecast, CORTEX measures accuracy, then FATUM, COMES, LIBER and ITERUM. The pillars form a food chain: each consumes the previous result, and each beats its own pulse once it succeeds. MAMY path: run_hook() in modules/mind_agent.py (auto-fired across the whole post-mission hook chain, with retry and a circuit breaker)
One organ's signal fires a reflex arc. The capability bus is the nervous system: … capabilities in a single registry, with the organism_feedback bus carrying events between organs. Cascades run many hops deep: exploit_available wakes risk_spike, which trips drift_detected, then dimension_stale, until decide_and_act closes the loop and the autonomous step seals a leaf in TESTIMONIUM, which comes to as many as six hops from stimulus to proof. MAMY path: modules/organism_feedback.py, scripts/reflex_arc_walk.py, modules/testis/reflex_arc_seal.py
Autonomy is a dial, not a switch. The operator does not pick between manual and fully automatic, but turns a dial across a matrix of risk classes, setting what the system does alone, what needs consent and what stays blocked, and that is deliberate will, exercised under the LEX policy engine and under a policy recorded per target. MAMY path: modules/autonomy_policy.py (AutonomyPolicy), the /organism page
The five rules resolve into one thesis: a single governed loop, running from the hunt to a sealed verdict, with real exploitation, the detection gap closed on the client's own SIEM, a cryptographically sealed proof fit for DORA TLPT, and not one byte leaving the client's walls. Part of that loop already beats; part of it we are still building DOŁOŻYMY, and the full act-by-act picture waits in the Mission ritual chapter. CYRBER tells you to verify rather than take its word, so we hold these docs to the same standard: every rule points at a place in the code, and the MAMY and DOŁOŻYMY markers separate what already runs from what is still being built.
Anatomia
Anatomy
Organizm ma anatomię, którą policzysz na żywo, ponieważ kafle wyżej biją własnym tętnem, obejmując moduły skanujące, zdolności na szynie oraz grupy zdolności, a te trzy rejestry składają się na całość. Pięć filarów niesie kręgosłup rozumowania, dwanaście organów utrzymuje i osądza, a trzy głowy dzielą atak po domenie, przy czym wszystko spina Capability Bus.
Pięć filarów
Filary tworzą kolumnę kręgową, z której każdy trzyma jeden wymiar misji i ma swoje miejsce w kodzie.
Silnik rozumowania. Prowadzi misję przez cykl OBSERVE, THINK, ACT, LEARN i sam wybiera następny ruch. MAMY ścieżka: modules/mind_agent.py
Security Genome. Składa profil obrony w pięciu wymiarach i rysuje radar, po jednym pomiarze na misję. MAMY ścieżka: modules/speculum*.py
Compliance i dowód. Mapuje wynik na NIS2, DORA i GDPR i podpisuje tę pieczęć zgodności kluczem Ed25519, a każdy skan pieczętuje drzewem Merkle z kotwicą OpenTimestamps w łańcuchu Bitcoina. MAMY ścieżka: modules/testis/, modules/compliance_seal.py (Ed25519 na pieczęci compliance)
Silnik prognozy. Liczy risk score i układa oś czasu na 30, 60 i 90 dni. MAMY ścieżka: modules/annales*.py
Cyfrowy bliźniak. Destrukcyjne testy chodzą po bliźniaku, nigdy po produkcji klienta, z sześciogodzinnym cooldownem. MAMY ścieżka: modules/umbra*.py
Dwanaście organów
Organy utrzymują organizm i pilnują osądu, a każdy z nich robi jedną, ściśle wyznaczoną rzecz.
- VIGIL trzyma ciągły monitoring powierzchni.
- MEDICUS proponuje, weryfikuje i w razie potrzeby wycofuje naprawy, a przy okazji odzyskuje uszkodzone usługi.
- CORTEX rozpoznaje wzorce i uczy się z misji.
- AUDIT prowadzi kryptograficzny łańcuch audytu.
- FORUM prowadzi przepływ postulatów i decyzji.
- LEX egzekwuje zakres i politykę.
- AURUM śledzi koszt tokenów LLM i ekspozycję ryzyka biznesowego w euro.
- TESTIS zaświadcza i weryfikuje każdy krok, żeby dowód dało się sprawdzić także później.
- FATUM przewiduje, jak ryzyko rozłoży się w czasie i kiedy exploit stanie się dostępny.
- COMES towarzyszy misji i porządkuje kolejkę.
- LIBER pamięta jako korpus instytucjonalny.
- ITERUM odtwarza i wariantuje przebyte misje.
Cała dwunastka jest obecna i wpięta, trzymana pod naszym rygorem ALIVE. MAMY ścieżka: modules/vigil*.py, modules/cortex.py, modules/lex.py, modules/testis/ i pozostałe; żywotność w GET /api/organism/liveness
Trzy głowy
Głowy dzielą atak według domen, przy czym one same jedynie planują, natomiast nad wykonaniem czuwa już MENS.
Wektor techniczny. Dysponuje ponad setką modułów skanujących i mapuje wynik na CWE oraz OWASP. MAMY ścieżka: modules/ratio/
Wektor ofensywny. Realnie wpięty jest garak, fuzzer bezpieczeństwa modeli LLM, którego dispatch woła trzema ścieżkami, wsparty nocnym baseline. Reszta arsenału, jak evilginx2 czy pineapple, leży w repozytorium bez wpięcia dispatchu, więc nie liczymy jej do MAMY. Nad całością stoi niezmiennik requires_consent=True, więc nic nie ruszy bez zadeklarowanej zgody. MAMY ścieżka: modules/animus/, garak przez trzy ścieżki dispatchu i nocny baseline
Ten sam moduł co organ FATUM, druga perspektywa. Organ przewiduje punktowo, głowa patrzy na czas jako aspekt rozumowania. MAMY ścieżka: modules/fatum.py
Capability Bus
Bus jest fundamentem, a nie kolejnym organem ani filarem, ponieważ stanowi jeden płaski rejestr zdolności, po którym rozmawiają ze sobą filary, organy i głowy. Każda zdolność niesie scope (owner, admin, operator, client), wpis w audit logu, opcjonalną zgodę przez HMAC lub bramkę MFA i udokumentowany pendant defensywny, czyli odpowiednik mówiący, jak SPECULUM albo UMBRA to samo wykrywa lub odzwierciedla. Liczbę zdolności, modułów i grup zobaczysz w kaflach wyżej, liczone na żywo. MAMY ścieżka: modules/capabilities/ (płaska struktura, dekorator @capability)
Kiedy komponent jest żywy
Nasz rygor ALIVE stawia trzy warunki naraz, a samo istnienie pliku nie liczy się do niczego. Po pierwsze producent wywołań w produkcji: realny dispatch albo hook woła kod, a nie tylko import. Po drugie test e2e, który ćwiczy prawdziwą ścieżkę i świeci na zielono w suite. Po trzecie udokumentowany pendant defensywny. Gdy zabraknie choćby jednego i piszemy stan wprost: wired-untested, dormant, unwired, skeleton. To właśnie ten rygor utrzymuje organizm w uczciwości, ponieważ żywotność liczy się co dobę, a milczenie dłuższe niż jedna doba znaczy śmierć. MAMY ścieżka: niezmiennik I-9, GET /api/organism/liveness
The organism has an anatomy you can count live, because the tiles above beat with their own pulse across scan modules, capabilities on the bus and capability groups, and those three registers make up the whole. Five pillars carry the spine of reasoning, twelve organs keep it running and judging, and three heads split the attack by domain, with the Capability Bus wiring them together.
Five pillars
The pillars are the backbone. Each holds one dimension of a mission and has its own place in the code.
The reasoning engine. It runs a mission through OBSERVE, THINK, ACT, LEARN and picks its own next move. MAMY path: modules/mind_agent.py
The Security Genome. It builds a defense profile across five dimensions and draws a radar, one reading per mission. MAMY path: modules/speculum*.py
Compliance and proof. It maps findings onto NIS2, DORA and GDPR and signs that compliance seal with an Ed25519 key, while it seals every scan with a Merkle tree and an OpenTimestamps anchor on the Bitcoin chain. MAMY path: modules/testis/, modules/compliance_seal.py (Ed25519 on the compliance seal)
The forecast engine. It scores risk and lays out a timeline over 30, 60 and 90 days. MAMY path: modules/annales*.py
A digital twin. Destructive tests run against the twin, never against the client's production, with a six-hour cooldown. MAMY path: modules/umbra*.py
Twelve organs
The organs keep the body running and guard its judgment, and each of them does one strictly assigned thing.
- VIGIL watches the surface without pause.
- MEDICUS proposes, verifies and, when needed, rolls back fixes, and recovers broken services along the way.
- CORTEX recognizes patterns and learns from missions.
- AUDIT keeps the cryptographic audit chain.
- FORUM runs the postulate and decision flow.
- LEX enforces scope and policy.
- AURUM tracks LLM token cost and business-risk exposure in EUR.
- TESTIS witnesses and verifies each step, so the proof can be checked later too.
- FATUM predicts how risk unfolds over time and when an exploit becomes available.
- COMES rides with the mission and orders its queue.
- LIBER remembers as an institutional corpus.
- ITERUM replays and varies past missions.
All twelve are present and wired, held to our ALIVE bar. MAMY path: modules/vigil*.py, modules/cortex.py, modules/lex.py, modules/testis/ and the rest; liveness at GET /api/organism/liveness
Three heads
The heads split the attack by domain. They plan; MENS owns the execution.
The technical vector. It dispatches over a hundred scan modules and maps findings onto CWE and OWASP. MAMY path: modules/ratio/
The offensive vector. The wired tool is garak, an LLM security fuzzer whose dispatch fires through three paths, backed by a nightly baseline. The rest of the arsenal, evilginx2 and pineapple among them, sits in the repository with no dispatch wired, so we do not count it as MAMY. The requires_consent=True invariant governs all of it, so nothing fires without declared consent. MAMY path: modules/animus/, garak via three dispatch paths and a nightly baseline
The same module as the FATUM organ, seen from a second angle. The organ predicts point by point; the head treats time as an aspect of reasoning. MAMY path: modules/fatum.py
The Capability Bus
The bus is the foundation, not another organ or pillar. It is a single flat registry of capabilities that pillars, organs and heads all speak through. Every capability carries a scope (owner, admin, operator, client), an audit-log entry, optional consent via HMAC or an MFA gate, and a documented defensive pendant, the counterpart that says how SPECULUM or UMBRA detects or reflects the same thing. The count of capabilities, modules and groups sits in the tiles above, computed live. MAMY path: modules/capabilities/ (flat structure, @capability decorator)
When a component is alive
Our ALIVE bar sets three conditions at once, and a file simply existing counts for nothing. First, a caller in production: a real dispatch or hook invokes the code, not just an import. Second, an e2e test that exercises the real path and stays green in the suite. Third, a documented defensive pendant. Miss any one and we name the state plainly: wired-untested, dormant, unwired, skeleton. This rigor keeps the organism honest. Liveness is counted every day, and silence longer than a day reads as death. MAMY path: invariant I-9, GET /api/organism/liveness
Rytuał misji
Cała praca organizmu układa się w jeden rytuał pięciu aktów. To rdzeń całego CYRBER: jedna rządzona pętla od polowania po zapieczętowany werdykt. Część aktów już bije pełnym tętnem, część dopiero dokładamy, co oznaczamy wprost, akt po akcie.
1 · Puls
Akt czuwania. VIGIL trzyma baseline powierzchni, niezmiennik I-9 liczy żywotność … komponentów, a standing-scan regimen wybija stały rytm. Zanim zacznie się polowanie, organizm już wie, co ma pod ręką i co usnęło. MAMY ścieżka: monitoring VIGIL, GET /api/organism/liveness
2 · Polowanie
Akt rozumowania. MENS iteruje pętlę i dysponuje moduły skanujące głowy RATIO pod prawem LEX, celując w realny dostęp, nie w samą listę podatności. Flotą celów rządzi pokrętło autonomii, a każdy cel niesie własny postulat zakresu. MAMY ścieżka: silnik always-on, fleet-under-LEX (modules/mind_agent.py, modules/lex.py)
3 · Pojedynek
Akt konfrontacji. Głowa ANIMUS uruchamia realną eksploatację, a wynik trafia na własny SIEM klienta, czyli Wazuh stawiany osobno dla każdej organizacji, żeby domknąć luki detekcji. To purple w czystej postaci: atak i obrona uczą się na tym samym zdarzeniu. Domyślnie dowodzimy dostępu, nie skutku, ponieważ sama eksploatacja pokazuje, że łańcuch da się przejść, a ekstrakcję danych włącza dopiero osobny tryb impact, który przechodzi przez pięć bramek naraz, od licencji i polityki LEX po autoryzację klienta oraz zgodę na każdy krok. Wazuh per-org, metryka standing-purple z siedmiu dni oraz domyślny dowód dostępu z bramkowanym trybem impact MAMY. Dwupanelowy widok purple spięty w jeden rytuał DOŁOŻYMY. ścieżka: Wazuh per-org, standing-purple 7d; prove_impact opt-in za pięcioma bramkami (modules/secretsdump_scan.py: tryb, LEX, autoryzacja klienta, leaf TESTIMONIUM, zgoda per krok)
4 · Werdykt
Akt świadectwa. TESTIMONIUM pieczętuje dowód drzewem Merkle oraz kotwicą OpenTimestamps w łańcuchu Bitcoina, a werdykt zmapowany na compliance, podpisany kluczem Ed25519, ląduje w zapieczętowanym PDF. Court-pack szyje to pod fazę purple-close w DORA TLPT, weryfikowalny offline, a living remediation bramkuje realny retest. Łańcuch pieczęci i compliance PDF MAMY. Weryfikator offline już istnieje, ale nie jest jeszcze wpięty w eksport ZIP court-packa, więc samo-weryfikowalny court-pack to DOŁOŻYMY, tak samo jak living remediation. ścieżka: seal chain i compliance PDF; court-pack i living remediation w planie
5 · Pamięć
Akt uczenia. Po misji łańcuch hooków karmi organizm: LIBER indeksuje do korpusu instytucjonalnego, CORTEX mierzy trafność, ANNALES odświeża prognozę, ITERUM przygotowuje replay. Organizm pamięta misję i wraca do niej mądrzejszy. MAMY ścieżka: hook chain filarów po misji (run_hook() w modules/mind_agent.py)
Tych pięć aktów tworzy jedną pętlę, którą sterujesz pokrętłem, którą udowodnisz regulatorowi i która w całości należy do klienta. Suwerenność, czyli on-prem i lokalny model LLM, czyni ją niekopiowalną: nikt z zewnątrz nie odtworzy ani danych, ani przebiegu. Jak działa dowód dla sceptyka, opisuje rozdział Glass House; skąd bierze się nienaruszalność, rozdział Suwerenność. Aspiracje z aktów Pojedynek i Werdykt oznaczamy DOŁOŻYMY, żeby było jasne, co należy do planu, a co już bije.
Mission ritual
Everything the organism does resolves into one ritual of five acts. This is the core of CYRBER: a single governed loop from the hunt to a sealed verdict. Some acts already beat at full pulse; some we are still building, and we say which is which, act by act.
1 · Pulse
The act of watching. VIGIL holds a baseline of the surface, invariant I-9 counts the liveness of … components, and the standing-scan regimen keeps a steady beat. Before the hunt begins, the organism already knows what it has to hand and what has gone quiet. MAMY path: VIGIL monitoring, GET /api/organism/liveness
2 · Hunt
The act of reasoning. MENS iterates its loop and dispatches the RATIO head's scan modules under the LEX policy engine, aiming at real access rather than a bare list of vulnerabilities. The autonomy dial governs the fleet of targets, and each target carries its own scope postulate. MAMY path: always-on engine, fleet-under-LEX (modules/mind_agent.py, modules/lex.py)
3 · Duel
The act of confrontation. The ANIMUS head runs real exploitation, and the result lands on the client's own SIEM, a Wazuh stack stood up separately for each organization, to close the detection gap. This is purple in its pure form: attack and defense learn from the same event. By default we prove access, not impact, because the exploitation itself shows the chain can be walked, while data extraction turns on only through a separate impact mode that passes five gates at once, from the license and the LEX policy to the client's authorisation and consent on every step. Per-org Wazuh, the seven-day standing-purple metric and the default proof-of-access with a gated impact mode are MAMY. A two-panel purple view fused into one ritual is DOŁOŻYMY. path: per-org Wazuh, standing-purple 7d; prove_impact opt-in behind five gates (modules/secretsdump_scan.py: mode, LEX, client authorisation, TESTIMONIUM leaf, per-step consent)
4 · Verdict
The act of witness. TESTIMONIUM seals the proof with a Merkle tree and an OpenTimestamps anchor on the Bitcoin chain, and the compliance-mapped verdict, signed with an Ed25519 key, lands in a sealed PDF. A court-pack tailors this to the purple-close phase of DORA TLPT, verifiable offline, while living remediation is gated on a real retest. The seal chain and compliance PDF are MAMY. The offline verifier already exists but is not yet wired into the court-pack ZIP export, so a self-verifying court-pack is DOŁOŻYMY, as is living remediation. path: seal chain and compliance PDF; court-pack and living remediation planned
5 · Memory
The act of learning. Once a mission closes, the hook chain feeds the organism: LIBER indexes into the institutional corpus, CORTEX measures accuracy, ANNALES refreshes the forecast, ITERUM prepares a replay. The organism remembers the mission and comes back to it wiser. MAMY path: pillar hook chain, post-mission (run_hook() in modules/mind_agent.py)
These five acts are one loop. You steer it with a dial, you can prove it to a regulator, and it belongs to the client in full. Sovereignty, meaning on-prem plus a local LLM, makes it uncopyable: no outsider can reconstruct the data or the run. The Glass House chapter shows how the proof works for a skeptic, and the Sovereignty chapter shows where the tamper-resistance comes from. We mark the aspirations in the Duel and Verdict acts as DOŁOŻYMY, so it stays clear which parts belong to the plan and which already run.
Samoleczenie
Samodoskonalenie w CYRBER dzieje się na trzech poziomach naraz: organizm naprawia własny stan działania, wyciąga wnioski z każdej zamkniętej misji oraz pilnuje, żeby jego własny opis samego siebie pozostawał prawdziwy. Nie kończy więc pracy na samym wykryciu usterki, lecz zauważa ją, naprawia, zapamiętuje płynący z niej wniosek, a tę samą pętlę domyka na dokumentacji, którą właśnie czytasz.
Jak się naprawia
Sam proponuje naprawę na finding, uruchamia retest, żeby potwierdzić, że problem faktycznie zniknął, i wycofuje krok, gdy weryfikacja nie przejdzie. Do tego trzyma rękę na pulsie usług i prowadzi recovery, gdy komponent pada, zanim ktokolwiek zdąży złożyć zgłoszenie. MAMY ścieżka: modules/organism_medicus_plenus.py, modules/medicus_ops.py
Pod spodem bije odruch. Sygnały organizmu są drenowane co sześćdziesiąt sekund, a handlery reagują same: wygaszają pewność, kasują nieaktualny baseline, wołają decide_and_act. MAMY ścieżka: modules/organism_feedback.py, drenaż co 60 s
Kiedy moduł wraca do zdrowia, self-test sam zamyka powiązane z nim zgłoszenie GH. Naprawa i jej ślad domykają się bez ręki człowieka. MAMY ścieżka: modules/module_self_test.py
Jak się uczy
Rozpoznaje wzorce w tym, co organizm już widział, i mierzy trafność własnych prognoz. Każda pomyłka wraca do niego jako korekta. MAMY ścieżka: modules/cortex.py
Zbiera wnioski z zamkniętych misji i domyka pętlę uczenia, żeby następny przebieg startował mądrzejszy. MAMY ścieżka: self-improvement engine nad korpusem misji (modules/self_improvement.py)
Jak leczy się ta dokumentacja
Ta strona podlega tej samej zasadzie. Liczby i statusy, które tu widzisz, nie są przepisane ręcznie, lecz renderują się z żywego API organizmu, dzięki czemu nie zestarzeją się po cichu. Nad samą prozą czuwa strażnik dryfu, ponieważ każde twierdzenie, oznaczone jako MAMY albo DOŁOŻYMY, trzyma kotwicę w konkretnym miejscu kodu, którą sprawdzasz przyciskiem „udowodnij”, a nocny przebieg weryfikuje, czy kod wciąż to twierdzenie potwierdza, i robi to na trzech warstwach: czy pliki, symbole oraz endpointy z kotwicy nadal istnieją, czy liczby zgadzają się z API, a wreszcie czy sam sens twierdzenia trzyma się kodu. Gdy organizm wyprzedzi opis, strażnik sam zakłada zgłoszenie GH z konkretem, tym samym trybem, którym self-test już dziś zamyka zgłoszenia po naprawie, i sam je domyka, gdy proza wróci do prawdy. To Glass House przyłożony do dokumentu: nie każemy Ci wierzyć, że opis pozostaje aktualny, lecz utrzymujemy mechanizm, który tę aktualność wymusza. Żywe fakty z API oraz strażnika dryfu prozy MAMY. ścieżka: żywe fakty z /api/public/organism/facts (data-live); strażnik dryfu modules/docs_drift/ warstwami L0 parity, L1 kotwice, L2 liczby oraz L3 semantyka, nocny docs_drift_guardian_task (beat 02:45 UTC), sink modules/docs_drift/sink.py do forum_postulata i GH, na busie docs.drift_status oraz docs.check_drift
Te trzy poziomy, naprawa stanu, nauka z misji oraz uczciwość własnego opisu, składają się na jedną ideę: system, który nie tylko działa, lecz sam doprowadza się do porządku, a każdy taki krok zostawia ślad, który możesz sprawdzić.
Self-healing
Self-improvement in CYRBER runs on three levels at once: the organism repairs its own running state, draws lessons from every mission that closes, and keeps its own account of itself true. It therefore does not stop at spotting a fault, but notices it, repairs it and keeps the lesson, and then the same loop closes on the documentation you are reading now.
How it repairs itself
Proposes a fix for a finding on its own, runs a retest to confirm the problem actually cleared, and rolls the step back when verification fails. Alongside that it keeps a hand on the pulse of the services and drives recovery when a component falls over, before anyone files a ticket. MAMY path: modules/organism_medicus_plenus.py, modules/medicus_ops.py
A reflex beats underneath. Organism signals drain every sixty seconds, and the handlers react on their own: they decay confidence, wipe a stale baseline, call decide_and_act. MAMY path: modules/organism_feedback.py, 60 s drain
When a module returns to health, the self-test closes the GH issue tied to it. The repair and its trace both close with no human hand. MAMY path: modules/module_self_test.py
How it learns
Recognises patterns in what the organism has already seen and measures the accuracy of its own forecasts. Every miss comes back to it as a correction. MAMY path: modules/cortex.py
Gathers the lessons from closed missions and closes the learning loop, so the next run starts wiser. MAMY path: self-improvement engine over the mission corpus (modules/self_improvement.py)
How this documentation heals
This page lives by the same rule. The numbers and statuses you see here are not typed in by hand. They render from the organism's live API, so they cannot age in silence. A drift guard watches the prose itself, because every claim, marked MAMY or DOŁOŻYMY, holds an anchor at a specific place in the code that you check with the "prove it" button, and a nightly run verifies that the code still bears the claim out, across three layers: whether the files, symbols and endpoints from the anchor still exist, whether the numbers match the API, and finally whether the meaning of the claim still holds against the code. When the organism runs ahead of the description, the guard opens a GH issue with the specifics, by the same route the self-test already uses to close issues after a repair, and closes it again once the prose returns to the truth. This is the Glass House turned on a document: we do not ask you to trust that the description is current; we run a mechanism that forces it to be. Live facts from the API and the prose drift guard are MAMY. path: live facts from /api/public/organism/facts (data-live); drift guard modules/docs_drift/ in layers L0 parity, L1 anchors, L2 numbers and L3 semantics, nightly docs_drift_guardian_task (beat 02:45 UTC), sink modules/docs_drift/sink.py to forum_postulata and GH, on the bus docs.drift_status and docs.check_drift
These three levels, repairing the state, learning from missions and keeping its own account honest, make one idea: a system that does not merely run but keeps setting itself right, and every such step leaves a trace you can check.
Glass House
Każdy dostawca prosi o zaufanie, natomiast CYRBER kładzie na stół dowód, który sprawdzisz samodzielnie, bez najmniejszego wglądu w jego bazę.
Pieczęć
Każdy finding trafia pod hash SHA-256, po czym hashe łączą się parami w drzewo Merkle, a ponieważ zmiana choćby jednego znaku w jednym findingu rozsypuje root tego drzewa, każda podmiana zostaje natychmiast widoczna. Każdy liść nosi przy tym podpis HMAC naszego serwera, a wiarygodność samego roota bierze się z kotwicy opisanej niżej, nie z naszego słowa. MAMY ścieżka: modules/testis/ seal, backend/proof.py hash_finding SHA-256 + sign_leaf HMAC-SHA256 + build_merkle_tree
Kotwica
Root skanów z danego dnia kotwiczymy w bloku łańcucha Bitcoina przez OpenTimestamps. Żeby przepisać historię, trzeba by przepisać bloki, a tego nikt nie zrobi po cichu. MAMY ścieżka: kotwica OpenTimestamps na dziennym root (modules/opentimestamps.py)
Weryfikacja bez zaufania
Audytor bierze finding, przelicza jego hash i przechodzi ścieżkę Merkle aż do roota, co kosztuje go O(log N) kroków, a nie kopię całej bazy, natomiast klucz weryfikujący dostaje offline w nagłówku X-Proof-Key, dzięki czemu dowód broni się nawet wtedy, gdy nasz serwer pozostaje niedostępny. MAMY ścieżka: rekomputacja hash + merkle path, X-Proof-Key offline (backend/proof.py verify_leaf)
Łańcuch pieczęci
Seal chain trzyma pieczęcie kolejnych misji, jedna za drugą. Liczba pieczęci rośnie z każdą zamkniętą misją: …. MAMY ścieżka: łańcuch pieczęci w tabeli testimonium_trees (modules/testimonium.py), liczba na żywo z /api/public/organism/facts (seals_total)
Court-pack
Court-pack szyje w jedną paczkę pieczęcie, zamknięte reguły detekcji i dowód realnego dostępu, ułożone pod fazę purple-close w DORA TLPT. Weryfikator cyrber-verify.py już istnieje i sprawdza dowód offline, ale nie jest jeszcze wpięty w eksport ZIP, więc samo-weryfikowalny court-pack dopinamy. DOŁOŻYMY ścieżka: cyrber-verify.py istnieje, brak wpięcia w eksport ZIP
Stąd bierze się zasada, którą trzymamy tu i w produkcie: masz sprawdzić werdykt, a nie zawierzyć mu. To decyzja architektoniczna, która przesądziła, jak wygląda każda pieczęć. Skąd bierze się nienaruszalność u klienta, mówi rozdział Suwerenność.
Glass House
Every vendor asks for trust. CYRBER puts a proof on the table that you can check without looking into its database.
The seal
Every finding goes under a SHA-256 hash. The hashes join in pairs into a Merkle tree. Change one character in one finding and the tree's root falls apart, so tampering stays visible. Each leaf carries an HMAC signature from our server, and the root's credibility comes from the anchor described below, not from our word. MAMY path: modules/testis/ seal, backend/proof.py hash_finding SHA-256 + sign_leaf HMAC-SHA256 + build_merkle_tree
The anchor
We anchor the root of a day's scans into a Bitcoin block through OpenTimestamps. To rewrite history, you would have to rewrite the blocks, and nobody does that quietly. MAMY path: OpenTimestamps anchor on the daily root (modules/opentimestamps.py)
Verification without trust
An auditor takes a finding, recomputes its hash and walks the Merkle path to the root. It costs them O(log N) steps, not a copy of the database. The verifying key arrives offline in the X-Proof-Key header, so the proof holds even when our server is unreachable. MAMY path: hash recompute + merkle path, X-Proof-Key offline (backend/proof.py verify_leaf)
The seal chain
The seal chain holds the seals of successive missions, one after another. The count grows with every mission that closes: …. MAMY path: seal chain in the testimonium_trees table (modules/testimonium.py), count live from /api/public/organism/facts (seals_total)
The court-pack
A court-pack sews the seals, the closed detection rules and the real-access proof into one bundle, laid out for the purple-close phase of DORA TLPT. The verifier cyrber-verify.py already exists and checks the proof offline, but it is not yet wired into the ZIP export, so a self-verifying court-pack is still ours to finish. DOŁOŻYMY path: cyrber-verify.py exists, not wired into ZIP export
This is where the rule we keep here and in the product comes from: verify the verdict, do not trust it. It is an architectural decision that shaped every seal, not a marketing line. Where the tamper-resistance comes from at the client's site is the Sovereignty chapter.
Quick start
Od loginu aż po zapieczętowany raport, bez żadnych rytuałów pośrednich, prowadzą Cię poniższe kroki, które przechodzą przez jedną pełną misję od początku do końca.
1. Zaloguj się
Wejdź na app.cyrber.com jako OPERATOR lub ADMIN. Sesja to ciasteczko HTTP-only, ważne cztery godziny; po wygaśnięciu logujesz się ponownie, token nie leży w localStorage.
2. Dodaj zasięg
Na stronie /lex ustaw politykę LEX dla celu: zakres CIDR, tryb autonomii (poziom LIBER pozwala systemowi działać samodzielnie w tej klasie ryzyka) i flagę requires_consent dla wyższych tierów, gdzie krok wymaga Twojego podpisu przed wykonaniem. Samo pokrętło autonomii, ile wolności ma organizm, kręcisz na stronie /organism.
3. Odpal misję
W MISJE wybierz Start, podaj politykę i cel. Jeśli krok w planie wymaga wyższego tieru, podpisujesz zgodę (consent signing), zanim MENS ruszy. Po starcie MENS buduje graf ataku i dysponuje moduły skanujące przez kolejki Celery (kolejka scanning).
4. Oglądaj na żywo
W KOKPICIE, w trybie Battle Mode, widzisz aktywną iterację: który moduł pracuje, na jakim celu, licznik znalezionych findingów i EKG, które pulsuje kolorem zależnym od stanu misji.
5. Odbierz raport i pieczęć
Po zamknięciu misji TESTIMONIUM pieczętuje wynik: drzewo Merkle oraz podpis, a stąd eksportujesz raport misji do PDF w języku polskim lub angielskim, natomiast zgodność pobierasz osobno, jako JSON dla NIS2, DORA i GDPR albo jako PDF dla samego NIS2. Pieczęć zweryfikujesz publicznie, bez naszej bazy, na trust.cyrber.com; krok po kroku pokazuje rozdział Public verify.
Quick start
From login to a sealed report, no detours in between. The steps below walk one mission from start to finish.
1. Log in
Go to app.cyrber.com as OPERATOR or ADMIN. The session runs on an HTTP-only cookie, good for four hours; once it expires, you log in again, and the token never touches localStorage.
2. Set the scope
On /lex, write a LEX policy for the target: a CIDR range, an autonomy tier (LIBER lets the system act on its own within that risk class), and a requires_consent flag for the higher tiers, where a step waits for your signature before it fires. The autonomy dial itself, how much latitude the organism gets, lives on /organism.
3. Launch the mission
Under MISSIONS, pick Start, then the policy and the target. If a planned step needs a higher tier, you sign consent before MENS moves. Once launched, MENS builds an attack graph and dispatches scan modules through the Celery queues (the scanning queue).
4. Watch it live
In KOKPIT, Battle Mode shows the running iteration: which module is active, against which target, a running finding count, and a heartbeat trace that shifts color with the mission's state.
5. Collect the report and the seal
Once the mission closes, TESTIMONIUM seals the result with a Merkle tree and a signature, and from there you export the mission report to PDF in Polish or English, while compliance is a separate export, as JSON for NIS2, DORA and GDPR or as PDF for NIS2 alone. You can check the seal yourself, no access to our database needed, at trust.cyrber.com; the Public verify chapter walks through it step by step.
Wdrożenie
CYRBER stawiasz na dwa sposoby i jest to świadomy wybór architektury, a nie przypadek, ponieważ model managed prowadzimy my na własnych serwerach, podczas gdy on-prem stoi w całości u klienta, na jego infrastrukturze i pod jego kontrolą. Ten rozdział mówi wprost, czym oba modele się różnią, co jest gotowe już dziś, a co dokładamy, zanim domkniemy pełny air-gap.
Dwa modele
Managed. Instancję prowadzimy my na infrastrukturze CYRBER, dzięki czemu dostajesz gotowe konto i zaczynasz pracę w kilka minut, bez stawiania własnego serwera, a wiele organizacji dzieli tę samą instancję z twardą izolacją per-org na poziomie bazy danych, tak że dane jednego klienta nigdy nie widzą danych drugiego, i właśnie w tym modelu działa dziś app.cyrber.com. MAMY ścieżka: app.cyrber.com prowadzony przez CYRBER, multi-tenant izolacja per-org (RLS) (modules/rls.py)
On-prem. Cały stos stoi wtedy u klienta, na jego metalu i pod jego licencją, przez co przebieg misji oraz wszystkie dane zostają na jego infrastrukturze, a my nie trzymamy żadnej kopii; jest to model dla tych, którzy potrzebują pełnej suwerenności, i choć rozumowanie zamknięte w murach klienta domykamy dopiero modelem lokalnym, sama zasada pozostaje jednoznaczna. On-prem MAMY, a rozumowanie bez wyjścia na zewnątrz DOŁOŻYMY. ścieżka: licencja on-prem modules/license.py, deployment on-prem; model lokalny air-gap w planie, patrz Suwerenność
Wybór modelu nie zmienia samego produktu, lecz jedynie to, gdzie on stoi i kto trzyma nad nim kontrolę, dlatego reszta rozdziału opisuje już wyłącznie stos, jednakowy w obu wariantach.
Edycje
Produkt jest jeden, a edycje różnią się przede wszystkim tym, jak długo trzymamy dane. Cztery pakiety układają się w drabinę: SPECULATOR trzyma misje przez trzydzieści dni, EXCUBITOR przez dziewięćdziesiąt, HARUSPEX przez rok, a PRAEFECTUS nie kasuje niczego i utrzymuje pełną historię bez końca, przy czym raporty przechowujemy odpowiednio dłużej, kolejno przez dziewięćdziesiąt dni, rok, trzy lata oraz również bez limitu, a wyższą edycję rozpoznasz też po tym, że dopiero na jej szczycie otwiera się tryb impact z ekstrakcją danych za pięcioma bramkami. Świadomie pokazujemy tu jedynie to, co edycja egzekwuje w kodzie, natomiast pełny zakres handlowy każdej z nich ustalasz z nami przy wdrożeniu, ponieważ nie chcemy wpisywać do dokumentacji obietnic, których kod nie potwierdza. Okna retencji per edycja oraz mapowanie licencji na pakiet MAMY. ścieżka: modules/retention.py MISSION/REPORT_RETENTION_DAYS per pakiet (SPECULATOR/EXCUBITOR/HARUSPEX/PRAEFECTUS); backend/routers/license.py _TIER_TO_PACKAGE
Architektura
Rdzeń stanowią FastAPI oraz Celery, osadzone nad PostgreSQL 16 i Redis, a całość ukryta jest za nginx, podczas gdy zadania w tle chodzą czterema izolowanymi kolejkami, z których scanning obsługuje moduły MENS, reporting generuje PDF, intel zasila się ze źródeł KEV, ATT&CK i EPSS, a maintenance pilnuje arsenału, licencji i sprzątania. Ponieważ wszystko składa jeden plik Compose z profilami, ciężkie narzędzia, takie jak Kali, przeglądarka czy garak włączasz jednym profilem, a nie ręcznie. MAMY ścieżka: docker-compose.yml, profile usług, cztery kolejki Celery
Wymagania i tryby
Na start wystarcza pojedynczy węzeł on-prem, na którym stoi Docker, znajduje się dysk na dane i raporty oraz otwarty port dla nginx, a trybem domyślnym jest instalacja u klienta, przy której przebieg misji i dane zostają na jego infrastrukturze. Całość podnosi jeden instalator uruchamiany pojedynczym poleceniem, natomiast obraz przygotowany pod prywatny rejestr, skracający postawienie środowiska całkowicie odciętego do kilku minut, dokładamy osobno. Stos Compose oraz instalator jednego polecenia MAMY, a obraz pod prywatny rejestr DOŁOŻYMY. ścieżka: single-node Compose działa; instalator jednym poleceniem cyrber-install.sh (sudo ./cyrber-install.sh, docs/INSTALL.md); obraz pod prywatny rejestr air-gap w planie
Wymagania sprzętowe
Wymagań sprzętowych nie zgadujemy, ponieważ rdzeń stacku deklaruje w Compose twarde limity zasobów, więc wyprowadzamy je wprost z tego, ile realnie biorą kontenery, a baza, Redis, API, worker Celery, beat oraz most Matrix sumują się w szczycie do około ośmiu gigabajtów pamięci i siedmiu rdzeni, natomiast każdy cięższy profil narzędziowy, taki jak ZAP czy Kali, dokłada do tego kolejne dwa gigabajty i dwa rdzenie. Poniżej opisujemy trzy poziomy, prowadzące od progu, na którym system w ogóle ruszy, aż po konfigurację, na której chodzi idealnie, przy czym pod samym poziomem minimalnym leży jeszcze niższy próg absolutny rzędu sześćdziesięciu gigabajtów dysku, którego instalator pilnuje i poniżej którego odmawia startu, lecz trzymamy go wyłącznie na ewaluację, a nie na realną pracę. MAMY ścieżka: limity mem_limit/cpus rdzenia w docker-compose.yml; próg dysku hard-fail 60 GB / warn 100 GB w cyrber-install.sh
Jest to próg, na którym system startuje z zapasem nad limitami kontenerów, ponieważ zakłada rozumowanie w chmurze bez GPU, skany prowadzone sekwencyjnie oraz niewielki zespół operatorów, lecz nie zostawia jeszcze pola na wiele misji naraz ani na pełny arsenał narzędzi.
To poziom, na którym stawiamy większość instalacji on-prem, ponieważ udźwignie kilka misji prowadzonych równolegle oraz włączone profile narzędzi, takie jak ZAP, Kali i przeglądarka, zapewniając operatorowi komfortową, płynną pracę.
Jest to konfiguracja, na której system chodzi idealnie, ponieważ udźwignie pełny arsenał, dużą flotę celów oraz lokalny model rozumowania w trybie air-gap uruchomiony na tej właśnie karcie, dzięki czemu ani jeden token nie wychodzi na zewnątrz, przy czym sam lokalny model na GPU dopiero DOŁOŻYMY. ścieżka: profil ollama w compose (GPU, air-gap), domyślnie chmura
Do zasobów obliczeniowych dochodzą zasoby dyskowe, ponieważ organizm z czasem rośnie i uczy się na własnej historii, a na dysku odkładają się dane PostgreSQL, wygenerowane raporty PDF, artefakty skanów, łańcuch pieczęci oraz korpus instytucjonalny z osadzeniami, z których CORTEX i LIBER czerpią przy kolejnych misjach, dlatego dysk traktuj jako zasób rosnący, a nie stały, i przewiduj zapas ponad wartości podane w powyższych poziomach. MAMY ścieżka: dane PostgreSQL, raporty PDF, seal chain, korpus LIBER oraz finding_embeddings
Zupełnie osobną, a przy tym jedną z najmocniejszych możliwości systemu jest UMBRA, czyli cyfrowy bliźniak, ponieważ pozwala odtworzyć całe środowisko klienta, wraz z Active Directory i siecią, a następnie prowadzić na nim testy destrukcyjne, których nigdy nie puścilibyśmy na produkcję, dzięki czemu sprawdzasz najgorszy scenariusz w pełnej skali, nie narażając ani jednego żywego systemu. Bliźniak, którego mamy dziś, to precyzyjny blueprint środowiska wraz z migawkami ryzyka, więc na dysku waży tyle, ile metadane, czyli rzędy megabajtów na organizację, i nie rezerwuje pod siebie osobnych maszyn, natomiast realny koszt w rdzeniach, pamięci oraz dysku pojawia się dopiero wtedy, gdy z tego blueprintu stawiamy pełną, działającą umbrę, której zapotrzebowanie skaluje się wprost z liczbą odwzorowanych hostów, tak że pełnowartościowa umbra całego środowiska potrzebuje własnej, oddzielnej puli zasobów, dobranej do skali celu i do budżetu, na jaki klient jest gotów. Samego bliźniaka z cooldownem MAMY, natomiast automatyczne stawianie pełnowartościowej umbry pod skalę całego środowiska DOŁOŻYMY. ścieżka: modules/umbra*.py, digital twin z cooldownem 6h; pełny twin per-środowisko w planie
Jeśli nie chcesz stawiać sprzętu samodzielnie, przygotowujemy gotowy appliance CYRBER, czyli maszynę z zainstalowanym i zestrojonym systemem, którą wystarczy wpiąć w sieć, aby ruszyć bez własnej roboty infrastrukturalnej. DOŁOŻYMY ścieżka: appliance sprzętowy w planie oferty
Retencja i dane do uczenia
Wzrost dysku nie jest nieokreślony, ponieważ część danych porządkuje w tle retencja: telemetria pulsu znika po sześćdziesięciu dniach, misje wędrują do archiwum po oknie właściwym dla pakietu, wynoszącym trzydzieści dni w SPECULATOR, dziewięćdziesiąt w EXCUBITOR oraz trzysta sześćdziesiąt pięć w HARUSPEX, a raporty trzymamy odpowiednio dłużej, przy czym pakiet PRAEFECTUS nie kasuje niczego i zachowuje pełną historię bez końca. MAMY ścieżka: MISSION_RETENTION_DAYS/REPORT_RETENTION_DAYS w modules/retention.py; pulse 60 dni w modules/data_hygiene.py
Retencja świadomie omija jedno, mianowicie substrat, na którym organizm się uczy, ponieważ genom bezpieczeństwa wraz z migawkami i trendem, osadzenia findingów oraz korpus instytucjonalny LIBER razem ze wzorcami CORTEX nie podlegają żadnemu czyszczeniu, tak że nawet kiedy usuwamy surowe misje, pamięć wyprowadzona z ich przebiegu zostaje, a to właśnie ona sprawia, że system z każdym miesiącem sądzi trafniej. Ma to jednak swoją konsekwencję dla dysku, gdyż ta warstwa rośnie bez górnej granicy i to ją, a nie chwilowe artefakty skanów, trzeba planować na lata, dlatego przy instalacji na dłuższą metę dokładaj zapas dysku ponad wartości z poziomów sprzętowych. MAMY ścieżka: genome_history, genome_snapshots, finding_embeddings, mens_threads (LIBER), wzorce CORTEX; brak prune w repo
Instalacja krok po kroku
Najkrótsza droga to jedno polecenie, ponieważ instalator sprawdza wymagania systemu, w razie potrzeby dokłada Dockera, generuje wszystkie sekrety oraz plik .env, wystawia certyfikat TLS, zakłada rolę bazy pod izolację RLS, podnosi stos, migruje schemat Alembikiem do wersji head, czeka na zdrowe API, a na końcu wypisuje adres panelu wraz z odciskiem maszyny do aktywacji licencji. Ścieżkę ręczną, czyli klon repozytorium, wypełnienie .env (baza, Redis, sekret JWT o długości co najmniej trzydziestu dwóch znaków oraz klucz szyfrujący kolumny), postawienie stosu i migracje, zostawiamy dla tych, którzy wolą prowadzić każdy krok samodzielnie, przy czym po jednej i drugiej drodze zakładasz konto administratora, włączasz MFA i od tego momentu logujesz się już wyłącznie ciasteczkiem HTTP-only. MAMY ścieżka: cyrber-install.sh (sudo ./cyrber-install.sh): check_requirements, configure_env plus sekrety, ensure_ssl_certs, setup_db_roles (RLS), run_migrations do head, health_check; ścieżka ręczna: alembic/versions 0001 do head, docker-compose.yml, cookie-auth + MFA
Kreator pierwszego uruchomienia
Po postawieniu stosu nie zostajesz przed pustym panelem, ponieważ pierwsze logowanie prowadzi kreator wdrożenia, który w pięciu krokach doprowadza cię od świeżej instalacji do pierwszej misji. Zaczynasz od profilu sektora, gdzie wybór instytucji, na przykład samorząd, finanse, przemysł albo zdrowie, ustawia rozsądne wartości domyślne pakietu, polityki oraz macierzy autonomii, następnie zakładasz organizację wraz z jej trybem połączenia, podłączonym, planowym albo całkowicie odciętym, po czym podajesz zakres celu jako adresy CIDR oraz domeny, na tej podstawie kreator zapisuje politykę LEX z oknami czasowymi i progami zgody, a na końcu odpala pierwszą misję MENS i przenosi cię prosto na jej podgląd. MAMY ścieżka: static/setup_wizard.html + backend/routers/pages.py (/setup); kroki wołają GET /api/deployment-profiles, POST /api/organizations, POST /api/lex/policies plus autonomy-matrix, POST /api/mens/missions
Model rozumowania
Domyślnie rozumowanie kierujemy do chmury łańcuchem zapasowym, w którym Mistral pełni rolę głównego dostawcy, a za nim ustawiają się kolejno Claude, OpenAI oraz DeepSeek, przy czym zanim jakikolwiek prompt trafi do chmurowego modelu, maskujemy w nim publiczne adresy IP oraz nazwy hostów deterministycznym hashem liczonym osobno dla każdej misji, więc model rozumuje nad strukturą, nie widząc realnych adresów, a prywatne zakresy testowe zostawiamy nietknięte. Taki układ działa już dziś, podczas gdy lokalny model zamknięty w murach klienta, czyli Ollama na serwerze GPU, jest wprawdzie przygotowany w kodzie, lecz prąd jeszcze przez niego nie płynie, dlatego przełączenie na tryb lokalny domykamy, zanim uruchomisz CYRBER produkcyjnie u siebie. Chmurę z maskowaniem adresów przed wysyłką MAMY, a model lokalny w trybie air-gap DOŁOŻYMY. ścieżka: llm_router.py łańcuch fallback; maskowanie IP/hostname przed LLM w modules/masking.py (SHA-256 per misja), wołane w mind_agent.py; Ollama Stage 2 na GPU
Stąd bierze się też wymóg karty o co najmniej dwudziestu czterech gigabajtach pamięci, ponieważ model, który zamykamy w murach klienta, należy do klasy od kilku do kilkunastu miliardów parametrów, czyli Mistral rzędu siedmiu miliardów do rozumowania oraz Qwen czternastu miliardów do zadań badawczych, a w wersji skwantyzowanej jeden taki model wraz z kontekstem mieści się właśnie w dwudziestu czterech gigabajtach, natomiast gdy chcesz trzymać oba załadowane równolegle, wygodną pracę daje dopiero około czterdziestu ośmiu gigabajtów, czyli para kart klasy RTX 6000 Ada. DOŁOŻYMY ścieżka: OLLAMA_MODEL=mistral + DEERFLOW_MODEL=qwen2.5:14b, OLLAMA_MAX_LOADED_MODELS=2; docs/deploy/ollama_activation.md (≥24 GB na model, ~48 GB / 2× RTX 6000 Ada na dwa)
Sieć i egress
Od strony sieci obraz jest przejrzysty, ponieważ do środka prowadzi jedynie nginx, przez który wchodzi ruch HTTPS operatorów, i żaden inny port nie musi być wystawiony na świat, natomiast na zewnątrz domyślna konfiguracja sięga dokładnie do czterech miejsc, które nazywamy wprost, bo to od nich zależy cała rozmowa o air-gapie: rozumowanie kierujemy do chmurowego dostawcy LLM, Intel Sync pobiera kanały zagrożeń z CISA KEV, MITRE ATT&CK, FIRST EPSS oraz NVD, most Matrix wysyła alerty na serwer domowy, a pieczęć TESTIMONIUM wysyła sam root_hash do publicznych serwerów kalendarza OpenTimestamps po kotwicę czasową w łańcuchu Bitcoin. MAMY ścieżka: nginx inbound; egress llm_router.py + Intel Sync feeds (CISA/MITRE/FIRST/NVD) + most Matrix + OTS modules/opentimestamps.py (OTS_ENABLED default true), wołany w testimonium_builder.py
Każde z tych czterech wyjść daje się domknąć, a suwerenność polega właśnie na ich świadomym odcięciu, ponieważ rozumowanie zamykasz w murach klienta lokalnym modelem na GPU, i to jedyny element, który do pełnego air-gapu jeszcze dokładamy, podczas gdy Intel Sync zastępujesz pakietem wywiadu offline, eksportowanym z instancji podłączonej i wgrywanym do odciętej, most Matrix albo wyłączasz jednym przełącznikiem, albo kierujesz na własny serwer domowy klienta, a kotwicę OpenTimestamps zdejmujesz jednym przełącznikiem, po którym pieczęć wciąż domyka się drzewem Merkle oraz podpisem HMAC na każdym liściu, tracąc jedynie publiczne zakotwiczenie w łańcuchu Bitcoin, przy czym wszystkie te trzy odcięcia działają już dziś. Odcięcie wywiadu, mostu oraz kotwicy OpenTimestamps MAMY, a odcięcie rozumowania lokalnym modelem DOŁOŻYMY. ścieżka: modules/intel_package.py pakiet offline; MATRIX_ENABLED/MATRIX_BRIDGE_ENABLED; OTS_ENABLED=false zdejmuje kotwicę, pieczęć zostaje Merkle + HMAC na liściu (backend/proof.py); model lokalny Ollama air-gap w planie
Kopia i odtwarzanie
Kopia zapasowa to zrzut PostgreSQL szyfrowany GPG, zamknięty w trybie fail-close, w którym pozbawiony klucza skrypt produkcyjny raczej przerwie pracę, niż zapisze jawny plik na dysku, a do tego dochodzi retencja domyślnie trzydziestodniowa oraz odcisk migracji, który przy odtwarzaniu pilnuje parytetu wersji, więc kiedy wepniesz całość zwykłym cronem, możesz spać spokojnie. MAMY ścieżka: scripts/backup.sh, pg_dump + GPG fail-close + retencja 30 dni
Sam pakiet to jednak więcej niż baza, ponieważ obok zrzutu PostgreSQL zamykamy w nim także wygenerowane raporty oraz odcisk wersji migracji, a na życzenie również plik konfiguracyjny z kluczem szyfrującym kolumny, bez którego odtworzenie bazy nie miałoby sensu, i tak złożony pakiet domyślnie ląduje na dysku węzła, natomiast gdy wskażesz zdalny magazyn, kopiuje się dodatkowo poza serwer, przy czym w modelu on-prem to miejsce pozostaje w pełni pod kontrolą klienta. MAMY ścieżka: scripts/backup.sh bundle DB + raporty + fingerprint + opcjonalny .env; offsite rclone przez CYRBER_BACKUP_OFFSITE_REMOTE
Rytm kopii ustawiasz własnym cronem, a my zalecamy przebieg nocny, przez co punkt odtworzenia, czyli ile danych najwyżej stracisz przy awarii, równa się odstępowi między kopiami i w wariancie dobowym wynosi co najwyżej jeden dzień, natomiast świeżości ostatniej kopii pilnuje osobny sprawdzian zdrowia, a jej odtwarzalność potwierdza skrypt testu odtworzenia, tak że kopia nie jest kwestią wiary, lecz czymś realnie sprawdzonym. Kopię, monitoring jej świeżości oraz test odtworzenia MAMY, a ciągłą archiwizację skracającą punkt odtworzenia poniżej doby DOŁOŻYMY. ścieżka: cron kliencki nocny (rekomendacja 03:00 UTC); _check_backup_status health; scripts/backup_restore_test.sh; brak WAL/PITR w repo
Wysoka dostępność
O odporności mówimy wprost, ponieważ dziś stawiamy CYRBER na pojedynczym węźle, a to, co chroni go w codziennej pracy, działa wewnątrz tego węzła, gdyż kontenery pod nadzorem wstają po zawieszeniu, osobne zadania w tle wykrywają i podnoszą utknięte misje oraz cofają nieudane naprawy, tak że pojedyncza usługa, która się potknie, wraca do formy bez udziału operatora. Samoleczenie w obrębie węzła MAMY. ścieżka: restart-unhealthy kontenerów, stuck_missions_recovery_task, organism_metabolism_self_heal, MEDICUS rollback
Nie udajemy natomiast prawdziwej wysokiej dostępności, ponieważ utrata całego węzła nie przełącza dziś ruchu na zapasowy samoczynnie, lecz sprowadza się do odtworzenia z kopii na nowym sprzęcie, którego czas zależy od rozmiaru bazy, dlatego gorący standby bazy, automatyczny failover oraz układ pozbawiony pojedynczego punktu awarii traktujemy jako osobny, świadomie nazwany etap. Odtworzenie po utracie węzła MAMY, a gorący standby z automatycznym przełączeniem DOŁOŻYMY. ścieżka: brak replikacji/standby/failover w docker-compose.yml; ścieżka ratunku = scripts/backup_restore_test.sh
Izolacja i hardening
Wiele organizacji utrzymywanych na jednej instancji rozdziela izolacja per-org na poziomie bazy danych, wejście chroni ciasteczko HTTP-only wsparte MFA/TOTP oraz SSO/OIDC, a każde wywołanie zdolności ląduje w łańcuchu audytu, natomiast formalny przewodnik hardeningu, spięty w jeden dokument, dopiero dokładamy. Izolację i audyt MAMY, a spójny przewodnik hardeningu DOŁOŻYMY. ścieżka: multi-tenant izolacja per-org, cookie + MFA + SSO/OIDC, łańcuch audytu zdolności
Postawienie maszyny to dopiero połowa drogi, ponieważ codzienna praca rządzi się własnymi prawami, a to, jak prowadzić misje, czytać werdykt i eksportować dowód, opisuje rozdział Obsługa.
Deployment
You stand CYRBER up in two ways, and it is a deliberate choice, not an accident. We run the managed model on our own servers, while on-prem stands entirely at the client. This chapter says plainly how they differ, what is ready today and what we will add before a full air-gap.
Two models
Managed. We run the instance on CYRBER infrastructure; you get an account and start in a few minutes, with no server of your own. Many organizations share one instance with hard per-org isolation at the database level, so one client's data never sees another's. This is how app.cyrber.com runs today. MAMY path: app.cyrber.com run by CYRBER, multi-tenant per-org isolation (RLS) (modules/rls.py)
On-prem. The whole stack stands at the client, on their metal, under their license. The mission run and the data stay on their infrastructure, we keep no copy. This is the model for full sovereignty; we close the reasoning inside the client's walls only once a local model lands. On-prem is MAMY, reasoning with no path outside is DOŁOŻYMY. path: on-prem license modules/license.py, on-prem deployment; local air-gap model planned, see Sovereignty
The choice does not change the product; it changes where it stands and who holds it. The rest of this chapter describes the stack itself, identical in both models.
Editions
The product is one; the editions differ mainly in how long we keep the data. Four packages form a ladder: SPECULATOR holds missions for thirty days, EXCUBITOR for ninety, HARUSPEX for a year, and PRAEFECTUS deletes nothing and keeps the full history without end, with reports kept correspondingly longer, ninety days, a year, three years and again without limit, and you also recognize a higher edition by the fact that only at its top does the impact mode open, with data extraction behind five gates. We deliberately show here only what an edition enforces in the code, while you agree the full commercial scope of each with us at deployment, because we do not want to write promises into the documentation that the code does not bear out. The retention windows per edition and the license-to-package mapping are MAMY. path: modules/retention.py MISSION/REPORT_RETENTION_DAYS per package (SPECULATOR/EXCUBITOR/HARUSPEX/PRAEFECTUS); backend/routers/license.py _TIER_TO_PACKAGE
Architecture
The core is FastAPI and Celery over PostgreSQL 16 and Redis, behind nginx. Background work runs on four isolated queues: scanning for the MENS modules, reporting for PDFs, intel for the KEV, ATT&CK and EPSS feeds, and maintenance for the arsenal, licensing and cleanup. One Compose file with profiles assembles the whole thing, so heavy tools like Kali, the browser or garak come up by profile, not by hand. MAMY path: docker-compose.yml, service profiles, four Celery queues
Requirements and modes
One on-prem node is enough to start: Docker, disk for data and reports, a port for nginx. The default mode is an install at the client, the mission run and the data stay on their infrastructure. A single installer brings the whole thing up with one command, while an image built for a private registry, which cuts standing up a fully severed environment down to minutes, we add separately. The Compose stack and the one-command installer are MAMY, the private-registry image is DOŁOŻYMY. path: single-node Compose works; one-command installer cyrber-install.sh (sudo ./cyrber-install.sh, docs/INSTALL.md); private-registry air-gap image planned
Hardware requirements
We do not guess the hardware, because the core stack declares hard resource limits in Compose, so we derive the sizing straight from what the containers actually take, and the database, Redis, the API, the Celery worker, beat and the Matrix bridge add up at peak to roughly eight gigabytes of memory and seven cores, while each heavier tool profile, such as ZAP or Kali, adds another two gigabytes and two cores. Below we describe three levels, leading from the threshold where the system runs at all to the configuration where it runs ideally, and below the minimum level itself sits an even lower absolute floor, around sixty gigabytes of disk, which the installer enforces and below which it refuses to start, though we keep it for evaluation only, not for real work. MAMY path: core mem_limit/cpus in docker-compose.yml; disk floor hard-fail 60 GB / warn 100 GB in cyrber-install.sh
This is the threshold where the system starts with headroom over the container limits, because it assumes cloud reasoning with no GPU, scans run sequentially and a small operator team, yet it leaves no room for many missions at once or the full tool arsenal.
This is the level on which we stand most on-prem installs, because it carries several missions in parallel and the tool profiles turned on, such as ZAP, Kali and the browser, giving the operator comfortable, smooth work.
This is the configuration where the system runs ideally, because it carries the full arsenal, a large fleet of targets and a local reasoning model in air-gap mode running on that very card, so not one token leaves, though the local model on the GPU itself is still DOŁOŻYMY. path: ollama profile in compose (GPU, air-gap), cloud by default
On top of the compute come the disk resources, because the organism grows over time and learns from its own history, and the disk accumulates PostgreSQL data, generated PDF reports, scan artifacts, the seal chain and the institutional corpus with embeddings that CORTEX and LIBER draw on across later missions, so treat the disk as a growing resource rather than a fixed one and plan headroom above the figures in the levels above. MAMY path: PostgreSQL data, PDF reports, seal chain, LIBER corpus and finding_embeddings
A wholly separate matter, and one of the system's most powerful capabilities, is UMBRA, the digital twin, because it lets you reconstruct the client's entire environment, Active Directory and network included, and then run destructive tests on it that we would never unleash on production, so you probe the worst case at full scale without exposing a single live system. The twin we have today is a precise blueprint of the environment together with risk snapshots, so on disk it weighs what metadata weighs, on the order of megabytes per organization, and it reserves no separate machines of its own, while the real cost in cores, memory and disk appears only when we stand a full, running umbra up from that blueprint, whose footprint scales directly with the number of mirrored hosts, so a full-value umbra of a whole environment needs its own separate pool of resources, matched to the scale of the target and to the budget the client is prepared to commit. The twin with its cooldown is MAMY, while standing up a full-value umbra automatically at the scale of a whole environment is DOŁOŻYMY. path: modules/umbra*.py, digital twin with a 6h cooldown; full twin per environment planned
If you would rather not stand up the hardware yourself, we are preparing a ready-made CYRBER appliance, a machine with the system installed and tuned, which you only plug into the network to start, with no infrastructure work of your own. DOŁOŻYMY path: hardware appliance planned as an offering
Retention and the learning data
Disk growth is not open-ended, because retention orders part of the data in the background: pulse telemetry is gone after sixty days, missions move to the archive after the window that fits the package, thirty days on SPECULATOR, ninety on EXCUBITOR and three hundred and sixty-five on HARUSPEX, and reports are kept correspondingly longer, while the PRAEFECTUS package deletes nothing and keeps the full history without end. MAMY path: MISSION_RETENTION_DAYS/REPORT_RETENTION_DAYS in modules/retention.py; pulse 60 days in modules/data_hygiene.py
Retention deliberately spares one thing, the substrate the organism learns on, because the security genome with its snapshots and trend, the finding embeddings and the LIBER institutional corpus together with the CORTEX patterns are subject to no cleanup, so even when we delete the raw missions, the memory drawn from their run stays, and it is that memory which makes the system judge more accurately each month. This does carry a consequence for disk, since this layer grows with no upper bound, and it is this layer, not the transient scan artifacts, that you plan for over the years, so for a long-lived install add disk headroom above the figures in the hardware levels. MAMY path: genome_history, genome_snapshots, finding_embeddings, mens_threads (LIBER), CORTEX patterns; no prune in repo
Install, step by step
The shortest path is one command, because the installer checks the system requirements, adds Docker if it is missing, generates every secret and the .env file, issues a TLS certificate, sets up the database role for RLS isolation, brings the stack up, migrates the schema with Alembic to head, waits for a healthy API, and finally prints the panel address together with the machine fingerprint for license activation. The manual path, cloning the repo, filling in .env (database, Redis, a JWT secret of at least thirty-two characters, the column encryption key), bringing the stack up and running migrations, we leave for those who prefer to drive every step themselves, and down either path you create an admin account, turn on MFA and from there log in with an HTTP-only cookie and nothing else. MAMY path: cyrber-install.sh (sudo ./cyrber-install.sh): check_requirements, configure_env plus secrets, ensure_ssl_certs, setup_db_roles (RLS), run_migrations to head, health_check; manual path: alembic/versions 0001 to head, docker-compose.yml, cookie-auth + MFA
First-run wizard
Once the stack is up you are not left staring at an empty panel, because the first login runs a deployment wizard that walks you in five steps from a fresh install to the first mission. You start with the sector profile, where the choice of institution, local government, finance, industry or health for instance, sets sensible defaults for the package, the policy and the autonomy matrix, then you create the organization together with its connection mode, connected, scheduled or fully severed, after which you give the target scope as CIDR addresses and domains, on that basis the wizard writes a LEX policy with time windows and consent thresholds, and finally it launches the first MENS mission and takes you straight to its view. MAMY path: static/setup_wizard.html + backend/routers/pages.py (/setup); steps call GET /api/deployment-profiles, POST /api/organizations, POST /api/lex/policies plus autonomy-matrix, POST /api/mens/missions
The reasoning model
By default the reasoning goes to the cloud with a fallback chain: Mistral as primary, then Claude, OpenAI and DeepSeek. Before any prompt reaches the cloud model, though, we mask the public IP addresses and hostnames inside it with a deterministic hash computed per mission, so the model reasons over the structure without ever seeing the real addresses, while private test ranges are left untouched. That works today. A local model inside the client's walls, Ollama on a GPU server, is prepared in the code, but the current is not flowing yet; the cutover to local lands before you run CYRBER in production on your own site. The cloud with address masking before send is MAMY, the local air-gap model is DOŁOŻYMY. path: llm_router.py fallback chain; IP/hostname masking before the LLM in modules/masking.py (SHA-256 per mission), called in mind_agent.py; Ollama Stage 2 on GPU
This is also where the requirement of a card with at least twenty-four gigabytes of memory comes from, because the model we shut inside the client's walls sits in the class of a few to a few tens of billions of parameters, meaning a Mistral around seven billion for reasoning and a Qwen of fourteen billion for research tasks, and when quantized, one such model together with its context fits exactly in twenty-four gigabytes, while if you want to keep both loaded in parallel, comfortable work starts only around forty-eight gigabytes, that is, a pair of RTX 6000 Ada-class cards. DOŁOŻYMY path: OLLAMA_MODEL=mistral + DEERFLOW_MODEL=qwen2.5:14b, OLLAMA_MAX_LOADED_MODELS=2; docs/deploy/ollama_activation.md (≥24 GB per model, ~48 GB / 2× RTX 6000 Ada for two)
Network and egress
On the network side the picture is clean, because the only way in is nginx, through which the operators' HTTPS traffic enters, and no other port has to face the world, while outbound the default configuration reaches exactly four places, which we name plainly, because the whole air-gap conversation turns on them: the reasoning goes to a cloud LLM provider, Intel Sync pulls threat feeds from CISA KEV, MITRE ATT&CK, FIRST EPSS and NVD, the Matrix bridge sends alerts to a home server, and the TESTIMONIUM seal sends the bare root_hash to the public OpenTimestamps calendar servers for a timestamp anchor on the Bitcoin chain. MAMY path: nginx inbound; egress llm_router.py + Intel Sync feeds (CISA/MITRE/FIRST/NVD) + Matrix bridge + OTS modules/opentimestamps.py (OTS_ENABLED default true), called in testimonium_builder.py
Each of these four exits can be closed, and sovereignty is exactly this deliberate severing, because you shut the reasoning inside the client's walls with a local model on the GPU, and that is the only element still outstanding for a full air-gap, while you replace Intel Sync with an offline intelligence package exported from a connected instance and imported into the severed one, you either turn the Matrix bridge off with a single switch or point it at the client's own home server, and you drop the OpenTimestamps anchor the same way, after which the seal still closes over its Merkle tree and the per-leaf HMAC signature, losing only the public Bitcoin anchoring, all three of which work today. Severing the intelligence, the bridge and the OpenTimestamps anchor is MAMY, severing the reasoning with a local model is DOŁOŻYMY. path: modules/intel_package.py offline bundle; MATRIX_ENABLED/MATRIX_BRIDGE_ENABLED; OTS_ENABLED=false drops the anchor, the seal stays Merkle + per-leaf HMAC (backend/proof.py); local Ollama air-gap planned
Backup and restore
The backup is a PostgreSQL dump encrypted with GPG and fail-close (with no key in production the script refuses to write a plaintext file), and it comes with a default thirty-day retention and a migration fingerprint for restore parity. You wire it to cron and sleep soundly. MAMY path: scripts/backup.sh, pg_dump + GPG fail-close + 30-day retention
The bundle is more than the database, because alongside the PostgreSQL dump we seal in the generated reports and the migration-version fingerprint, and on request the configuration file with the column encryption key, without which restoring the database would be pointless, and the bundle so assembled lands by default on the node's disk, while if you name a remote store it is additionally copied off the server, and in the on-prem model that location stays entirely under the client's control. MAMY path: scripts/backup.sh bundle DB + reports + fingerprint + optional .env; offsite rclone via CYRBER_BACKUP_OFFSITE_REMOTE
You set the backup rhythm with your own cron, and we recommend a nightly run, so the recovery point, meaning how much data you lose at most in a failure, equals the interval between backups and in the daily variant is at most one day, while the freshness of the latest backup is watched by a separate health check and its restorability is proven by a restore-test script, so the backup is not a matter of faith but something actually verified. The backup, the freshness monitoring and the restore test are MAMY, continuous archiving that shortens the recovery point below a day is DOŁOŻYMY. path: client nightly cron (recommended 03:00 UTC); _check_backup_status health; scripts/backup_restore_test.sh; no WAL/PITR in repo
High availability
We talk about resilience plainly, because today we stand CYRBER on a single node, and what protects it in daily work runs inside that node, since supervised containers come back up after a stall, separate background tasks detect and revive stuck missions and roll back failed remediations, so a single service that trips returns to form with no hand from an operator. Self-healing within the node is MAMY. path: container restart-unhealthy, stuck_missions_recovery_task, organism_metabolism_self_heal, MEDICUS rollback
What we do not pretend, on the other hand, is true high availability, because the loss of a whole node does not switch traffic to a spare on its own today, but comes down to restoring from backup on new hardware, whose time depends on the database size, so we treat a hot standby of the database, automatic failover and a layout with no single point of failure as a separate, deliberately named stage. Recovery after a node loss is MAMY, a hot standby with automatic failover is DOŁOŻYMY. path: no replication/standby/failover in docker-compose.yml; recovery path = scripts/backup_restore_test.sh
Isolation and hardening
Many organizations on one instance are kept apart by per-org isolation at the database level. The entrance is guarded by an HTTP-only cookie, MFA/TOTP and SSO/OIDC, and every capability call lands in the audit chain. A formal hardening guide, gathered into one document, is still to come. Isolation and audit are MAMY, the hardening guide is DOŁOŻYMY. path: multi-tenant per-org isolation, cookie + MFA + SSO/OIDC, capability audit chain
Standing the machine up is one thing; the daily work is another. The Operating chapter covers how to run missions, read the verdict and export the proof.
Obsługa
Quick start przeprowadza jedną misję od loginu aż po pieczęć, natomiast ten rozdział zbiera całą obsługę codzienną, na którą składają się role i dostęp, cykl misji, pokrętło autonomii, naprawa oraz eksport dowodu.
Role i dostęp
System zna pięć ról, z których każda widzi dokładnie tyle, ile widzieć powinna, ponieważ SUPERADMIN prowadzi wszystkie organizacje, ADMIN zarządza swoją własną wraz z kluczami API, SSO oraz audytem, OPERATOR obejmuje misje, raporty, naprawę i playbooki, CLIENT ogląda findings wyłącznie do odczytu i może je wyeksportować, a DEMO otrzymuje jedynie ograniczony podgląd. MAMY ścieżka: role SUPERADMIN/ADMIN/OPERATOR/CLIENT/DEMO, require_role jako zależność
Cykl misji
Misja zaczyna się od polityki LEX, która wyznacza zasięg oraz klasę ryzyka, po czym MENS iteruje pętlą OBSERVE, THINK, ACT, LEARN i samodzielnie dobiera następny ruch, a gdy tylko się domknie, uruchamia się łańcuch hooków, na który składają się profil SPECULUM, pieczęć TESTIMONIUM, bliźniak UMBRA, prognoza ANNALES, kolejka naprawy oraz pamięć LIBER. MAMY ścieżka: mind_agent.py run_hook, łańcuch hooków po misji
Pokrętło autonomii
To, ile wolności otrzymuje organizm, ustawiasz na stronie /organism, gdzie dla niższej klasy ryzyka system działa samodzielnie, natomiast dla wyższej każdy krok czeka na Twój podpis, czyli na consent, a opcjonalnie na bramę MFA, zanim w ogóle się wykona, i właśnie dlatego jest to pokrętło z klasami ryzyka, a nie przełącznik zero-jeden. MAMY ścieżka: pokrętło autonomii na /organism, requires_consent na krok
Werdykt i naprawa
Findings lądują na Zagrożeniach opatrzone poziomem severity oraz ryzykiem biznesowym, a samą naprawę prowadzi MEDICUS, który proponuje konkretny krok, którego wykonanie zbroisz podpisem TOTP na miejscu, bez opuszczania ekranu. MAMY ścieżka: findings na static/threats.html, MEDICUS apply modules/medicus_ops.py, remediation zbrojona podpisem TOTP inline
Zgodność i eksport
Wynik mapuje się na NIS2, DORA oraz GDPR, a sam raport misji, w języku polskim lub angielskim i opatrzony brandingiem klienta, eksportujesz do PDF jednym kliknięciem, natomiast eksport zgodności pobierasz osobno: dla całej trójki wychodzi jako JSON, a do PDF renderuje się dziś wyłącznie NIS2, ponieważ wariantu dla DORA i GDPR jeszcze nie dołożyliśmy. Każdy skan pieczętuje przy tym TESTIMONIUM drzewem Merkle oraz podpisem, dzięki czemu samą pieczęć sprawdzisz publicznie, bez dostępu do naszej bazy. Raport misji w PDF, eksport zgodności w JSON dla całej trójki oraz PDF dla NIS2 MAMY, a PDF dla DORA i GDPR DOŁOŻYMY (szczegóły w rozdziale Compliance). ścieżka: raport misji PL/EN backend/routers/report.py ?lang=; eksport zgodności nis2/dora/gdpr JSON + nis2 pdf backend/routers/proof.py (508/552/599/922); pieczęć TESTIMONIUM, trust.cyrber.com
Podgląd na żywo
KOKPIT w trybie Battle pokazuje aktywną iterację wraz z EKG misji, natomiast żywotność organizmu, w którym każdy z … komponentów pozostaje pod rygorem niezmiennika I-9, obserwujesz na stronach Organizm oraz Status. MAMY ścieżka: I-9 liveness 19/19, GET /api/organism/liveness, KOKPIT Battle Mode
Gdzie konkretnie werdykt zapada w rytuale, opisuje akt Werdykt w rozdziale Rytuał, natomiast to, jak sprawdzić pieczęć bez naszej bazy, pokazuje rozdział Public verify.
Operating
Quick start walks one mission from login to seal. This is the full operation: roles, the mission cycle, the autonomy dial, remediation and the evidence export.
Roles and access
There are five roles, and each sees exactly what it should. SUPERADMIN runs every organization, ADMIN runs their own with API keys, SSO and the audit log, OPERATOR runs missions, reports, remediation and playbooks, CLIENT gets read-only findings and export, DEMO a limited view. MAMY path: roles SUPERADMIN/ADMIN/OPERATOR/CLIENT/DEMO, require_role as a dependency
The mission cycle
A mission starts from a LEX policy that sets the scope and the risk class. Then MENS iterates the OBSERVE, THINK, ACT, LEARN loop and picks its own next move. On close a hook chain fires: the SPECULUM profile, the TESTIMONIUM seal, the UMBRA twin, the ANNALES forecast, the remediation queue and the LIBER memory. MAMY path: mind_agent.py run_hook, the post-mission hook chain
The autonomy dial
You set how much latitude the organism gets on /organism. For a lower risk class the system acts on its own, for a higher one a step waits for your signature (consent, optionally an MFA gate) before it fires. It is a dial with risk classes, not a zero-one switch. MAMY path: autonomy dial on /organism, requires_consent per step
Verdict and remediation
Findings land under Threats with a severity level and a business risk. Remediation runs through MEDICUS: it proposes a step, and you arm its execution with an inline TOTP signature, without leaving the screen. MAMY path: findings on static/threats.html, MEDICUS apply modules/medicus_ops.py, remediation armed with an inline TOTP signature
Compliance and export
The result maps to NIS2, DORA and GDPR, and the mission report itself, in Polish or English and with the client's branding, exports to PDF in one click, while the compliance export is separate: it comes out as JSON for all three, and only NIS2 renders to PDF today, since we have not yet added that variant for DORA and GDPR. Every scan is sealed by TESTIMONIUM with a Merkle tree and a signature, so you can check the seal publicly, without our database. The mission report PDF, the JSON compliance export for all three and the NIS2 PDF are MAMY, a PDF for DORA and GDPR is DOŁOŻYMY (details in the Compliance chapter). path: mission report PL/EN backend/routers/report.py ?lang=; compliance export nis2/dora/gdpr JSON + nis2 pdf backend/routers/proof.py (508/552/599/922); TESTIMONIUM seal, trust.cyrber.com
Live view
KOKPIT in Battle Mode shows the running iteration and the mission heartbeat, and the organism's liveness, where each of the … components sits under the I-9 invariant, is what you see on Organism and Status. MAMY path: I-9 liveness 19/19, GET /api/organism/liveness, KOKPIT Battle Mode
The Verdict act of the Ritual chapter shows where the verdict is reached, and the Public verify chapter shows how to check the seal without our database.
API
Powierzchnię API dzielą trzy warstwy dostępu, z których każda ma inny próg zaufania i inne wymagania wobec tego, kto do niej puka.
Publiczne
/api/public/* nie wymaga uwierzytelnienia i ma otwarty CORS. Tu żyją status komponentów oraz dane, które CYRBER pokazuje na zewnątrz bez logowania. MAMY ścieżka: backend/routers/public_status.py prefix /api/public, bez zależności auth, CORS przez FastAPI
X-Proof-Key
/api/proof/verify/* i /api/proof/feed wymagają nagłówka X-Proof-Key, klucza wydawanego audytorom kanałem offline, a jest to ścieżka dla kogoś, kto ma sprawdzić dowód, a nie zarządzać kontem, przy czym pełny jej opis znajdziesz w rozdziale Public verify. MAMY ścieżka: backend/routers/proof.py, /api/proof/feed zwraca 422 bez nagłówka X-Proof-Key
Bearer i cookie
Reszta API stoi za sesją operatora: ciasteczko HTTP-only jako pierwszy wybór, nagłówek Bearer jako zapasowy oraz klucz API (X-API-Key) dla integracji maszyna-maszyna. MAMY ścieżka: backend/deps.py get_current_user: cookie → Bearer → X-API-Key
Status publiczny
GET /api/public/status zwraca migawkę zdrowia ośmiu komponentów, złożoną w jeden wynik po najgorszym przypadku, i trzyma ją w cache 30 sekund, żeby nie dobijać się do bazy przy każdym odpytaniu. Ten sam status napędza status.cyrber.com. MAMY ścieżka: backend/routers/public_status.py, 8 komponentów, _CACHE_TTL=30.0, worst-case _overall()
curl https://api.cyrber.com/api/public/status
{
"generated_at": "2026-07-18T09:12:00Z",
"overall": "operational",
"components": [
{"name": "api", "status": "operational"},
{"name": "database", "status": "operational", "latency_ms": 4.2},
{"name": "redis", "status": "operational", "latency_ms": 1.1},
{"name": "scheduler", "status": "operational", "latency_ms": 812.5},
{"name": "llm-router", "status": "operational"},
{"name": "glass-house-verify", "status": "operational"},
{"name": "matrix-bridge", "status": "operational"},
{"name": "jitsi", "status": "operational", "latency_ms": 210.4}
],
"incidents": [],
"maintenance": []
}
Reference
Interaktywny Swagger oraz surowy openapi.json pod generatory kodu klienta budują się z tras FastAPI, natomiast w trybie produkcyjnym wyłączamy je z rozmysłu, żeby nie wystawiać powierzchni na zewnątrz, dlatego publiczny api.cyrber.com/docs odpowiada dziś 404. Klient on-prem włącza je u siebie jedną zmienną środowiskową (CYRBER_ENV na wartość inną niż production), po czym /docs, /redoc i /openapi.json stają się dostępne w jego instancji. MAMY ścieżka: backend/main.py docs_url/redoc_url/openapi_url = ... if _is_dev else None, _is_dev = CYRBER_ENV != "production"
API
Three access tiers, each with its own trust threshold and its own demands on whoever knocks.
Public
/api/public/* needs no authentication and runs open CORS. Component status and anything CYRBER shows to the outside world without a login live here. MAMY path: backend/routers/public_status.py prefix /api/public, no auth dependency, CORS via FastAPI
X-Proof-Key
/api/proof/verify/* and /api/proof/feed require an X-Proof-Key header, a key handed to auditors through an offline channel. This tier is for someone checking a proof, not managing an account. Full detail sits in the Public verify chapter. MAMY path: backend/routers/proof.py, /api/proof/feed returns 422 without the X-Proof-Key header
Bearer and cookie
Everything else runs behind an operator session: an HTTP-only cookie first, a Bearer header as fallback, and an API key (X-API-Key) for machine-to-machine integrations. MAMY path: backend/deps.py get_current_user: cookie → Bearer → X-API-Key
Public status
GET /api/public/status returns a health snapshot of eight components, rolled up to a single worst-case reading, and caches it for 30 seconds so a poll does not hit the database every time. The same status feeds status.cyrber.com. MAMY path: backend/routers/public_status.py, 8 components, _CACHE_TTL=30.0, worst-case _overall()
curl https://api.cyrber.com/api/public/status
{
"generated_at": "2026-07-18T09:12:00Z",
"overall": "operational",
"components": [
{"name": "api", "status": "operational"},
{"name": "database", "status": "operational", "latency_ms": 4.2},
{"name": "redis", "status": "operational", "latency_ms": 1.1},
{"name": "scheduler", "status": "operational", "latency_ms": 812.5},
{"name": "llm-router", "status": "operational"},
{"name": "glass-house-verify", "status": "operational"},
{"name": "matrix-bridge", "status": "operational"},
{"name": "jitsi", "status": "operational", "latency_ms": 210.4}
],
"incidents": [],
"maintenance": []
}
Reference
The interactive Swagger and a raw openapi.json for client codegen are built from the FastAPI routes, yet in production we disable them on purpose, to keep that surface off the public edge, which is why api.cyrber.com/docs answers 404 today. An on-prem customer turns them on with a single environment variable (CYRBER_ENV set to anything other than production), after which /docs, /redoc and /openapi.json become available in their own instance. MAMY path: backend/main.py docs_url/redoc_url/openapi_url = ... if _is_dev else None, _is_dev = CYRBER_ENV != "production"
Public verify
Każdy finding jest hashowany, podpisany HMAC i zamknięty w drzewie Merkle na poziomie skanu. Root drzewa plus ścieżka Merkle wystarczą, żeby dowolna strona potwierdziła istnienie findingu w momencie skanu, bez wglądu w naszą bazę. MAMY ścieżka: backend/proof.py hash_finding SHA-256, sign_leaf HMAC-SHA256, build_merkle_tree
1. Zdobądź klucz
Poproś o X-Proof-Key kanałem offline, nie mailem ani przez UI. To jeden współdzielony klucz, ten sam dla każdego audytora, nie osobne wydanie per audyt, i po dostarczeniu nie zależy od dostępności naszego serwera. MAMY ścieżka: backend/routers/proof.py _verify_proof_key = hmac.compare_digest(x_proof_key, PROOF_API_KEY), 403 na zły
2. Zbierz identyfikatory
Z raportu wypisz scan_id i finding_id findingu, który sprawdzasz.
3. Zapytaj i przelicz
curl -H "X-Proof-Key: $PROOF_KEY" \
https://api.cyrber.com/api/proof/verify/{scan_id}/{finding_id}
{
"valid": true,
"root_hash": "3f2b7a9e1c4d8f60b52e77a1d9c3f048e91a",
"finding_hash": "9c7d5e1a0b3f6428d715c9a02b8e4f01",
"verified_at": "2026-07-18T10:03:11Z"
}
Pole valid to wynik przeliczenia ścieżki Merkle po stronie serwera, nie gołosłowne twierdzenie: porównaj root_hash z rootem opublikowanym dla tego skanu na trust.cyrber.com i finding_hash z hashem findingu we własnym raporcie. Sama ścieżka Merkle użyta do przeliczenia nie wraca w tej odpowiedzi; kto ma dostęp operatorski do platformy, znajdzie ją per finding pod GET /api/proof/trees/{scan_id} (pole merkle_path w każdym liściu). MAMY ścieżka: backend/routers/proof.py verify_finding zwraca valid=ProofEngine.verify_leaf(finding_hash, merkle_path, root_hash); get_tree liście z merkle_path
Public verify
Every finding is hashed, HMAC-signed and closed inside a Merkle tree at scan level. The tree's root plus a Merkle path are enough for any party to confirm a finding existed at scan time, with no view into our database. MAMY path: backend/proof.py hash_finding SHA-256, sign_leaf HMAC-SHA256, build_merkle_tree
1. Get a key
Ask for an X-Proof-Key through an offline channel, never email or the UI. It is one shared key, the same for every auditor, not issued fresh per audit, and once delivered it does not depend on our server being reachable. MAMY path: backend/routers/proof.py _verify_proof_key = hmac.compare_digest(x_proof_key, PROOF_API_KEY), 403 on mismatch
2. Collect the identifiers
From the report, pull scan_id and finding_id for the finding you are checking.
3. Query and recompute
curl -H "X-Proof-Key: $PROOF_KEY" \
https://api.cyrber.com/api/proof/verify/{scan_id}/{finding_id}
{
"valid": true,
"root_hash": "3f2b7a9e1c4d8f60b52e77a1d9c3f048e91a",
"finding_hash": "9c7d5e1a0b3f6428d715c9a02b8e4f01",
"verified_at": "2026-07-18T10:03:11Z"
}
The valid field is the result of the server walking the Merkle path, not an unsupported claim: check root_hash against the root published for that scan at trust.cyrber.com, and finding_hash against the finding's hash in your own report. The Merkle path used for that walk does not come back in this response; anyone with operator access to the platform finds it per finding at GET /api/proof/trees/{scan_id} (the merkle_path field on each leaf). MAMY path: backend/routers/proof.py verify_finding returns valid=ProofEngine.verify_leaf(finding_hash, merkle_path, root_hash); get_tree leaves with merkle_path
Integracje
Po zamknięciu misji łańcuch hooków rozsyła findings na zewnątrz, a konfiguracja tego rozsyłu żyje w panelu admin → Integrations, osobno dla każdej organizacji.
Kanały wychodzące
Matrix (czat w czasie rzeczywistym), webhook (POST JSON pod dowolny endpoint, w tym Slack, Teams czy Discord, z opcjonalnym podpisem HMAC), Jira (automatyczny issue per finding), GitLab (issue tracker), Wazuh (korelacja SIEM), MISP i TheHive (threat intel, IOC), ELS (zewnętrzny strumień logów, syslog CEF oraz Elasticsearch). To domknięta ósemka kanałów, którymi platforma wypycha findings na zewnątrz. MAMY ścieżka: modules/integrations/__init__.py _INTEGRATION_CLASSES (8 kanałów), dispatch per-org z mind_agent.py hook chain
Matrix
Pokoje tworzą jeden zestaw wspólny dla całej platformy, skonfigurowany zmiennymi środowiskowymi (Alerts, Admin, System, Incidents, Postulatum), przy czym nie zakładamy osobnego kompletu ani per organizacja, ani per poziom severity. MAMY ścieżka: modules/matrix_bridge.py
Jira i GitLab
Do trackera trafiają dziś wyłącznie findings o severity CRITICAL oraz HIGH, ponieważ ten próg jest zaszyty w łańcuchu hooków po misji, a severity mapuje się na priorytet Jira wprost, gdzie dla CRITICAL zakładamy ticket o priorytecie Highest, a dla HIGH o priorytecie High. GitLab dostaje issue tą samą ścieżką, natomiast MEDIUM, LOW oraz INFO nie trafiają do trackera wcale. MAMY ścieżka: mind_agent.py _notify_findings filtr sev in (CRITICAL, HIGH); jira.py _SEVERITY_TO_PRIORITY CRITICAL→Highest, HIGH→High
Próg konfigurowalny osobno dla każdej organizacji, a więc wybór, od którego poziomu severity zakładamy ticket, DOŁOŻYMY. ścieżka: dziś próg CRITICAL/HIGH zaszyty w mind_agent.py:_notify_findings, brak per-org override na progu
Integracje wejściowe
Rozsył findings biegnie na zewnątrz, natomiast platforma przyjmuje też połączenia z drugiej strony, a każde z nich ma w panelu admina osobną zakładkę, niezależną od kanałów. Tożsamość wpinasz przez SSO/OIDC, gdzie logowanie prowadzi zewnętrzny dostawca, taki jak Okta, Azure AD albo Google, a przepływ domyka standardowy OpenID Connect z weryfikacją podpisu tokena. Wywiad zasila Intel Sync, który zaciąga kanały zagrożeń z CISA KEV, NVD, FIRST EPSS oraz MITRE ATT&CK, a w trybie odciętym zastępujesz go pakietem wywiadu offline. Dostęp maszyna do maszyny otwierasz kluczem API w nagłówku X-API-Key, obwarowanym zakresami uprawnień, przy czym tą samą bramą stoi serwer MCP, przez który zewnętrzny agent sięga po narzędzia platformy. MAMY ścieżka: SSO/OIDC backend/routers/sso.py (okta/azure_ad/google/custom), zakładka SSO; Intel Sync backend/routers/intelligence.py + cyrber-intel-sync.sh (KEV/NVD/EPSS/ATT&CK), sekcja Intelligence; klucze API backend/routers/apikeys.py (X-API-Key + scopes), zakładka API KLUCZE; serwer MCP backend/routers/mcp.py
Silniki skanujące
Obok modułów, które MENS dysponuje w trakcie misji, CYRBER prowadzi też zewnętrzny silnik skanowania podatności Greenbone, znany szerzej jako OpenVAS, wpięty protokołem GMP do osobnego serwera skanera, a nie do jednego z kontenerów platformy. Reżim dzienny sam odpala głęboki skan każdego celu, który mieści się w zakresie polityki LEX, po czym osobny cykl dociąga wynik i wpuszcza findings tą samą rurą, którą płyną wyniki nuclei czy ZAP, więc raport nie rozróżnia, czy podatność znalazł moduł wewnętrzny, czy silnik zewnętrzny. MAMY ścieżka: modules/openvas_scan.py + openvas_client.py (GMP/TLS) + openvas_parser.py; reżim openvas_regimen_task (beat 02:00) + openvas_poll_task (co 120 s), GVM_HOST; findings przez _extract_findings module=openvas
Konfiguracja
Każdy kanał włączasz zmienną środowiskową albo wpisem na poziomie organizacji, który ląduje w bazie i wczytuje się dopiero w chwili rozsyłu, dzięki czemu pojedynczej integracji nie musisz przypłacać restartem całej platformy. MAMY ścieżka: modules/integrations/models.py IntegrationConfig per-org w DB, get_integrations() ładuje aktywne przy dispatchu
Integrations
Once a mission closes, the hook chain fans findings out to your stack. Configuration lives under admin → Integrations, per organization.
Outbound channels
Matrix (real-time chat), webhook (POST JSON to any endpoint, Slack, Teams or Discord included, with an optional HMAC signature), Jira (an issue per finding, automatic), GitLab (issue tracker), Wazuh (SIEM correlation), MISP and TheHive (threat intel, IOCs), ELS (external log stream, syslog CEF and Elasticsearch). This is a closed set of eight channels through which the platform pushes findings out. MAMY path: modules/integrations/__init__.py _INTEGRATION_CLASSES (8 channels), per-org dispatch from the mind_agent.py hook chain
Matrix
One room set, shared across the whole platform and configured through environment variables (Alerts, Admin, System, Incidents, Postulatum), not a separate set per organization or per severity level. MAMY path: modules/matrix_bridge.py
Jira and GitLab
Only CRITICAL and HIGH findings reach the tracker today, because that threshold is baked into the post-mission hook chain, and severity maps straight onto a Jira priority, where CRITICAL opens a Highest-priority ticket and HIGH a High one. GitLab gets an issue down the same path, while MEDIUM, LOW and INFO never reach the tracker at all. MAMY path: mind_agent.py _notify_findings filter sev in (CRITICAL, HIGH); jira.py _SEVERITY_TO_PRIORITY CRITICAL→Highest, HIGH→High
Making the threshold configurable per organization, so you pick the severity level at which a ticket opens, is DOŁOŻYMY. path: the CRITICAL/HIGH threshold is fixed in mind_agent.py:_notify_findings today, no per-org override on it
Inbound integrations
The finding fan-out runs outward, yet the platform also takes connections from the other side, and each of them has its own tab in the admin panel, separate from the channels. Identity plugs in through SSO/OIDC, where an external provider such as Okta, Azure AD or Google drives the login and standard OpenID Connect closes the flow with token-signature verification. Intelligence is fed by Intel Sync, which pulls threat feeds from CISA KEV, NVD, FIRST EPSS and MITRE ATT&CK, and in the severed mode you replace it with an offline intelligence bundle. Machine-to-machine access opens with an API key in the X-API-Key header, fenced by permission scopes, and the same gate carries the MCP server, through which an external agent reaches the platform's tools. MAMY path: SSO/OIDC backend/routers/sso.py (okta/azure_ad/google/custom), SSO tab; Intel Sync backend/routers/intelligence.py + cyrber-intel-sync.sh (KEV/NVD/EPSS/ATT&CK), Intelligence section; API keys backend/routers/apikeys.py (X-API-Key + scopes), API KEYS tab; MCP server backend/routers/mcp.py
Scanning engines
Beyond the modules MENS dispatches during a mission, CYRBER also drives an external Greenbone vulnerability scanner, known more widely as OpenVAS, wired over the GMP protocol to a separate scanner server rather than to one of the platform's own containers. A daily regimen launches a deep scan of every target that falls inside a LEX policy's scope, a separate cycle then pulls the result and feeds the findings down the same pipe the nuclei and ZAP results travel, so the report does not distinguish whether an internal module or the external engine found the vulnerability. MAMY path: modules/openvas_scan.py + openvas_client.py (GMP/TLS) + openvas_parser.py; regimen openvas_regimen_task (beat 02:00) + openvas_poll_task (every 120s), GVM_HOST; findings via _extract_findings module=openvas
Configuration
Each channel turns on through an environment variable or an organization-level entry that lands in the database and loads only at dispatch time, so a single integration never costs you a full platform restart. MAMY path: modules/integrations/models.py IntegrationConfig per-org in the DB, get_integrations() loads active ones at dispatch
Compliance
TESTIMONIUM mapuje findings na kontrole regulacyjne: coverage per wymóg, poziom ryzyka tam, gdzie kontrola nie jest spełniona, i luka do zamknięcia w naprawie. MAMY ścieżka: modules/testis/ + modules/compliance_map.py mapują findings na kontrole
Frameworki
NIS2 (Art. 21 §2), DORA (ryzyko ICT oraz rekordy autoryzacji TLPT), GDPR/RODO (środki techniczne i podsumowanie ochrony danych), ISO/IEC 27001:2022. MAMY ścieżka: NIS2/ISO27001 w modules/compliance_map.py (ISO27001_MAPPING); DORA/TLPT w modules/compliance_engine.py + modules/bec_simulation.py (Art. 24)
Eksport per misja
Endpoint zwraca wszystkie trzy frameworki naraz, nie jeden wybrany filtrem ?framework=: nie ma takiego parametru, ponieważ oceniamy misję jednym zapytaniem pod NIS2, DORA i GDPR równolegle. MAMY ścieżka: GET /api/proof/mission/{id}/compliance, backend/routers/proof.py:1177
GET /api/proof/mission/4821/compliance
{
"organization": "Acme Sp. z o.o.",
"mission_id": 4821,
"overall_status": "PARTIALLY_COMPLIANT",
"frameworks": {
"NIS2": {
"overall_status": "PARTIALLY_COMPLIANT",
"risk_level": "MEDIUM",
"coverage_percentage": 62,
"requirements": {
"21_2_b": {
"name": "Obsługa incydentów",
"article": "Art. 21(2)(b)",
"status": "COVERED_WITH_FINDINGS",
"covering_modules": ["nuclei", "mens_loop"],
"high_critical_findings": 1
},
"21_2_e": {
"name": "Testowanie planów odzyskiwania",
"article": "Art. 21(2)(e)",
"status": "NOT_TESTED",
"covering_modules": [],
"high_critical_findings": 0
}
},
"summary": {"total_requirements": 9, "covered": 5, "covered_with_findings": 2, "not_tested": 4}
},
"DORA": {"overall_status": "PARTIALLY_COMPLIANT", "coverage_percentage": 55},
"GDPR": {"overall_status": "COMPLIANT", "coverage_percentage": 84}
},
"coverage_summary": {"NIS2": 62, "DORA": 55, "GDPR": 84}
}
Eksport per organizacja
/api/proof/export/{nis2|dora|gdpr}/{org_id} zwraca zagregowany JSON po wszystkich misjach organizacji dla każdego z trzech frameworków, natomiast wariant PDF renderuje WeasyPrint na razie tylko dla NIS2 (/api/proof/export/nis2/{org_id}/pdf), podczas gdy DORA i GDPR zostają przy JSON. Eksport JSON całej trójki oraz PDF dla NIS2 MAMY, a PDF dla DORA i GDPR DOŁOŻYMY. ścieżka: backend/routers/proof.py export nis2/dora/gdpr (508/552/922) + nis2 pdf (599); brak endpointu pdf dla dora/gdpr
Eksport w otwartym standardzie OSCAL
CYRBER eksportuje dowód badania w otwartym standardzie NIST OSCAL 1.1.2, w dwóch modelach, przy czym pierwszy z nich, assessment-results, niesie wyniki badania, w którym każda obserwacja daje się zweryfikować względem korzenia Merkle danej misji, a drugi, plan-of-action-and-milestones, zbiera otwarte zadania naprawcze. Ponieważ dokument przechodzi walidację oficjalnym narzędziem oscal-cli instytutu NIST, nabywca wczytuje go wprost do własnego systemu GRC, nie pisząc ani nie utrzymując własnego tłumacza formatu, i właśnie dlatego oparcie się o standard branżowy jest dla odbiorcy wygodniejsze niż kolejny format zamknięty w jednym produkcie. Eksport OSCAL, zarówno dla pojedynczej misji (/api/proof/mission/{id}/oscal/assessment-results oraz /api/proof/mission/{id}/oscal/poam), jak i zbiorczo dla całej organizacji (parametr ?format=oscal na trasach eksportu), MAMY, natomiast bezpośredni push dowodu do konkretnego systemu GRC DOŁOŻYMY. Poszczególne ustalenia wiążą się z konkretnymi artykułami regulacji przez mapowanie modułu skanującego, który je wykrył, na wymaganie NIS2, DORA lub RODO, dzięki czemu przeważająca część dowodu wskazuje wprost artykuł, którego dotyczy, natomiast jeżeli ustalenie pochodzi z modułu spoza mapy, trafia do dokumentu jako niezmapowane, co jest w jego treści widoczne wprost i świadomie nie jest maskowane, ponieważ dokument dowodowy nie może twierdzić więcej, niż zostało zbadane. ścieżka: backend/routers/proof.py oscal/assessment-results + oscal/poam + format=oscal; modules/oscal_export.py, modules/oscal_validate.py, mapowanie modułu na artykuł w modules/compliance_engine.py; walidacja oficjalnym oscal-cli 1.0.3 (misja 581 assessment-results, 89 obserwacji, wszystkie zmapowane na artykuły NIS2, valid)
Compliance
TESTIMONIUM maps findings onto regulatory controls: coverage per requirement, a risk level wherever a control is not met, and a gap to close through remediation. MAMY path: modules/testis/ + modules/compliance_map.py map findings onto controls
Frameworks
NIS2 (Art. 21 par. 2), DORA (ICT risk plus TLPT authorization records), GDPR (technical measures and a data protection summary), ISO/IEC 27001:2022. MAMY path: NIS2/ISO27001 in modules/compliance_map.py (ISO27001_MAPPING); DORA/TLPT in modules/compliance_engine.py + modules/bec_simulation.py (Art. 24)
Per-mission export
The endpoint returns all three frameworks at once, not one picked through a ?framework= filter: there is no such parameter, one call assesses the mission under NIS2, DORA and GDPR in parallel. MAMY path: GET /api/proof/mission/{id}/compliance, backend/routers/proof.py:1177
GET /api/proof/mission/4821/compliance
{
"organization": "Acme Sp. z o.o.",
"mission_id": 4821,
"overall_status": "PARTIALLY_COMPLIANT",
"frameworks": {
"NIS2": {
"overall_status": "PARTIALLY_COMPLIANT",
"risk_level": "MEDIUM",
"coverage_percentage": 62,
"requirements": {
"21_2_b": {
"name": "Incident handling",
"article": "Art. 21(2)(b)",
"status": "COVERED_WITH_FINDINGS",
"covering_modules": ["nuclei", "mens_loop"],
"high_critical_findings": 1
},
"21_2_e": {
"name": "Recovery plan testing",
"article": "Art. 21(2)(e)",
"status": "NOT_TESTED",
"covering_modules": [],
"high_critical_findings": 0
}
},
"summary": {"total_requirements": 9, "covered": 5, "covered_with_findings": 2, "not_tested": 4}
},
"DORA": {"overall_status": "PARTIALLY_COMPLIANT", "coverage_percentage": 55},
"GDPR": {"overall_status": "COMPLIANT", "coverage_percentage": 84}
},
"coverage_summary": {"NIS2": 62, "DORA": 55, "GDPR": 84}
}
Per-org export
/api/proof/export/{nis2|dora|gdpr}/{org_id} returns aggregated JSON across every mission the organization ran, for each of the three frameworks, while the PDF variant renders through WeasyPrint for NIS2 alone for now (/api/proof/export/nis2/{org_id}/pdf), whereas DORA and GDPR stay JSON. The JSON export of all three and the NIS2 PDF are MAMY, a PDF for DORA and GDPR is DOŁOŻYMY. path: backend/routers/proof.py export nis2/dora/gdpr (508/552/922) + nis2 pdf (599); no pdf endpoint for dora/gdpr
Export in the open OSCAL standard
CYRBER exports its assessment evidence in the open NIST OSCAL 1.1.2 standard across two models, where the first one, assessment-results, carries the findings of the assessment in which every observation can be verified against the mission Merkle root, and the second one, plan-of-action-and-milestones, gathers the open remediation tasks. Because the document passes validation with the official NIST oscal-cli tool, a buyer loads it straight into their own GRC system without writing or maintaining a bespoke format translator, and that is precisely why relying on an industry standard is more convenient for the recipient than yet another format locked inside a single product. OSCAL export, both for a single mission (/api/proof/mission/{id}/oscal/assessment-results and /api/proof/mission/{id}/oscal/poam) and aggregated for the whole organization (the ?format=oscal parameter on the export routes), is MAMY, whereas a direct push of the evidence into a specific GRC system is DOŁOŻYMY. Individual findings tie to concrete regulatory articles through a mapping of the scanning module that surfaced them onto a NIS2, DORA or GDPR requirement, so the majority of the evidence points straight at the article it concerns, whereas a finding coming from a module outside the map enters the document as unmapped, which is shown plainly in its contents and is deliberately not masked, because an evidence document must never claim more than what was actually examined. path: backend/routers/proof.py oscal/assessment-results + oscal/poam + format=oscal; modules/oscal_export.py, modules/oscal_validate.py, module-to-article mapping in modules/compliance_engine.py; validated with official oscal-cli 1.0.3 (mission 581 assessment-results, 89 observations, all mapped to NIS2 articles, valid)
Incident response
Przy findingu o poziomie CRITICAL lub HIGH system wysyła zdarzenie do zewnętrznego SIEM automatycznie, przez webhook, bez czekania na operatora. MAMY ścieżka: mind_agent.py _notify_findings filtr sev in (CRITICAL, HIGH) → modules/integrations/webhook.py
Payload
{
"source": "CYRBER",
"event_type": "finding_detected",
"title": "Finding Detected",
"color": "#ff4444",
"timestamp": "2026-07-18T10:15:00Z",
"payload": {
"severity": "CRITICAL",
"target": "10.0.0.5",
"finding": "SQL Injection",
"cve_id": "CVE-2024-1234",
"organization_id": 1,
"mission_id": "m-4821",
"message": "Parametr id podatny na wstrzyknięcie SQL"
}
}
Podpis
Każde zdarzenie niesie nagłówek X-CYRBER-Signature, HMAC-SHA256 nad surowym ciałem payloadu, liczony współdzielonym sekretem ustalonym z góry przy konfiguracji webhooka. SOC weryfikuje go offline: liczy ten sam HMAC-SHA256 nad otrzymanym ciałem tym samym sekretem i porównuje wynik z nagłówkiem, bez odpytywania naszego API. MAMY ścieżka: modules/integrations/webhook.py _sign HMAC-SHA256, nagłówek X-CYRBER-Signature
Korelacja i air-gap
Operator SOC koreluje event z własnym logiem po polach payloadu, przede wszystkim po mission_id oraz target, a sam podpis HMAC sprawdza offline współdzielonym sekretem, bez żadnego wywołania do CYRBER. Pełny dowód Merkle danego findingu weryfikuje osobno, ścieżką z rozdziału Public verify, czyli przeliczeniem hasha i drogi Merkle pod kluczem X-Proof-Key, również bez kontaktu z naszym API, więc cały krok domyka się bez dostępu do sieci. Weryfikację podpisu oraz offline'owy dowód Merkle MAMY, a wzbogacenie samego eventu o gotowy verify_url i merkle_root, żeby SOC nie sięgał po nie osobno, DOŁOŻYMY. ścieżka: payload ma target/mission_id/organization_id (nie scan_id/verify_url); podpis HMAC offline; dowód Merkle przez GET /api/proof/verify/{scan_id}/{finding_id} (X-Proof-Key)
Incident response
A CRITICAL or HIGH finding sends an event to the external SIEM on its own, over a webhook, with no operator needed to trigger it. MAMY path: mind_agent.py _notify_findings filter sev in (CRITICAL, HIGH) → modules/integrations/webhook.py
Payload
{
"source": "CYRBER",
"event_type": "finding_detected",
"title": "Finding Detected",
"color": "#ff4444",
"timestamp": "2026-07-18T10:15:00Z",
"payload": {
"severity": "CRITICAL",
"target": "10.0.0.5",
"finding": "SQL Injection",
"cve_id": "CVE-2024-1234",
"organization_id": 1,
"mission_id": "m-4821",
"message": "id parameter vulnerable to SQL injection"
}
}
Signature
Every event carries an X-CYRBER-Signature header, an HMAC-SHA256 over the raw payload body, computed with a shared secret agreed when the webhook was configured. The SOC verifies it offline, computing the same HMAC-SHA256 over the received body with that same secret and compare it against the header, no call back to our API required. MAMY path: modules/integrations/webhook.py _sign HMAC-SHA256, X-CYRBER-Signature header
Correlation and air-gap
The SOC operator correlates the event against their own log by the payload fields, chiefly mission_id and target, and checks the HMAC signature offline with the shared secret, with no call to CYRBER at all. They verify the full Merkle proof of a finding separately, by the path in the Public verify chapter, recomputing the hash and the Merkle walk under an X-Proof-Key, again with no contact with our API, so the whole step closes off the network. Verifying the signature and the offline Merkle proof are MAMY, while enriching the event itself with a ready verify_url and merkle_root, so the SOC need not fetch them separately, is DOŁOŻYMY. path: payload carries target/mission_id/organization_id (no scan_id/verify_url); HMAC signature offline; Merkle proof via GET /api/proof/verify/{scan_id}/{finding_id} (X-Proof-Key)
Suwerenność
Suwerenność w CYRBER znaczy, że platforma, dane oraz dowód zostają po Twojej stronie, a nie po naszej. Dostajesz maszynę dowodową, której nikt z zewnątrz nie odtworzy bez jednoczesnego złożenia silnika eksploatacji, zamknięcia detekcji na własnym SIEM oraz zbudowania łańcucha dowodowego uszytego pod Twoją regulację. To rozdział, w którym jesteśmy najbardziej szczerzy w całym dokumencie, bo część tej obietnicy jest już faktem, a część dopiero planem.
On-prem
Platforma stoi u klienta, a dane i przebieg misji zostają na jego infrastrukturze, my zaś nie trzymamy żadnej kopii, ponieważ deployment on-prem działa już dziś. MAMY ścieżka: instalacja on-prem u klienta (docker-compose.yml)
Lokalny model
Chcemy, żeby całe rozumowanie zostawało w murach klienta, i choć routing air-gap oraz lokalna Ollama są już przygotowane w kodzie, domyślnym trybem pozostaje dziś chmura, a passthrough GPU jest zakomentowany, więc instalacja wprawdzie istnieje, lecz prąd jeszcze przez nią nie płynie. Dopóki tak pozostaje, nie napiszemy, że rozumowanie nie wychodzi na zewnątrz, a przełączenie na model lokalny domykamy, zanim uruchomisz CYRBER produkcyjnie u siebie. DOŁOŻYMY ścieżka: routing air-gap + Ollama przygotowane, domyślnie chmura, GPU passthrough zakomentowany
Klucze u klienta
Klucz podpisujący pieczęcie jest dziś jeden na instancję, po stronie serwera. Żeby klient sam trzymał swój klucz i sam decydował o podpisie, dokładamy BYOK. DOŁOŻYMY ścieżka: klucz podpisujący instance-wide po stronie serwera; BYOK w planie
Air-gap uczciwie
Teza „nic nie wychodzi” pęka w chwili, w której GUI pobiera cokolwiek z zewnętrznego CDN. Ta dokumentacja trzyma u siebie zasadę zero-CDN: żadnych fontów z sieci, żadnych bibliotek z zewnątrz, wszystko podane z serwera. Dla tej strony air-gap jest już faktem, natomiast dla całego produktu pozostaje warunkiem, który dopinamy powierzchnia po powierzchni. Z czterech wyjść danych opisanych w sekcji Sieć i egress wywiad, most alertów oraz kotwicę OpenTimestamps odcinasz już dziś, więc do pełnego air-gapu brakuje przede wszystkim lokalnego modelu rozumowania. Zero CDN na tej stronie MAMY. Air-gap całego produktu DOŁOŻYMY. ścieżka: zero-CDN egzekwowane testem test_docs_content_lint.py
Suwerenność jest właściwością, którą sprawdzisz sam. Dopóki rozumowanie idzie do chmury, nie napiszemy, że nic nie wychodzi, i właśnie dlatego przełączenie na model lokalny domykamy, zanim uruchomisz CYRBER produkcyjnie u siebie. Jak ten sam werdykt zweryfikujesz bez naszej bazy, pokazuje Glass House, a gdzie werdykt zapada w rytuale, opisuje akt Werdykt w rozdziale Rytuał.
Sovereignty
Sovereignty in CYRBER means the platform, the data and the proof stay on your side, not ours. You get a proof machine no outsider can reconstruct without building the exploitation engine, the detection close on the SIEM and the evidence chain all at once, tailored to your regulation. This is the chapter where we are most honest in the whole document, because part of that promise is already a fact and part is still a plan.
On-prem
The platform stands at the client's site. The data and the mission run stay on their infrastructure, and we keep no copy. On-prem deployment works today. MAMY path: on-prem install at the client (docker-compose.yml)
The local model
We want all of the reasoning to stay inside the client's walls. The air-gap routing and a local Ollama are prepared in the code, but the default mode today is the cloud, and the GPU passthrough is commented out. The wiring is in; the current is not flowing yet. As long as that holds, we will not write that the reasoning stays inside those walls. The cutover to a local model lands before you run CYRBER in production on your own site. DOŁOŻYMY path: air-gap routing + Ollama prepared, cloud by default, GPU passthrough commented out
Keys at the client
The key that signs the seals is, for now, one per instance, on the server side. For the client to hold their own key and own the signature, we add BYOK. DOŁOŻYMY path: instance-wide signing key on the server; BYOK planned
Air-gap, honestly
The claim that nothing leaves breaks the moment the GUI pulls anything from an external CDN. This documentation keeps a zero-CDN rule of its own: no fonts from the network, no libraries from outside, everything served from the server. For this page, the air-gap is a fact. For the whole product it is a condition we are closing surface by surface. Of the four data exits described in the Network and egress section, you already sever the intelligence feed, the alert bridge and the OpenTimestamps anchor today, so what a full air-gap mainly still needs is the local reasoning model. Zero CDN on this page is MAMY. A whole-product air-gap is DOŁOŻYMY. path: zero-CDN enforced by test_docs_content_lint.py
Sovereignty is not a slogan but a property you can check yourself. As long as the reasoning goes to the cloud we will not write that nothing leaves, which is why the cutover to a local model lands before you run CYRBER in production on your own site. The Glass House chapter shows how you check the same verdict without our database, and the Verdict act of the Ritual chapter shows where the verdict is reached.
Release notes
Pełna, bieżąca historia zmian żyje na cyrber.com/zmiany. Ta sekcja odsyła tam celowo: release notes trzymamy poza tym dokumentem, żeby proza tutaj nie starzała się przy każdym wydaniu.
Release notes
The full, current change history lives at cyrber.com/zmiany. This section points there on purpose: we keep release notes outside this document so the prose here does not go stale with every release.