# AMAS Central Manager — podsumowanie projektu i audyt kodu

Data analizy: 2026-09-07

## Status projektu

AMAS Central Manager jest funkcjonalnym prototypem centralnego zarządzania
hostami AMAS. Projekt nie jest obecnie gotowy do bezpiecznego wystawienia w
sieci produkcyjnej. Przed wdrożeniem należy przede wszystkim zabezpieczyć API,
usunąć wspólne sekrety i ujednolicić sposób instalacji.

## Architektura

Projekt składa się z:

- aplikacji FastAPI w `main.py`,
- głównego API managera w `api/manager_api.py`,
- komunikacji SSH przez Paramiko w `core/ssh_manager.py`,
- konfiguracji w `core/config.py`,
- bazy SQLite obsługiwanej przez `db/sqlite.py`,
- panelu WWW używającego `templates/index.html` i `static/app.js`,
- pakietu systemowego `amas-cluster-manager`,
- usługi systemd uruchamianej jako użytkownik `amas-cluster-manager`.

Manager przechowuje w SQLite:

- datacenter,
- klastry,
- nody AMAS,
- snapshoty inwentarza,
- zadania,
- zdarzenia,
- użytkowników panelu,
- sesje panelu,
- ustawienia managera.

Komunikacja z nodami odbywa się przez SSH oraz zdalne API AMAS.

## Problemy krytyczne

### 1. Brak globalnej ochrony API

Tylko 3 z 55 endpointów routera mają jawne sprawdzanie sesji przez
`require_manager_session`. Większość operacji można wywołać bez zalogowania.

Szczególnie niebezpieczne są:

- `/manager/nodes/{node_id}/ssh/run` — wykonuje dowolne polecenie SSH i może
  użyć `sudo`,
- `/manager/nodes/{node_id}/proxy/{proxy_path}` — przekazuje operacje do API
  zarządzanego AMAS,
- endpointy dodawania, importowania, edycji i usuwania nodów,
- endpointy operacji klastrowych,
- endpointy konfiguracji tokenów i sekretów,
- endpointy sprawdzania i instalowania aktualizacji managera.

Frontend wysyła token Bearer, ale większość backendu go nie weryfikuje.

Docelowo cały router `/manager` powinien wymagać sesji. Publiczne powinny zostać
wyłącznie świadomie wybrane endpointy, np. `/manager/auth/login` i `/health`.
Operacje administracyjne powinny dodatkowo sprawdzać rolę użytkownika.

### 2. Domyślne konto admin/admin

Baza automatycznie tworzy konto:

- użytkownik: `admin`,
- hasło: `admin`.

Konto jest odtwarzane także przez dodatkowy bezpiecznik w
`api/manager_api.py`. Instalacja powinna wymagać ustawienia losowego lub
podanego przez administratora hasła. Pierwsze logowanie powinno wymuszać jego
zmianę.

### 3. Stały token zdalnego API

W `core/config.py` oraz `api/manager_api.py` znajduje się zaszyty domyślny
token API. Wszystkie instalacje mogą przez to korzystać z tego samego sekretu.

Token powinien być:

- generowany indywidualnie,
- przechowywany poza kodem,
- zapisywany z uprawnieniami `0600`,
- możliwy do rotacji,
- osobny dla każdego zarządzanego noda lub aplikacji.

### 4. Dowolne wykonanie poleceń SSH

Endpoint `/manager/nodes/{node_id}/ssh/run` przyjmuje dowolny tekst polecenia i
flagę `sudo`. Bez obowiązkowej autoryzacji oznacza to możliwość zdalnego
wykonania poleceń administracyjnych na zarządzanych hostach.

Endpoint powinien zostać usunięty z API produkcyjnego albo ograniczony do
ściśle kontrolowanej listy operacji i wyłącznie roli administratora.

## Sekrety i dane uwierzytelniające

Aktualne problemy:

