BDAR ir duomenų apsauga
Privatumo užtikrinimas projektavimo stadijoje (Privacy-by-Design)
qr3.app yra sukurtas nuo pat pradžių laikantis BDAR reikalavimų:
- IP adresų pseudoniminimas — IP adresai Edge Worker iškart paverčiami HMAC-SHA-256 UTC dienos pseudonimais. Tikrasis IP adresas niekada nesaugomas; pseudonimas lieka asmens duomenimis.
- Duomenų mažinimas — renkami tik tie duomenys, kurie yra būtini paslaugos veikimui.
Privatumo API
Duomenų suvestinė (BDAR 15 str.)
GET /v1/account/privacy — grąžina visų saugomų duomenų apžvalgą.
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 skaičiuoja saugomus įrašus. scan_records – tai QR kodų nuskaitymai, dpp_scan_records – užklausos į produktų pasus per viešąjį DPP resolverį. Abiejuose yra IP pseudonimas.
dashboard_activity_records ir dashboard_document_activity_records skaičiuoja dienas, kai narys atidarė valdymo skydelį (dvi lentelės), api_operation_records — kasdienius užklausų skaitiklius pagal API raktą, operaciją ir rezultatą, o webhook_delivery_records — webhook pristatymo bandymus, įskaitant ištrintų webhook bandymus. Nė vienoje iš jų nesaugomas IP adresas ar User-Agent; pristatymo žurnale tačiau saugomas įvykio payload ir pirmasis kilobaitas (1 KB) gavėjo atsakymo. Visi keturi ištrinami po 90 UTC dienų (usage_retention, webhook_delivery_retention).
account nurodo asmenį, pateikusį užklausą — valdymo skydelyje prisijungusį asmenį, kitu atveju raktą sukūrusį asmenį — su el. paštu, vardu, kalba ir sukūrimo data; Publishable Key atveju reikšmė yra null. Kiti skaitikliai apima kiekvieną kitą lentelę su paskyros duomenimis: produktų pasus, DPP dokumentus, failus, GS1 identifikatorius, komentarus, audito įrašus, importavimo vykdymus, workspace narius ir organizacijos kvotos pranešimus (scan_quota_alerts). Švelniai ištrintos eilutės skaičiuojamos, nes jos vis dar saugomos. erasure, backup_retention ir billing_records aprašo, ką ištrina DELETE /v1/account ir kas dar kurį laiką lieka; pii_in_export yra true, nes eksportas nurodo asmenį (el. paštą, vardą) — IP pseudonimai niekada nepalieka duomenų bazės.
Duomenų eksportavimas (BDAR 20 str. — duomenų perkeliamumas)
GET /v1/account/export — atsisiunčia visus duomenis kaip JSON failą.
curl https://qr3.app/v1/account/export \ -H "Authorization: Bearer qr3_sk_..." \ -o my-data.jsonEksportuojamame faile yra:
- Visi QR kodai (įskaitant ištrintus)
- Agreguota nuskaitymų statistika (be neapdorotų IP maišos reikšmių)
- Agreguotos DPP užklausos pagal produkto pasą (
dpp_scan_aggregates, taip pat be IP maišos reikšmių) - Naudojimo statistika agregatų pavidalu (
dashboard_activity_aggregates,api_operation_aggregates): aktyvios dienos ir aktyvių naudotojų skaičius pagal valdymo skydelio kanalą, užklausų skaitikliai pagal operaciją ir rezultatą — be naudotojų ir raktų ID - Webhook pristatymo bandymai pagal webhook ir įvykio tipą (
webhook_delivery_aggregates), be payload ir atsakymo - Užklausą pateikusį asmenį (
account), organizaciją (organization; atsiskaitymo ir pranešimų adresas tik organizacijos administratoriams) ir workspace (workspace) - Produktų pasus, DPP dokumentų ir failų metaduomenis (ne pačius failus), GS1 identifikatorius, prašymus juos patvirtinti ir importavimo vykdymus (
dpp_passports,dpp_documents,files,gs1_identifiers,gs1_verification_requests,dpp_import_jobs) - Komentarus be autoriaus laukų (
code_comments), audito įrašus kaip agregatus (audit_log_aggregates) ir narius pagal rolę (member_aggregates) - API raktus be ID ir maišos (
api_keys), webhook be URL ir paslapties (webhooks) ir organizacijos kvotos pranešimus (scan_quota_alerts) - Sukūrimo ir keitimo laiko žymos
Publishable Keys (qr3_pk_) gauna 403: faile yra visų kodų paskirties adresai ir pastabos.
Paskyros trynimas (BDAR 17 str. — teisė būti pamirštam)
DELETE /v1/account — Nedelsiant ir negrįžtamai ištrina užklausą pateikusio asmens paskyrą: valdymo skydelyje prisijungusio asmens, kitu atveju raktą sukūrusio asmens. Prašymas ištrinti el. paštu lemia tą patį ištrynimą: paslaugos teikėjas ištrina prisijungimą per Clerk, o qr3 po to ištrina paskyrą.
curl -X DELETE https://qr3.app/v1/account \ -H "Authorization: Bearer qr3_sk_..."Kas vyksta:
- Asmeniui priklausančios organizacijos ištrinamos su visomis workspace, kodais, produktų pasais, failais, statistika ir žurnalais, įskaitant jų failus saugykloje. Jei tokia organizacija turi kitą aktyvų organizacijos administratorių, vietoj to ją kartu su duomenimis ir prenumerata perima ilgiausiai šias pareigas einantis administratorius.
- Prenumerata: galiojanti prenumerata baigiasi nedelsiant, be proporcingo pinigų grąžinimo ir be galutinės sąskaitos faktūros; po to ištrinamas Stripe klientas. Sąskaitos faktūros lieka Stripe įstatymų nustatytą saugojimo laikotarpį (7 metai, § 132 BAO).
- Komandos: asmens narystės kitose organizacijose baigiasi; tos komandos išsaugo savo duomenis. Asmens komentaruose nebenurodomas autorius, iš jo audito įrašų pašalinami IP pseudonimas ir user agent, o jo ten sukurti API raktai atšaukiami.
- Asmuo: prisijungimas (Clerk) ir naudotojo įrašas ištrinami.
Atsakymas yra 200 su status: "completed" ir skaitikliais organizations_deleted, organizations_transferred, memberships_removed ir login_deleted. Labai didelėms organizacijoms vienos užklausos nepakanka: tada atsakymas yra 202 su status: "in_progress", o ištrynimas automatiškai užbaigiamas per kelias valandas.
Reikia Secret arba Test Key su rašymo teise arba valdymo skydelio sesijos (bet kuri rolė, nes tai asmens nuosava paskyra). Publishable Keys ir tik skaitymo raktai gauna 403, raktas be asmens (created_by = 'system') gauna 409. 503 reiškia, kad diegimui trūksta paslapties, kurios reikia ištrynimui; niekas nebuvo ištrinta.
Sutikimų valdymas
GET /v1/account/privacy/consents — gauti esamus sutikimus.
POST /v1/account/privacy/consents — atnaujinti sutikimus.
# Gauti dabartinius sutikimuscurl https://qr3.app/v1/account/privacy/consents \ -H "Authorization: Bearer qr3_sk_..."
# Išjungti rinkodaros el. laiškuscurl -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 }'Sutikimų laukai:
| Laukas | Numatytasis | Aprašymas |
|---|---|---|
marketing_emails | false | Naujienlaiškiai ir reklaminiai el. laiškai |
analytics | true | Agreguota naudojimo statistika |
product_updates | true | Produkto naujienos ir pakeitimų žurnalai (changelogs) |
Norint keisti sutikimus, reikalingos rašymo teisės: rolė viewer ir Publishable Keys gauna 403.
Techninis BDAR įgyvendinimas
IP adresų pseudoniminimas (BDAR 25 str.)
HTTP užklausa → Cloudflare Edge Worker ↓CF-Connecting-IP antraštė → HMAC-SHA-256(IP_HASH_SALT, paskirtis, UTC diena, IP) ↓ip_hash (dienos pseudonimas) → D1 duomenų bazė ↓Tikrasis IP adresas niekada nesaugomasIP_HASH_SALT yra ilgalaikė pagrindinė paslaptis; paskirtis ir UTC diena automatiškai išveda atskirus dienos pseudonimus. Skirtingų UTC dienų pseudonimai nėra tiesiogiai vienodi, tačiau paslapties turėtojas gali konkrečiai dienai perskaičiuoti žinomą IP kandidatą. Nenaudojama nei KV dienos druska, nei rankinė kasdienė rotacija.
Duomenų saugojimo laikotarpis (automatizuotas)
| Planas | Saugojimo laikotarpis |
|---|---|
| Visi planai | 90 dienų |
Naudojimo statistika (valdymo skydelio aktyvumas, API naudojimo skaitikliai) ir webhook pristatymo žurnalai taip pat saugomi 90 UTC dienų: einamoji UTC diena ir 89 ankstesnės dienos. Ta pati kasdienė cron užduotis ištrina senesnes eilutes (purgeOldDashboardActivity, purgeOldApiOperationUsage, purgeOldWebhookDeliveries).
Duomenų tvarkymo sutartis (DPA) su subrangovais
Cloudflare, Inc. tvarko duomenis kaip duomenų tvarkytojas. Duomenų tvarkymo sutartis (DPA) pateikiama adresu cloudflare.com/cloudflare-customer-dpa.
„Cloudflare“ tvarko duomenis su vietos nuoroda į ES regioną (be kita ko, Frankfurtą); sutartimi garantuota ES jurisdikcija šiuo metu nėra užsakyta. Kadangi „Cloudflare, Inc.“ yra įsikūrusi JAV, duomenų perdavimo pagrindas yra standartinės sutarčių sąlygos (SCC) pagal BDAR 46 str.
Kontaktai
- Duomenų apsaugos pareigūnas: [email protected]
- Duomenų tvarkymo sutartis (DPA): [email protected] (pagal užklausą)
- Privatumo politika: qr3.app/de/legal/datenschutz