Fleet Agent — Developer Reference
Fleet Agent — Developer Reference
Section titled “Fleet Agent — Developer Reference”Sencai fleet vrstva se skládá z lehké Go binárky, sencai-agent, která běží
na spravovaných hostech (VM/bare-metal), a Go control-plane služby,
agent-gateway, která agenty enrolluje a přemosťuje jejich
WebSocket-over-TLS (WSS) spojení do Strapi. Samostatná, nesouvisející
komponenta, k8s-agent, obsluhuje Kubernetes clustery a nejde přes
agent-gateway — viz Kubernetes fleet agent níže.
ssh-proxy-service (port 3400) není součástí této architektury — pouze
proxíruje browser-based SSH terminálové relace na cloudové instance a nemá
žádný vztah k sencai-agent ani agent-gateway.
Architektura
Section titled “Architektura”Spravovaný host / VM├── sencai-agent (Go binary)│ ├── mTLS klient → agent-gateway (WSS, port 4400)│ ├── patch management (internal/patch)│ ├── software inventář + EOL detekce (internal/inventory)│ ├── CIS/Lynis hardening scan (internal/cis)│ ├── log shipping do Loki (internal/logshipper)│ ├── Prometheus Pushgateway export, opt-in (internal/pushgateway)│ └── runbook executor (internal/runbook)│agent-gateway (Go, port 4400)├── POST /enroll — bootstrap, bez auth, ověřuje token proti Strapi├── GET /ws — mTLS, heartbeat + server-push kanál├── GET /health — liveness probe├── POST /bulk-action — X-Service-Secret, jen server-side volající├── GET /fleet-status — X-Service-Secret, jen server-side volající├── POST /dispatch-runbook — X-Service-Secret, jen server-side volající└── POST /dispatch-exec — X-Service-Secret, jen server-side volajícíZdroj: sencai-agent/ (agent binárka), agent-gateway/ (control-plane
služba). Oba jsou nezávislé Go repozitáře, oddělené od k8s-agent/.
Enrollment flow
Section titled “Enrollment flow”- Pro záznam
sencai-agentv Strapi se vygeneruje enrollment token (stavpending, org-scoped). - Agent pošle
POST <gateway>/enrolls{enrollment_token, hostname, os, arch, version}. Tento endpoint nevyžaduje žádný klientský certifikát — je to bootstrap krok. agent-gatewayověří token proti Strapi (odpovídající záznamsencai-agentmusí mítstatus: pending), a poté sám vygeneruje keypair i certifikát: self-signed CA (4096-bit RSA, 10 let platnosti, uložená pod/etc/agent-gateway/) vystaví per-agent leaf certifikát (2048-bit RSA, 1 rok platnosti,CommonNamenastavené na StrapidocumentIdagenta). Agent si negeneruje vlastní keypair.- Gateway aktivuje agenta ve Strapi (
status: active, uložícert_fingerprint) a vrátí{agent_id, cert, key, ca_cert, capabilities}. - Agent zapíše certifikát, klíč a CA bundle do
/etc/sencai-agent/certs/a svoji konfiguraci do/etc/sencai-agent/config.yaml. sencai-agent startotevře mTLS WSS spojení na/wsa zahájí heartbeat smyčku.
sencai-agent enroll --gateway https://agent-gateway:4400 --token <token>sencai-agent startInstalace
Section titled “Instalace”curl -fsSL https://agent.sencai.space/install.sh \ | SENCAI_GATEWAY_URL=https://agent-gateway:4400 SENCAI_TOKEN=<token> bashPodepsané .deb/.rpm balíčky (sestavené přes nfpm, GPG-podepsané) jsou
také publikovány k tagged GitHub releasům sencai-agent; na
Debian/Ubuntu hostech instalátor nejprve nabídne cestu přes balíček, než
spadne zpět na raw binárku.
Heartbeat
Section titled “Heartbeat”Jakmile je agent připojen přes mTLS GET /ws kanál, posílá heartbeat každých
30 sekund s cpu_percent, memory_used_bytes a disk_used_bytes. Zápisy
heartbeatu do Strapi (last_heartbeat_at) jsou na straně gateway
rate-limitované jako ochrana proti connection stormům.
{ "type": "heartbeat", "agent_id": "...", "timestamp": 1718900000, "cpu_percent": 12.5, "memory_used_bytes": 1073741824, "disk_used_bytes": 21474836480}Porty a endpointy agent-gateway
Section titled “Porty a endpointy agent-gateway”agent-gateway naslouchá na jediném portu, 4400 (HTTPS/WSS). Neexistuje
žádný oddělený metrics port.
| Endpoint | Autentizace | Účel |
|---|---|---|
POST /enroll | žádná (bootstrap) | Výměna enrollment tokenu za mTLS certifikát |
GET /ws | mTLS klientský certifikát | Heartbeat kanál + server-push (capabilities_update, revoke, execute_runbook) |
GET /health | žádná | Liveness probe |
POST /bulk-action | X-Service-Secret | Jen server-side — hromadné fleet operace |
GET /fleet-status | X-Service-Secret | Jen server-side — agregovaný stav fleetu |
POST /dispatch-runbook | X-Service-Secret | Jen server-side — spouští vykonání runbooku na agentovi |
POST /dispatch-exec | X-Service-Secret | Jen server-side — spouští whitelistovanou exec akci |
Endpointy chráněné X-Service-Secret volají pouze jiné backendové služby
(nikdy přímo agenti nebo prohlížeče).
Software inventář
Section titled “Software inventář”V celém fleet stacku není žádná integrace osquery. Inventář sbírá
internal/inventory v sencai-agent, gatovaný capability inventory:scan:
- Čte nainstalované balíčky přes
dpkg-query(Debian/Ubuntu) neborpm -qa(RHEL/Fedora/CentOS). - Porovnává verze balíčků proti API
endoflife.date, aby označil balíčky blížící se nebo již za koncem životnosti, klasifikované jakocritical,warningneboinfourgence. - Běží na staggered rozvrhu: start 10 minut po bootu agenta, poté opakování každých 24 hodin.
CIS / Lynis hardening scan
Section titled “CIS / Lynis hardening scan”internal/cis spouští:
lynis audit system --quiet --no-log --no-colors --cronjobTo vyžaduje, aby binárka lynis byla na hostu již přítomná — pokud
nainstalovaná není, scan goroutine tiše skončí bez chyby (žádný výsledek
scanu se nevyprodukuje). Start je 15 minut po bootu agenta, poté se opakuje
každých 24 hodin. Neexistuje žádný pevný denní rozvrh (např. 02:00) ani
endpoint /api/fleet/nodes/:nodeId/compliance-report — výsledky se parsují
ze stdout výstupu Lynis (hardening score, počet testů, warningy) a zpracovává
je interně agent/gateway pipeline.
Patch management
Section titled “Patch management”internal/patch detekuje package manager hosta (apt, dnf nebo
zypper), vypíše dostupné aktualizace (Scan(), gatováno capability
patch_management:scan) a umí je nainstalovat (Apply(), gatováno
capability patch_management:apply). InMaintenanceWindow() parsuje
zjednodušený cron-like výraz (hodina + den v týdnu), aby omezil Apply() na
nakonfigurovaná maintenance okna. Scan startuje 5 minut po bootu a opakuje se
každých 24 hodin.
Log shipping do Loki
Section titled “Log shipping do Loki”internal/logshipper čte systemd journal (journalctl --output=short-iso) a
logové soubory odpovídající konfigurovatelným glob patternům (výchozí:
/var/log/syslog, /var/log/messages, /var/log/*.log). Před odesláním
redaguje z každého řádku PII — emailové adresy, IPv4 adresy, MAC adresy,
key/value páry vypadající jako credentials a čísla platebních karet — a poté
posílá dávky na Loki push API (tagované X-Scope-OrgID pro tenant izolaci).
Gatováno capabilities log_shipping:system / log_shipping:app, ve výchozím
stavu vypnuté, dokud se v konfiguraci agenta nenastaví
log_shipping_enabled a loki_url.
Prometheus Pushgateway export (opt-in)
Section titled “Prometheus Pushgateway export (opt-in)”internal/pushgateway posílá tři gauge metriky
(sencai_agent_cpu_percent, sencai_agent_memory_used_bytes,
sencai_agent_disk_used_bytes) na Prometheus Pushgateway při každém
heartbeatu. Je to zcela opt-in: jediný způsob, jak to zapnout, je nastavit
proměnnou prostředí SENCAI_PUSHGATEWAY_URL. Bez ní se agent chová přesně
jako předtím, bez jakéhokoliv dodatečného síťového provozu.
Vykonávání runbooků
Section titled “Vykonávání runbooků”Vykonávání runbooků je pevný whitelist, ne obecný YAML/shell-command formát. Jediné povolené akce jsou:
restart_serviceclear_disk_spacekill_processrun_approved_script— omezeno na skripty pod/etc/sencai-agent/scripts/
Dispatch flow:
- Volající (pouze server-side) pošle
POST /dispatch-runbooknaagent-gateways hlavičkouX-Service-Secret. agent-gatewayodešle WS zprávu cílovému agentovi:{type: "execute_runbook", execution_id, actions, dry_run}.- Agent (
internal/runbook) prosazuje rate limit 5 vykonání za hodinu na akci, sledovaný v paměti a resetovaný při restartu agenta. - Výsledek se vrací jako WS zpráva
{type: "runbook_result", ...}s výsledkem per-akce a celkovým success flagem.
Neexistuje žádný HTTP POST /runbook-result endpoint — výsledek putuje zpět
přes stejné WS spojení.
Karanténa
Section titled “Karanténa”Karanténa je iniciovaná serverem a probíhá na úrovni OS — agent se
nekarantinuje sám. Když je karanténa spuštěna z Fleet dashboardu
(podložena Strapi content-typy quarantine-policy / quarantine-event),
spustí se handler internal/quarantine v agent-gateway, který na cílovém
hostu (pouze Linux, vyžaduje passwordless sudo) provede:
sudo iptables -I OUTPUT -j DROP -m comment --comment sencai-quarantine-<agentID>Uvolnění karantény odstraní tagované pravidlo (nalezené podle komentáře
sencai-quarantine-<agentID>). V tomto flow neexistuje žádný krok “Action
Gateway approval” — samostatná Action Gateway služba neexistuje; viz
dev/gateway.md pro to, co skutečně existuje.
Self-update
Section titled “Self-update”sencai-agent update zkontroluje novou podepsanou verzi a aplikuje ji:
- Stažené binárky a checksumy jsou podepsané
cosign sign-blob(keyless, přes GitHub OIDC); agent před nahrazením sebe sama ověří SHA-256 checksum. - Výměna binárky je atomická (
os.Rename), předchozí binárka zůstává jako.baksoubor pro rollback, pokud nová verze selže na health checku. - Rollout je rozdělen do ringů (10 % / 50 % / 100 %) přiřazovaných
deterministicky podle
agent_idagenta, takže vadný release zasáhne jen zlomek fleetu, než se rozšíří dál.
Supply-chain podepisování
Section titled “Supply-chain podepisování”- Binárky: cross-compilované pro linux/amd64 a linux/arm64, podepsané
cosign sign-blob(keyless, na základě GitHub OIDC), spolu se SPDX SBOM vygenerovanýmanchore/sbom-action. - Balíčky:
.deb/.rpmbalíčky jsou sestavené přesnfpma GPG-podepsané na tagged releasech.
cosign verify-blob \ --certificate sencai-agent-linux-amd64.pem \ --signature sencai-agent-linux-amd64.sig \ sencai-agent-linux-amd64Kubernetes fleet agent
Section titled “Kubernetes fleet agent”k8s-agent je samostatný, čistě deployment repozitář — neobsahuje žádný
Go zdrojový kód. Obsahuje Helm chart (helm/sencai-agent/) a plochý manifest,
oba nasazují stejný předpřipravený image,
ghcr.io/sencai/sencai-agent:dev-latest, publikovaný z release pipeline
repozitáře sencai-agent.
Nejde o „DaemonSet variantu stejné binárky” jdoucí přes agent-gateway —
Kubernetes clustery používají zcela oddělenou cestu. In-cluster agent
reportuje read-only cluster metriky (počty node/pod/namespace, verzi
clusteru) každých 30 sekund přes:
POST /api/k8s-agents/<id>/heartbeatX-K8s-Agent-Token: <token>přímo do Strapi. S agent-gateway vůbec nekomunikuje. Konfigurace
(sencai.apiUrl, sencai.registrationToken, sencai.organisationId) se
dodává přes Helm values.yaml nebo ConfigMap/Secret plochého manifestu.
Řešení problémů
Section titled “Řešení problémů”Agent se neobjevuje ve Fleet dashboardu po enrollmentu
Section titled “Agent se neobjevuje ve Fleet dashboardu po enrollmentu”Ověřte, že je gateway URL dostupné z hostu a že záznam sencai-agent ve
Strapi je stále pending (již použitý nebo expirovaný token vrátí z
/enroll 401). Zkontrolujte logy agenta:
journalctl -u sencai-agent -n 50Selhání mTLS handshake / problémy s certifikátem
Section titled “Selhání mTLS handshake / problémy s certifikátem”Znovu proveďte enrollment, abyste získali nový certifikát:
sencai-agent enroll --gateway <url> --token <new-token>CLI sencai-agent v současnosti u enroll vystavuje pouze --gateway a
--token — žádný zdokumentovaný přepínač --force neexistuje; před
spoléháním se na něj ověřte se service ownerem.
Lynis scan nikdy neprodukuje výsledek
Section titled “Lynis scan nikdy neprodukuje výsledek”Binárka lynis musí být na hostu již nainstalovaná — internal/cis ji
neinstaluje a scan tiše přeskočí, pokud chybí.