GDPR a ochrana osobných údajov
Ochrana osobných údajov od návrhu
qr3.app je od základu navrhnutý v súlade s GDPR:
- Pseudonymizácia IP adries — IP adresy sa v Edge Workeri okamžite konvertujú na denné pseudonymy HMAC-SHA-256 UTC. Pôvodná IP adresa sa nikdy neukladá; pseudonym zostáva osobným údajom.
- Minimalizácia údajov — Zaznamenávajú sa iba údaje nevyhnutné na prevádzku.
Privacy API
Súhrn údajov (čl. 15 GDPR)
GET /v1/account/privacy — Vracia prehľad všetkých uložených údajov.
curl https://qr3.app/v1/account/privacy \ -H "Authorization: Bearer qr3_sk_..."Response:
{ "data": { "workspace_id": "ws_xxx", "organization_id": "org_xxx", "account": { "name": "Alex Example", "locale": "en", "created_at": "2026-01-15T09:00:00.000Z" }, "stored_data": { "qr_codes": 42, "scan_records": 15000, "dpp_scan_records": 3200, "dashboard_activity_records": 0, "dashboard_document_activity_records": 36, "api_operation_records": 180, "webhook_delivery_records": 640, "api_keys": 2, "webhooks": 1, "dpp_passports": 12, "dpp_documents": 30, "files": 4, "gs1_identifiers": 2, "gs1_verification_requests": 1, "code_comments": 5, "audit_log_entries": 0, "dpp_import_jobs": 1, "workspace_members": 3, "scan_quota_alerts": 1 }, "gdpr_rights": { "access": "GET /v1/account/privacy", "export": "GET /v1/account/export", "erasure": "DELETE /v1/account", "consents": "GET /v1/account/privacy/consents" }, "data_processing": { "ip_storage": "Purpose-separated HMAC-SHA-256 UTC-day IP pseudonym — pseudonymous personal data", "scan_retention": "90 days by default", "usage_retention": "90 UTC days", "webhook_delivery_retention": "90 UTC days", "pii_in_export": true, "erasure": "DELETE /v1/account erases the person's account: organizations they own with all workspaces and data (unless another org admin takes them over), their memberships in other organizations, their login and their Stripe customer. A running subscription ends immediately, without refund.", "backup_retention": "Erased rows stay restorable from the database backups (Cloudflare D1 Time Travel) for up to 30 days, then they are gone.", "billing_records": "Invoices stay with Stripe for the statutory retention period (7 years, § 132 BAO)." } }, "meta": { "request_id": "req_xxx" }}stored_data počíta uložené záznamy. scan_records sú skeny QR kódov, dpp_scan_records požiadavky na produktové pasy cez verejný DPP resolver. Oba obsahujú IP pseudonym.
dashboard_activity_records a dashboard_document_activity_records počítajú dni, keď člen otvoril dashboard (dve tabuľky), api_operation_records denné počítadlá požiadaviek podľa API kľúča, operácie a výsledku a webhook_delivery_records pokusy o doručenie webhookov vrátane pokusov vymazaných webhookov. Žiadna z nich neukladá IP adresu ani User-Agent; log doručenia však ukladá payload udalosti a prvý kilobajt (1 KB) odpovede príjemcu. Všetky štyri sa mažú po 90 dňoch UTC (usage_retention, webhook_delivery_retention).
account uvádza osobu, ktorá stojí za požiadavkou — v dashboarde prihlásenú osobu, inak osobu, ktorá vytvorila kľúč — s e-mailom, menom, jazykom a dátumom vytvorenia; pri Publishable Key je hodnota null. Ostatné počítadlá pokrývajú každú ďalšiu tabuľku s údajmi účtu: produktové pasy, dokumenty DPP, súbory, identifikátory GS1, komentáre, záznamy auditu, behy importu, členov workspace a upozornenia na kvótu organizácie (scan_quota_alerts). Mäkko vymazané riadky sa započítavajú, pretože sú stále uložené. erasure, backup_retention a billing_records opisujú, čo DELETE /v1/account vymaže a čo ešte nejaký čas zostáva; pii_in_export je true, pretože export uvádza osobu (e-mail, meno) — IP pseudonymy nikdy neopúšťajú databázu.
Export údajov (čl. 20 GDPR — prenosnosť údajov)
GET /v1/account/export — Stiahne všetky údaje ako JSON súbor.
curl https://qr3.app/v1/account/export \ -H "Authorization: Bearer qr3_sk_..." \ -o my-data.jsonExport obsahuje:
- Všetky QR kódy (vrátane vymazaných)
- Agregované štatistiky skenovania (žiadne surové IP hashe)
- Agregované požiadavky na DPP pre každý produktový pas (
dpp_scan_aggregates, takisto bez IP hashov) - Agregované štatistiky používania (
dashboard_activity_aggregates,api_operation_aggregates): aktívne dni a počet aktívnych používateľov podľa kanála dashboardu, počítadlá požiadaviek podľa operácie a výsledku — bez ID používateľov a kľúčov - Agregované pokusy o doručenie webhookov podľa webhooku a typu udalosti (
webhook_delivery_aggregates), bez payloadu a odpovede - Osobu, ktorá stojí za požiadavkou (
account), organizáciu (organization; fakturačnú a notifikačnú adresu len pre správcov organizácie) a workspace (workspace) - Produktové pasy, metadáta dokumentov DPP a súborov (nie samotné súbory), identifikátory GS1, žiadosti o ich overenie a behy importu (
dpp_passports,dpp_documents,files,gs1_identifiers,gs1_verification_requests,dpp_import_jobs) - Komentáre bez polí autora (
code_comments), záznamy auditu ako agregáty (audit_log_aggregates) a členov podľa roly (member_aggregates) - API kľúče bez ID a hashu (
api_keys), webhooky bez URL a tajomstva (webhooks) a upozornenia na kvótu organizácie (scan_quota_alerts) - Časové pečiatky vytvorenia a zmeny
Publishable Keys (qr3_pk_) dostanú 403: súbor obsahuje cieľové adresy a poznámky všetkých kódov.
Vymazanie účtu (čl. 17 GDPR — právo na zabudnutie)
DELETE /v1/account — Okamžite a nevratne vymaže účet osoby, ktorá stojí za požiadavkou: v dashboarde prihlásenú osobu, inak osobu, ktorá vytvorila kľúč. Žiadosť o vymazanie e-mailom vedie k rovnakému vymazaniu: prevádzkovateľ vymaže prihlásenie v Clerk a qr3 potom vymaže účet.
curl -X DELETE https://qr3.app/v1/account \ -H "Authorization: Bearer qr3_sk_..."Čo sa stane:
- Organizácie, ktoré patria osobe, sa vymažú so všetkými workspace, kódmi, produktovými pasmi, súbormi, štatistikami a logmi vrátane ich súborov v úložisku. Ak má takáto organizácia ďalšieho aktívneho správcu organizácie, namiesto toho ju prevezme ten s najdlhším pôsobením — aj s údajmi a predplatným.
- Predplatné: prebiehajúce predplatné sa končí okamžite, bez pomerného vrátenia peňazí a bez záverečnej faktúry; potom sa vymaže zákazník v Stripe. Faktúry zostávajú v Stripe počas zákonnej lehoty uchovávania (7 rokov, § 132 BAO).
- Tímy: členstvá osoby v iných organizáciách sa končia; tieto tímy si ponechávajú svoje údaje. Komentáre osoby už neuvádzajú autora, jej záznamy auditu strácajú IP pseudonym a user agent a API kľúče, ktoré tam vytvorila, sa zrušia.
- Osoba: prihlásenie (Clerk) a používateľský záznam sa vymažú.
Odpoveď je 200 so status: "completed" a počítadlami organizations_deleted, organizations_transferred, memberships_removed a login_deleted. Pri veľmi veľkých organizáciách jedna požiadavka nestačí: odpoveď je potom 202 so status: "in_progress" a vymazanie sa v priebehu niekoľkých hodín dokončí samo.
Vyžaduje Secret alebo Test Key s právom zápisu alebo reláciu v dashboarde (akákoľvek rola, pretože ide o vlastný účet). Publishable Keys a kľúče len na čítanie dostanú 403, kľúč bez osoby za ním (created_by = 'system') dostane 409. 503 znamená, že nasadeniu chýba tajomstvo, ktoré vymazanie potrebuje; nič sa nevymazalo.
Správa súhlasov
GET /v1/account/privacy/consents — Získanie aktuálnych súhlasov.
POST /v1/account/privacy/consents — Aktualizácia súhlasov.
# Načítanie aktuálnych súhlasovcurl https://qr3.app/v1/account/privacy/consents \ -H "Authorization: Bearer qr3_sk_..."
# Vypnutie marketingových e-mailovcurl -X POST https://qr3.app/v1/account/privacy/consents \ -H "Authorization: Bearer qr3_sk_..." \ -H "Content-Type: application/json" \ -d '{ "marketing_emails": false, "analytics": true, "product_updates": true }'Polia súhlasu:
| Pole | Predvolené | Popis |
|---|---|---|
marketing_emails | false | Newsletter a reklamné e-maily |
analytics | true | Agregované štatistiky používania |
product_updates | true | Novinky o produktoch a changelogy |
Zmena súhlasov vyžaduje oprávnenie na zápis: rola viewer a Publishable Keys dostanú 403.
Technická implementácia GDPR
Pseudonymizácia IP adries (čl. 25 GDPR)
HTTP požiadavka → Cloudflare Edge Worker ↓Hlavička CF-Connecting-IP → HMAC-SHA-256(IP_HASH_SALT, účel, deň UTC, IP) ↓ip_hash (denný pseudonym) → databáza D1 ↓Pôvodná IP adresa sa nikdy neukladáIP_HASH_SALT je dlhodobé hlavné tajomstvo; účel a deň UTC automaticky odvodzujú oddelené denné pseudonymy. Pseudonymy z rôznych dní UTC nie sú priamo rovnaké, držiteľ tajomstva však môže pre konkrétny deň znovu vypočítať známeho kandidáta IP adresy. Nepoužíva sa denná soľ v KV ani ručná denná rotácia.
Uchovávanie údajov (automatizované)
| Predplatné | Uchovávanie |
|---|---|
| Všetky programy | 90 dní |
Štatistiky používania (aktivita v dashboarde, počítadlá používania API) a logy doručenia webhookov sa tiež uchovávajú 90 dní UTC: aktuálny deň UTC a 89 predchádzajúcich dní. Tá istá denná úloha cron maže staršie riadky (purgeOldDashboardActivity, purgeOldApiOperationUsage, purgeOldWebhookDeliveries).
DPA so subdodávateľmi
Spoločnosť Cloudflare, Inc. spracúva údaje ako sprostredkovateľ. Zmluva DPA je dostupná na adrese cloudflare.com/cloudflare-customer-dpa.
Cloudflare spracúva údaje s lokalizačným tipom (location hint) pre región EÚ (okrem iného Frankfurt); zmluvne garantovaná jurisdikcia EÚ nie je v súčasnosti predplatená. Keďže spoločnosť Cloudflare, Inc. sídli v USA, ako základ pre prenos platia štandardné zmluvné doložky (SCC) podľa čl. 46 GDPR.
Kontakt
- Zodpovedná osoba za ochranu osobných údajov: [email protected]
- Zmluva o spracúvaní osobných údajov (AVV): [email protected] (na vyžiadanie)
- Zásady ochrany osobných údajov: qr3.app/de/legal/datenschutz