- hasła API/PAM nodów są przechowywane jawnie w `config_json`,
- tokeny sesji są przechowywane jawnie,
- sesje nie mają czasu wygaśnięcia,
- hasła panelu są hashowane pojedynczym SHA-256 z solą,
- nie ma ograniczenia prób logowania,
- prywatny klucz RSA znajduje się w katalogu projektu,
- prywatny klucz ma niewłaściwe uprawnienia `0664`.

Prywatny klucz `data/keys/amas_manager_rsa` powinien zostać usunięty z projektu,
unieważniony i generowany dopiero podczas instalacji. Powinien mieć prawa
`0600`, a katalog kluczy `0700`.

Do haseł należy użyć Argon2id, bcrypt albo scrypt. Dane dostępowe do nodów
powinny zostać zaszyfrowane kluczem instalacji albo zastąpione indywidualnymi
kluczami/tokenami.

## SSH

`core/ssh_manager.py` automatycznie akceptuje nieznane klucze hostów przez
`AutoAddPolicy`. Manager nie zapisuje i nie porównuje fingerprintu hosta.

Zalecany przepływ onboardingu:

1. pobranie fingerprintu hosta,
2. pokazanie go administratorowi,
3. jawne zatwierdzenie,
4. zapis w trwałym `known_hosts`,
5. odrzucenie połączenia po zmianie fingerprintu.

Połączenia SSH są cache'owane bez limitu bezczynności. Polecenia mają przeważnie
stały timeout 60 sekund, co może być niewystarczające dla długich operacji.

## Baza danych i sesje

SQLite nie ustawia obecnie:

- trybu WAL,
- `busy_timeout`,
- automatycznego wygasania sesji,
- limitu liczby sesji,
- czyszczenia nieaktywnych sesji,
- blokady lub opóźnienia po błędnych próbach logowania.

Logowanie synchronicznie sprawdza lock na wszystkich nodach. Niedostępny node
może przez to znacznie wydłużyć logowanie. Kontrolę nodów należy przenieść do
zadania wykonywanego po zalogowaniu.

## Aktualizator centralnego managera

Aktualizator wymaga przebudowy, ponieważ:

- korzysta z `/etc/apt/sources.list.d/amas.list`,
- używa wpisu `deb [trusted=yes]`, omijając weryfikację GPG,
- usuwa `/etc/apt/sources.list.d/magnimodi.list`,
- endpointy aktualizacji nie wymagają zalogowania,
- usługa działa jako `amas-cluster-manager`, ale APT jest uruchamiany bez
  poprawnie zdefiniowanego mechanizmu eskalacji uprawnień.

Repozytorium powinno używać osobnego keyringu, `signed-by` oraz źródła
Magnimodi. Backend powinien sprawdzać tylko właściwy pakiet i wykonywać
aktualizację przez ograniczony helper uprzywilejowany.

## Zdalne API AMAS

Konfiguracja zdalnego API ma niespójności:

- argumenty tokenów przekazywane do `update_remote_api_config` są ignorowane,
- funkcja zawsze wpisuje token statyczny,
- hasło użytkownika jest przechowywane jawnie,
- możliwy jest bezpośredni HTTP oraz fallback przez `curl` uruchamiany po SSH,
- adres bazowy z konfiguracji może kierować żądania do dowolnego celu,
- proxy przyjmuje wiele metod HTTP i dowolną ścieżkę.

Należy ustalić jeden model uwierzytelniania i jeden kontrolowany transport.
Proxy powinno posiadać listę dozwolonych endpointów zamiast przekazywać dowolną
ścieżkę.

## Blokady i operacje klastrowe

Projekt zawiera koncepcję blokady managera na nodach i sprawdza ją przed częścią
operacji. Jest to dobry kierunek, ale blokada nie zastępuje autoryzacji
użytkownika centralnego panelu.

Operacje klastrowe wykonują akcje kolejno i posiadają mechanizm rollback
best-effort. Nie gwarantuje on pełnej transakcyjności. Stan części nodów może
pozostać zmieniony, jeżeli rollback również się nie powiedzie. Takie zdarzenie
powinno tworzyć trwały alarm wymagający ręcznej interwencji.

