# LGPD and data sovereignty

Preá is built in Brazil by [Orbin](https://orbin.tech) with data sovereignty as a core architectural property. This document explains how Preá handles personal data under Brazil's General Data Protection Law (*Lei Geral de Proteção de Dados Pessoais* — LGPD, Law No. 13.709/2018) across both self-hosted deployments and Orbin-managed cloud deployments, and maps data subject rights directly to the product's codebase.

> [!IMPORTANT]
> Sections marked **[Legal review required]** identify contractual, regulatory, or operational designations that must be confirmed by qualified Brazilian legal counsel before binding publication for a production deployment.

## Roles under LGPD (Arts. 5 and 37–40)

LGPD distinguishes between the **Controller** (*Controlador*, Art. 5, VI), who makes decisions regarding the processing of personal data, and the **Operator / Processor** (*Operador*, Art. 5, VII), who processes personal data on behalf of the Controller. Both must keep records of personal data processing operations (Art. 37), and the Operator must follow the Controller's instructions and security standards (Arts. 38–40).

| Deployment model | Workspace content (chats, files, memory, computer state, connected apps) | Account administration, security logs, and billing records | External model, voice, memory, and sandbox providers |
| --- | --- | --- | --- |
| **Self-hosted Preá** | Deploying organization or individual is **Controller**. Orbin has zero access to the deployment. | Deploying organization or individual is **Controller**. | Selected by the operator; act as **Operators** or independent **Controllers** under the operator's direct agreements. |
| **Orbin Cloud (`prea.ia.br`)** | Customer / workspace owner is **Controller**; Orbin acts as **Operator** (Arts. 39–40). | Orbin acts as **Controller** for platform authentication, security monitoring, and billing compliance. | Orbin Customer Inference acts as **Operator** in Brazil; third-party providers configured via BYOK or explicit routing act under their respective terms. |

- **Self-hosted autonomy.** A self-hosted instance runs entirely on hardware controlled by its operator without calling any Orbin service. Orbin is neither Controller nor Operator for self-hosted instances unless the operator explicitly routes requests through Orbin Customer Inference.
- **[Legal review required]** Enterprise Data Processing Agreements (DPAs) for Orbin Cloud must formalize the Controller/Operator split, sub-processor lists, and audit rights under Arts. 37–40.

## Legal bases for processing (Arts. 7 and 11)

Depending on the deployment context, personal data processing in Preá relies on the following legal bases under LGPD Art. 7:

- **Execution of a contract or preliminary procedures (Art. 7, V):** Creating and authenticating user accounts, running user-directed teammates and scheduled routines, persisting workspace files and memory, and metering task credits, computer minutes, and voice usage (`apps/api/src/billing.ts`, `packages/db/src/billing.ts`).
- **Legitimate interest (Art. 7, IX; Art. 10):** Protecting platform integrity, preventing credential stuffing, enforcing rate limits, and logging refused internal network probes in `security_events` (`packages/db/src/security-events.ts`, `apps/api/src/security-audit.ts`). Data minimization is enforced in code: `securityEventMetadata` strips keys matching content, prompts, messages, passwords, tokens, cookies, emails, or secrets before writing.
- **Compliance with a legal or regulatory obligation (Art. 7, II; Art. 16, I):** Retaining immutable financial accounting entries in `billing_audit_events` (`packages/db/prisma/migrations/20261023000300_billing_audit/migration.sql`) and access/security records required under Brazilian law. **[Legal review required]** Confirm exact applicability and retention windows under *Marco Civil da Internet* (Law No. 12.965/2014, Art. 15) and Brazilian tax law.
- **Consent (Art. 7, I; Art. 8):** Recording explicit user permission before the mobile app transmits messages, files, routines, or voice audio to configured AI recipients (`apps/api/src/ai-consent.ts`, `packages/contracts/src/ai-consent.ts`).
- **Third-party recipients only:** the permission covers the recipients another company runs. A model server the operator runs, and Orbin's own in-country gateway (`orbin-main`, `orbin-embeddings`), are the Controller's own infrastructure or an Operator acting on the Controller's instructions (Art. 38-40), not third-party recipients; both stay in the disclosure, but neither depends on the permission.
- **Sensitive personal data (Art. 11):** Preá does not require sensitive personal data (biometric, health, political, or religious data) to operate. **[Legal review required]** Define whether standard terms prohibit inputting Art. 11 sensitive data without an enterprise addendum.

## Data subject rights and product implementation (Art. 18)

LGPD Art. 18 grants data subjects (*titulares*) rights to confirmation of processing, access, correction, anonymization/blocking/deletion, portability, information on sharing, and revocation of consent. Preá implements self-service mechanisms for these rights directly in the application:

### Access and portability (Art. 18, I, II, and V)

Users can export a complete machine-readable archive of their data from **Settings → General → Export data**:

- **Endpoint and transport:** `mountAccountExportRoute` in `apps/api/src/account-export.ts` serves `GET /api/account/export?token=`, consuming a single-use token (`consumeAccountExportToken`) and streaming `prea-export-YYYY-MM-DD.zip` with `Cache-Control: no-store`.
- **Scope and tenant isolation:** `readAccountExport` in `packages/db/src/account-export.ts` queries each Space inside its PostgreSQL Row-Level Security tenant context (`runAsTenant` and `runGeneratorAsTenant`) through the decrypting Prisma client extension.
- **Exported contents:**
  - `manifest.json` with export format version, timestamp, user profile (`name`, `email`, `timezone`), and Space metadata.
  - Per-Space JSON Lines (`records.jsonl`) containing `bot_section`, `bot`, `chat_group`, `thread`, `message`, `artifact` metadata, `memory_document`, `memory_revision`, `routine`, `scratchpad_item`, `agent_skill`, and (for Space owners) `board`, `ticket`, and `ticket_comment` records.
  - Conversations that arrived from an external channel: the channel conversation, the thread it mirrors, that thread's messages, and the messages the channel delivered (`external_conversation`, `external_message`).
  - Decrypted artifact files streamed from `ArtifactStore` (`stores.artifacts.get`).
  - Bot computer workspace files exported from `AgentHomeStore` (`stores.home.exportHome`) along with `executables.json`.
- **Nothing is left out silently:**
  - A workspace file larger than `ACCOUNT_EXPORT_MAX_HOME_FILE_BYTES` is not embedded in the zip. `manifest.json` lists it under `files` with a scoped, single-use link (`GET /api/account/export/file`) that fetches that one file, so every file is either in the archive or named in the manifest.
  - The archive is measured before it is written. `fflate` writes no Zip64 records, so an export that cannot fit in one zip is refused with an explicit error (HTTP 413) instead of a truncated download.

### Correction (Art. 18, III)

Users can update their profile name, email, password, passkeys, and timezone in **Settings**, and can edit or remove teammate instructions, memory documents (`memory_documents`), routines, credentials, and computer files at any time.

### Deletion / erasure (Art. 18, IV and VI)

Users can permanently delete their account from **Settings → General → Delete account** (web/desktop) or **Account → Delete account** (mobile):

- **Orchestration:** `beforeDeleteUser` in `apps/api/src/app.ts` cancels active billing subscriptions (`billing.cancelForDeletedUser`), invokes `deleteAccountContent` (`apps/api/src/account-deletion.ts`), removes local Pi session state (`removePiUserSessions`), and deletes push notification tokens (`pushTokens.remove`).
- **Space claiming and teardown:** `claimSpacesLeavingWithAccount` (`packages/db/src/spaces.ts`) claims all personal Spaces and sole-member Spaces in Serializable transactions. `deleteAccountContent` then:
  1. Destroys every user-owned bot and every bot in leaving Spaces via `destroyBot` with `deleteMemories: true` and `strictTeardown: true`.
  2. Removes deleted bots' directories from shared legacy Team Computers (`removeDeletedBotsFromLegacyTeamHome`).
  3. Destroys isolated sandboxes at the sandbox provider (`deps.sandbox.destroy`), records computer run completion, removes agent home storage (`removeAgentHome`), and deletes `computer` rows.
  4. Calls `deleteSpaceLeavingWithAccount` (`packages/db/src/spaces.ts`), which deletes the `space` rows (cascading to threads, messages, memories, routines, and deleting the Space's encryption keys in `space_keys` via database trigger) and deletes stored artifact blobs (`deps.artifacts.remove`).
- **Resumable reliability:** `settleAll` in `apps/api/src/account-deletion.ts` ensures that if an external sandbox or storage teardown fails, the deletion halts before dropping database handles so a retry finishes cleaning up the remaining resources.

### Information on sharing and consent revocation (Art. 18, VII, VIII, and IX)

- `aiConsentStatus` and `allowAiConsent` in `apps/api/src/ai-consent.ts` enumerate every configured model, role fallback, team-chat judge, voice service, memory provider, and cloud agent for the active Space, including custom endpoint origins.
- Users can inspect these recipients and withdraw sharing consent under **Account → AI data sharing**.
- **The server applies the decision, not only the client.** Before it dispatches, the API and the worker check the decision for every third-party recipient the request would reach (`assertAiDataSharingAllowed` in `apps/api/src/ai-data-sharing.ts`, `aiDataSharingRefusals` in `packages/adapters/src/ai-consent.ts`). A recipient the user denied is refused with the typed error `ai_data_sharing_denied` (`AI_DATA_SHARING_DENIED_CODE` in `packages/contracts/src/ai-consent.ts`), which the clients render as "Review AI data sharing in Account settings before continuing." A provider added after the user answered for that kind of use needs its own grant.
- **Withdrawal stops the work.** The decision is kept rather than deleted (`status` on `ai_data_consents`), so it survives on every surface. Withdrawing a model permission cancels the runs in flight and pauses the routines of that account in that Space (`stopWorkForDeniedModel`); a voice or memory permission stops its own dispatches.
- Every third-party recipient requires an explicit current grant, including its first dispatch. Missing or stale grants are refused; operator-local inference and Orbin's in-country gateway remain exempt. See [AI data sharing review](https://prea.ia.br/docs/ai-data-sharing-review.md) for the decision rules.

## International data transfers and model routing (Art. 33)

LGPD Art. 33 regulates transfers of personal data to countries or international organizations outside Brazil:

- **In-country residency in Brazil:** On Orbin infrastructure in Brazil, PostgreSQL databases, encrypted artifacts, computer sandboxes, and default model routing through **Orbin Customer Inference** (`orbin-main` and `orbin-embeddings`) remain on hardware in Brazil. No international transfer occurs unless the workspace owner or operator configures an external provider located abroad.
- **Self-hosted residency controls:** Operators can keep all inference inside their own network or country by configuring local models (`PREA_LOCAL_MODELS`), allowlisting private OpenAI-compatible hosts (`PREA_OPENAI_COMPAT_PRIVATE_HOSTS`), and disabling public OpenAI-compatible endpoints (`PREA_OPENAI_COMPAT_ALLOW_PUBLIC=0`, documented in `docs/self-host-models.md`).
- **Cross-border providers:** When an operator or user connects providers hosted outside Brazil (such as OpenAI, Anthropic, Google, OpenRouter, Vercel AI Gateway, ElevenLabs, Cartesia, Fish Audio, Supermemory, E2B, or Daytona), prompts, conversation context, attachments, or voice audio are transmitted to those providers to execute the requested task.
- **Transfer mechanisms:** **[Legal review required]** Cross-border transfers on hosted tiers must be backed by an Art. 33 mechanism—such as Standard Contractual Clauses (*Cláusulas-Padrão Contratuais*) under ANPD Resolution CD/ANPD No. 19/2024 (Art. 33, II, *b*), necessity for executing a contract at the data subject's request (Art. 33, IX), or specific and highlighted consent (Art. 33, VIII).

## Technical safeguards and incident notification (Arts. 46 and 48)

### Security and encryption at rest (Art. 46)

- **Envelope encryption:** `packages/db/src/content-encryption.ts` encrypts `messages.blocks`, `messages.replyQuote`, `events.payload`, `threads.historyCompactionSummary`, `memory_documents.content`, `memory_revisions.content`, `external_messages.content`, `messaging_outbound.body`, `ticket_comments.body`, `agent_skills.content`, `agent_skills.files`, `bots.instructionHistory`, `taught_skills.playbook` and `taught_skills.recording` with per-Space 256-bit AES-GCM keys stored in `space_keys` and wrapped by master keys (`ENCRYPTION_MASTER_KEYS`, `ENCRYPTION_KEY`, or `MASTER_KEY_PROVIDER=aws-kms`). Authenticated data binds ciphertext to the exact table, column, row ID, and Space ID. Artifacts and object-storage bot homes are stream-encrypted with AES-256-GCM. Rows written before a column started being encrypted stay in plaintext until `content-encryption migrate` runs.
- **Provider identifiers:** requests to external providers carry a keyed pseudonym per provider and account, derived from the deployment's master secret, instead of the internal user id (`providerUserPseudonym` in `packages/adapters/src/provider-pseudonym.ts`). A provider can still group one person's requests, no two providers can recognise the same person from their own records, and a deployment without a master secret sends no identifier at all.
- **Cryptographic erasure:** Deleting a Space triggers deletion of its `space_keys` rows, making any residual ciphertext in unvacuumed database pages or orphaned files permanently unreadable (`docs/content-encryption.md`).
- **Tenant isolation:** PostgreSQL Row-Level Security (`packages/db/src/row-security.ts`) isolates tenant tables by `spaceId` and `userId`.

### Incident notification to ANPD (Art. 48)

Under LGPD Art. 48, the Controller must notify the National Data Protection Authority (*Autoridade Nacional de Proteção de Dados* — ANPD) and affected data subjects of any security incident that may create relevant risk or damage:

- **Orbin as Operator (Orbin Cloud):** If Orbin detects a confirmed security breach affecting customer workspace data, Orbin notifies the customer Controller promptly with the incident timestamp, affected Space and user identifiers, nature of the data involved, encryption status (`space_keys` AES-256-GCM state), and remediation steps taken.
- **Orbin as Controller / Self-hosted Controllers:** **[Legal review required]** Controllers must submit incident notifications to the ANPD and affected data subjects within the regulatory deadline established by ANPD Resolution CD/ANPD No. 15/2024 (ordinarily 3 business days from knowledge of the incident).

## Data retention (Arts. 15 and 16)

| Data category | Storage location | Retention period | Deletion / expiration mechanism |
| --- | --- | --- | --- |
| Workspace content (chats, memories, routines, artifacts, computers) | PostgreSQL, `DATA_DIR/artifacts`, sandbox provider, object storage | While account and Space remain active | Immediate teardown and cryptographic key deletion (`space_keys`) upon Space or account deletion (`apps/api/src/account-deletion.ts`). |
| Security audit events | `security_events` table and structured stdout logs | **90 days** by default (`SECURITY_EVENT_RETENTION_DAYS`, `packages/db/src/security-events.ts`) | Hourly automated pruning via `createSecurityEventPruner` (`pruneSecurityEvents`). |
| Financial and billing ledger | `billing_audit_events` table | Statutory tax and accounting retention period (**[Legal review required]**: typically 5 years under Brazilian law) | Append-only journal protected by database triggers (`billing_audit_no_mutation`) under LGPD Art. 16, I. |
| Encrypted backups | Operator backup storage | Until backup rotation window expires | Retiring old master keys (`ENCRYPTION_MASTER_KEYS`) after backup expiration renders historical ciphertext permanently unreadable. |

## DPO / Encarregado contact (Art. 41)

Under LGPD Art. 41, the Controller must appoint a Data Protection Officer (*Encarregado pelo Tratamento de Dados Pessoais*) and publish their identity and contact information clearly.

- **Orbin Cloud DPO / Encarregado:** **[Legal review required — insert appointed Encarregado full name / corporate designation before production launch]**
- **Contact email:** `dpo@prea.ia.br` (privacy and LGPD Art. 18 requests) · `seguranca@prea.ia.br` (security incident reports)
- **Self-hosted deployments:** Self-hosted operators must designate their own *Encarregado* and configure `PRIVACY_POLICY_URL` to point to their deployment's privacy notice and DPO contact details (`docs/ai-data-sharing-review.md`).

---

## Resumo em Português (pt-BR)

O **Preá** foi projetado no Brasil pela [Orbin](https://orbin.tech) com soberania de dados e conformidade com a **Lei Geral de Proteção de Dados Pessoais (LGPD — Lei nº 13.709/2018)** como propriedades centrais da arquitetura.

### 1. Papéis de Controlador e Operador (Arts. 5º e 37 a 40)

- **Preá Auto-hospedado (*Self-hosted*):** A organização ou pessoa que opera o servidor é o **Controlador** exclusivo dos dados pessoais tratados na instância. A Orbin não recebe telemetria, conversas, arquivos nem credenciais de instâncias auto-hospedadas, exceto quando o operador opta por conectar o gateway **Orbin Customer Inference**.
- **Preá na Nuvem Orbin (`prea.ia.br`):** O cliente/organização titular do workspace atua como **Controlador** do conteúdo operacional (conversas, instruções dos colegas de IA, memórias, arquivos e computadores), enquanto a Orbin atua como **Operadora** (Arts. 39 e 40). Para dados cadastrais de conta, registros de segurança (`security_events`) e razão contábil de faturamento (`billing_audit_events`), a Orbin atua como **Controladora**. *(Requer revisão jurídica nos contratos B2B / DPA).*

### 2. Bases Legais (Arts. 7º e 11)

- **Execução de contrato (Art. 7º, V):** Autenticação, operação dos colegas de IA, rotinas agendadas, computadores persistentes e medição de franquias (créditos de tarefas, minutos de computador e voz).
- **Legítimo interesse (Art. 7º, IX e Art. 10):** Prevenção a fraudes, limites de taxa (*rate limiting*) e auditoria de segurança em `security_events` (`packages/db/src/security-events.ts`), com minimização estrita (sem armazenar conteúdo de mensagens, prompts ou segredos).
- **Cumprimento de obrigação legal ou regulatória (Art. 7º, II e Art. 16, I):** Guarda de registros contábeis imutáveis em `billing_audit_events` e registros de conexão/acesso exigidos pela legislação brasileira (*Marco Civil da Internet* e legislação tributária — *requer revisão jurídica*).
- **Consentimento (Art. 7º, I e Art. 8º):** Permissão explícita por Espaço e destinatário no aplicativo móvel antes do envio de dados a provedores de IA (`apps/api/src/ai-consent.ts`).

### 3. Direitos do Titular no Produto (Art. 18)

- **Acesso e Portabilidade (Art. 18, I, II e V):** Em **Configurações → Geral → Exportar dados**, o endpoint `GET /api/account/export?token=` (`apps/api/src/account-export.ts` e `packages/db/src/account-export.ts`) gera um pacote ZIP (`prea-export-AAAA-MM-DD.zip`) com `manifest.json`, histórico completo em JSONL por Espaço (conversas, mensagens, memórias, rotinas, habilidades e quadros de tarefas), conversas que vieram de canais externos, artefatos descriptografados e arquivos de trabalho dos computadores dos colegas de IA. Nenhum arquivo é omitido em silêncio: um arquivo de trabalho maior que o limite é listado no manifesto com um link de download de uso único, e uma exportação que não caiba em um único ZIP é recusada com um erro explícito.
- **Correção (Art. 18, III):** Edição direta de dados cadastrais, memórias, instruções e arquivos pelo titular.
- **Eliminação e Revogação de Consentimento (Art. 18, IV, VI e IX):** A exclusão de conta (`apps/api/src/account-deletion.ts` e `packages/db/src/spaces.ts`) cancela assinaturas ativas, destrói bots e memórias (`deleteMemories: true`), encerra sandboxes nos provedores, remove diretórios de computadores compartilhados e apaga os Espaços exclusivos e suas chaves criptográficas (`space_keys`), tornando qualquer texto cifrado residual permanentemente ilegível. O consentimento de compartilhamento com IA pode ser revogado a qualquer momento em **Conta → Compartilhamento de dados com IA**. A revogação vale em todas as superfícies: o servidor recusa o envio ao destinatário cujo consentimento foi retirado, cancela as execuções em andamento e pausa as rotinas da conta naquele Espaço.

### 4. Soberania de Dados e Transferência Internacional (Art. 33)

- Na infraestrutura da Orbin no Brasil, bancos de dados, arquivos, computadores e o roteamento padrão via **Orbin Customer Inference** permanecem integralmente em território nacional.
- Quando o usuário ou operador configura provedores externos no exterior (como OpenAI, Anthropic, Google, OpenRouter, ElevenLabs ou E2B), ocorre transferência internacional sujeita às salvaguardas do Art. 33 da LGPD e da Resolução CD/ANPD nº 19/2024 (*requer revisão jurídica das cláusulas contratuais aplicáveis*).

### 5. Segurança, Retenção e Encarregado (Arts. 15, 16, 41, 46 e 48)

- **Criptografia em repouso:** Conteúdo protegido com criptografia de envelope AES-256-GCM por Espaço (`packages/db/src/content-encryption.ts`) e isolamento por *Row-Level Security* no PostgreSQL (`packages/db/src/row-security.ts`).
- **Retenção:** Dados de trabalho são mantidos enquanto a conta estiver ativa; eventos de segurança (`security_events`) são expurgados automaticamente após **90 dias** por padrão (`SECURITY_EVENT_RETENTION_DAYS`); registros de auditoria financeira (`billing_audit_events`) são retidos pelo prazo legal aplicável.
- **Notificação de Incidentes (Art. 48):** Comunicação tempestiva ao Controlador e, quando aplicável, à ANPD e aos titulares conforme a Resolução CD/ANPD nº 15/2024 (*prazo operacional sujeito a revisão jurídica*).
- **Encarregado pelo Tratamento de Dados (DPO — Art. 41):** Contato pelo e-mail `dpo@prea.ia.br` (*identificação formal do Encarregado a ser preenchida pelo departamento jurídico antes da publicação em produção*).
