Preskočiť na obsah
Táto stránka je dostupná aj v: Čeština, English, Українська

Bezpečnosť — technický detail

Aktualizované: 7. mája 2026

Hľadáte verziu zrozumiteľnú pre bežného používateľa? Prečítajte si Ako chránime vaše údaje. Táto stránka je jej implementačne verný náprotivok — písaná pre vývojárov, bezpečnostných výskumníkov a partnerov robiacich due diligence. Je to vecný popis primitív, ktoré máme nasadené v produkcii.

I. Identitné údaje — Bank iD a Stripe Identity

Na overenie, že naši profesionáli môžu legálne pracovať, používame dvoch externých poskytovateľov KYC. Žiadny z nich neukladá citlivé identitné údaje trvalo na našich serveroch.

Bank iD (OIDC). Keď si pracovník zvolí overenie cez Bank iD, jeho banka podpíše JWT obsahujúci iba overené polia (meno, dátum narodenia, adresa, číslo dokladu) — nikdy prístupové údaje k banke. Token verifikujeme oproti verejnému JWKS Bank iD (env BANKID_JWKS_URL) a štruktúrovaný výsledok persistujeme do worker_identity_verifications. Surový token po overení zahodíme.

Stripe Identity. Keď si pracovník zvolí naskenovanie dokladu, jeho zariadenie nahráva obrázky priamo do Stripe — fyzické snímky pasu / OP nikdy neprechádzajú našou backendovou infraštruktúrou. Stripe nám pošle webhook s verified | requires_input | canceled a štruktúrovanými poľami (meno, dátum narodenia, číslo dokladu) cez náš jediný KYC endpoint v worker-identity.service.ts. Snímky zostávajú u Stripe pod ich retenčnou politikou.

Audit a retencia. Každá zmena stavu sa zapisuje do worker_identity_audit_events (modul worker-identity-audit). Štruktúrované údaje o overení držíme po dobu zákonom požadovanú pre pracovnoprávny vzťah; surové webhook payloady a pending-verification relácie čistíme po 60 dňoch.

II. Tokeny a relácie

Pri prihlásení klient dostane dva tokeny: krátkodobý JWT access token (15 minút) a opakovane použiteľný refresh token (14 dní klzavo, 365 dní absolútne).

Refresh token je opaque. 64 znakov hexadecimálneho náhodného reťazca — nie JWT. Nemožno ho "rozšifrovať" mimo nášho backendu. Pri každom použití je rotovaný: starý token sa okamžite označí ako spotrebovaný, vystaví sa nový.

Detekcia zneužitia cez family_id. Každý refresh token nesie family_id, ktoré identifikuje rodičovskú autorizáciu (napr. pôvodné prihlásenie z konkrétneho zariadenia). Ak je spotrebovaný token z tej istej rodiny predložený znova — kdekoľvek vo svete — revokujeme celú rodinu okamžite a všetky aktívne relácie odvodené z tejto autorizácie sa odhlásia. To detekuje krádež cookies / replay útoky v priebehu sekúnd. Implementácia: apps/api/src/modules/auth/, tabuľka refresh_tokens.

Aktívne zariadenia. Na /account/security/sessions (web) a /sessions (mobile) používateľ vidí všetky aktívne relácie, ich poslednú aktivitu a zariadenie / lokalitu (z User-Agent + aktuálnej IP — historické IP sa neperzistujú). Relácie možno revokovať individuálne alebo hromadne; revokácia zneplatní rodinu, nie iba jeden token.

III. Súbory a dokumenty

Zmluvy, profilové fotky, doklady k zákazkám — všetko, čo používatelia do FixIt nahrajú, ukladáme na vlastnom MinIO clusteri (S3-kompatibilný), nie vo verejne prístupnej CDN.

Databáza nikdy neukladá URL. Persistujeme iba object key (napr. users/abc123/avatar.jpg). URL skladáme až pri response v AssetUrlService (apps/api/src/modules/storage/asset-url.service.ts) — každý URL má krátku platnosť a storage providerov možno meniť bez prepisovania databázy.

Trojstupňová prístupová kontrola (apps/api/src/modules/storage/storage.controller.ts):

  1. Public assets (logá firiem, profilové fotky verejných remeselníkov) — bez autorizácie, ale vystavené ako signed URL s krátkou expiráciou.
  2. Authenticated assets (zmluvy, doklady k zákazkám) — JWT validácia + overenie vlastníctva predtým, než vystavíme signed URL.
  3. Tenant-scoped assets (interné firemné dokumenty) — kontrolujeme aj X-Active-Company-Id header, takže admin firmy A nemá prístup k súborom firmy B.

IV. Šifrovanie v prenose aj v pokoji

V prenose. TLS 1.3 (povinne), HSTS s preload subdomén, CSP s nonce. Konfigurácia na nginx reverse proxy s Cloudflare ako WAF. Všetka prevádzka medzi mobilnou/web aplikáciou a API je šifrovaná medzi klientom a naším edge.

V pokoji. PostgreSQL 16 s šifrovaním na úrovni disku (LUKS na hostiteľovi). Zálohy databázy sú šifrované samostatným kľúčom a uložené mimo databázového containera — pozri bun run db:backup:dev / db:backup:staging / db:backup:prod, ktoré volajú on-VPS backup skript.

Cross-tenant scope safety. Verejné dotazy na tabuľku companies prechádzajú cez excludePlatformCompany() (apps/api/src/common/scopes/exclude-platform-company.scope.ts) — interný FIXIT_PLATFORM shell employer tak nemôže preniknúť do verejných listingov, vyhľadávania ani Elasticsearch indexácie.

Vstupy používateľa. Voľný text prechádza stripHtmlTags() sanitizáciou (apps/api/src/common/utils/sanitize.utils.ts) predtým, než ho uložíme — žiadny regex, len overený parser. Podozrivé HTML a nulové bajty zachytí globálny SanitizeNullBytesInterceptor. URL zadané používateľom (napr. odkaz na portfólio) prechádzajú SSRF guard (@fixit/url-security) predtým, než si ich server stiahne.

V. GDPR a kontakty

FixIt App s.r.o. je správcom osobných údajov podľa článku 4 GDPR. Naše Zásady ochrany osobných údajov popisujú právny rámec a vaše práva.

Hlásenie bezpečnostných incidentov. Ak objavíte zraniteľnosť, ozvite sa nám na security@fixit.app. Reagujeme do 48 hodín. Nezverejňujte zraniteľnosť verejne pred opravou — postupujeme v duchu coordinated disclosure.


Táto stránka je vecný popis. Ak nájdete nesúlad medzi tým, čo je tu popísané, a tým, čo skutočne robíme, je to bug — pošlite to na security@fixit.app a opravíme to.