## Frontend

W projekcie występują równolegle:

- `index.html`,
- `templates/index.html`,
- `static/app.js`,
- `js/app.js`,
- pliki `.bak-codex`.

Faktycznie aplikacja serwuje `templates/index.html` oraz zasoby z `static/`.
Katalog `js/` jest również montowany, ale zawiera inną wersję interfejsu. Grozi
to wprowadzaniem poprawek do pliku, którego aplikacja faktycznie nie używa.

Należy pozostawić jeden frontend i usunąć pliki zapasowe z dystrybucji.

W backendzie i frontendzie nadal występuje wiele tekstów wpisanych bezpośrednio
w kodzie. Wszystkie nazwy, nagłówki, komunikaty, przyciski i wartości opisowe
powinny przechodzić przez wspólny system i18n z językiem angielskim jako
fallbackiem.

## Packaging

Istnieją dwa niespójne sposoby budowania:

- skrypt `build_deb.sh`,
- standardowy katalog `debian/`.

Skrypt ręczny tworzy środowisko venv i pobiera zależności przez pip podczas
instalacji. Standardowy pakiet korzysta z zależności systemowych Debiana.
Efektem mogą być dwa pakiety o innej zawartości i zachowaniu.

Dodatkowo:

- `VERSION` zawiera `0.55.0-1783947220`,
- `debian/changelog` zawiera `0.35.0-1`,
- metadane maintanera i homepage są przykładowe,
- instalacja przez pip wymaga dostępu do Internetu podczas instalacji pakietu.

Należy wybrać jeden proces budowania i zapewnić, że instalacja `.deb` nie
pobiera zależności z Internetu.

## Jakość i testy

Sprawdzono:

- składnię modułów Python,
- składnię plików JavaScript,
- składnię skryptów Bash.

Nie wykryto błędów składni. W projekcie nie ma kompletnego zestawu testów
automatycznych. Szczególnie potrzebne są testy:

- autoryzacji każdego endpointu,
- uprawnień administratora,
- onboardingu i weryfikacji fingerprintu SSH,
- utraty połączenia w połowie operacji klastrowej,
- rollbacku częściowo wykonanej operacji,
- blokad managera,
- wygasania sesji,
- migracji schematu SQLite,
- aktualizacji pakietu,
- obsługi niedostępnych nodów.

## Zalecana kolejność prac

1. Założyć obowiązkową autoryzację na cały router `/manager`.
2. Zablokować lub usunąć endpoint dowolnych poleceń SSH.
3. Usunąć domyślne `admin/admin` i wymusić bezpieczne hasło startowe.
4. Usunąć zaszyty token API i dokonać jego rotacji na wszystkich nodach.
5. Usunąć prywatny klucz z projektu i wygenerować nową parę kluczy.
6. Zaszyfrować dane dostępowe oraz wdrożyć bezpieczny KDF haseł.
7. Dodać wygasanie sesji, rate limiting i role użytkowników.
8. Wdrożyć weryfikację fingerprintów SSH.
9. Ograniczyć proxy zdalnego API do listy dozwolonych operacji.
10. Poprawić aktualizator i podpisy repozytorium.
11. Ujednolicić packaging i wersjonowanie.
12. Usunąć zdublowany frontend oraz pliki zapasowe.
13. Uzupełnić i18n i testy automatyczne.

## Wniosek

Kod zawiera wartościowe elementy funkcjonalne: model datacenter/cluster/node,
cache inwentarza, integrację SSH i API, blokadę zarządzania oraz próbę rollbacku
operacji klastrowych. Największym problemem nie jest jednak funkcjonalność, lecz
granica bezpieczeństwa. Centralny manager posiada uprawnienia do wielu hostów,
dlatego każda niezabezpieczona ścieżka API ma wpływ na cały zarządzany klaster.

Do czasu wykonania punktów krytycznych aplikacja powinna działać wyłącznie w
izolowanym środowisku deweloperskim i nie powinna być dostępna z niezaufanej
sieci.
