diff --git a/docs/gdpr-legal-basis-registry.md b/docs/gdpr-legal-basis-registry.md new file mode 100644 index 0000000..35d57c8 --- /dev/null +++ b/docs/gdpr-legal-basis-registry.md @@ -0,0 +1,58 @@ +# GDPR Legal Basis Registry — CEO OS +# PRV-005 | CC-046 | 2026-07-31 +# Controller: AI Impact SRL (RO) / ADA MarkAI UG (DE) — DPO review required before production launch + +| # | Processing Activity | Data Categories | Data Subjects | Legal Basis (GDPR Art.) | Retention | Processor / Sub-processor | Transfer | High Risk | Notes | +|---|---------------------|-----------------|---------------|------------------------|-----------|--------------------------|----------|-----------|-------| +| 1 | User authentication & session management | email, hashed password, JWT, session tokens | Platform users | Art. 6(1)(b) — contract performance | Session lifetime; refresh tokens 30 days; JWT 1h | Supabase (EU) | EU only | No | Token stored in Supabase Auth; no plaintext password | +| 2 | Membership & RBAC | userId, tenantId, role, validFrom, validUntil | Platform users | Art. 6(1)(b) — contract performance | Duration of membership + 90 days post-termination | Supabase Postgres | EU only | No | Used to enforce data isolation | +| 3 | Audit log | actorId, tenantId, action, resource, timestamp | Platform users | Art. 6(1)(c) — legal obligation (traceability) / Art. 6(1)(f) — legitimate interest | 2 years; review at 1 year | Supabase Postgres | EU only | No | Contains userId permanently — erasure procedure required | +| 4 | Outbox events | tenantId, actorId, eventType, payload | Platform users (indirect) | Art. 6(1)(b) — contract performance | 30 days post-processing | Supabase Postgres | EU only | No | Processed events deleted by cleanup cron | +| 5 | Goals & strategic data | tenantId, ownerUserId, horizon, metric, target | Platform users | Art. 6(1)(b) — contract performance | Duration of account + 30 days post-deletion | Supabase Postgres | EU only | No | Soft delete; hard delete on account closure | +| 6 | Decisions | tenantId, ownerUserId, title, body, tags | Platform users | Art. 6(1)(b) — contract performance | Duration of account + 30 days | Supabase Postgres | EU only | No | Private records; no third-party sharing | +| 7 | Financial transactions | tenantId, organizationId, amountMinorUnits, currency, date | Platform users / Organizations | Art. 6(1)(c) — legal obligation (accounting) | 10 years (DE HGB § 257 / RO L 82/1991) | Supabase Postgres | EU only | No | amountMinorUnits stored as integer string; no float drift | +| 8 | Observations & opportunities | tenantId, ownerUserId, content | Platform users | Art. 6(1)(b) — contract performance | Duration of account + 30 days | Supabase Postgres | EU only | No | Append-only for observations | +| 9 | AI gateway requests | tenantId, actorId, prompt fragments, model response | Platform users | Art. 6(1)(b) — contract performance / Art. 6(1)(f) — legitimate interest (service quality) | 90 days | Supabase Postgres; AI provider (see below) | See below | Yes — automated decision | Prompts may contain personal data; AI provider sub-processor agreement required | +| 10 | Email notifications | email, name, notification content | Platform users | Art. 6(1)(b) — contract performance | Until account deletion | SMTP provider (TBD) | EU only preferred | No | Provider DPA required | +| 11 | Application logs (pino) | IP address (indirect), requestId, correlationId | Platform users | Art. 6(1)(f) — legitimate interest (security, debugging) | 30 days | Host server (Hetzner, DE) | EU only | No | IP addresses not logged at application level — confirm at infra level | + +--- + +## Sub-processors (current) + +| Sub-processor | Country | Purpose | DPA in place | Notes | +|---------------|---------|---------|-------------|-------| +| Supabase (PostgreSQL) | EU (AWS eu-central-1) | Database, Auth | Yes (Supabase standard DPA) | Primary data store | +| Hetzner | DE | Server hosting, Coolify | Yes (standard AV) | Covers server infra | +| Redis (Coolify-managed) | DE (same server) | Queue, cache | N/A (same controller infra) | No personal data in queue payloads | +| AI Provider (TBD) | TBD | AI inference for ai_requests | **REQUIRED before production** | DPA + data processing agreement mandatory | +| SMTP Provider (TBD) | TBD | Email delivery | **REQUIRED before production** | Must be EU or with SCCs | + +--- + +## Data Subject Rights Procedures (required before production) + +| Right | GDPR Article | Current Status | Owner | +|-------|-------------|----------------|-------| +| Right to access | Art. 15 | NOT IMPLEMENTED | Engineering | +| Right to erasure ("right to be forgotten") | Art. 17 | NOT IMPLEMENTED — audit_log.actor_id permanently stored | Engineering | +| Right to data portability | Art. 20 | NOT IMPLEMENTED | Engineering | +| Right to rectification | Art. 16 | Partial (users can update profile via Supabase Auth) | Engineering | +| Right to object (automated decisions) | Art. 21 | NOT IMPLEMENTED for ai_requests | Engineering | + +--- + +## Open Risks (PRV-005 Findings) + +| ID | Severity | Finding | Remediation | Owner | +|----|----------|---------|-------------|-------| +| PRV-F1 | HIGH | audit_log.actor_id stored permanently — no erasure path for deleted users | Implement right-to-erasure endpoint that anonymizes actor_id in audit_log | Engineering | +| PRV-F2 | HIGH | AI provider sub-processor DPA not in place | Select AI provider and sign DPA before any production traffic | Legal | +| PRV-F3 | MEDIUM | SMTP provider not selected, no DPA | Select EU provider with DPA | Legal | +| PRV-F4 | MEDIUM | No retention enforcement in code for Goals/Decisions/Observations (only soft delete) | Implement hard-delete / anonymization job on account closure | Engineering | +| PRV-F5 | LOW | Application log retention policy not enforced at infra level | Configure log rotation to 30 days in Coolify/Hetzner | Ops | + +--- + +*This registry must be reviewed quarterly and updated before any new processing activity is introduced.* +*DPO sign-off required before production launch with real user data.*