> For the complete documentation index, see [llms.txt](https://lunarie.gitbook.io/lunarie-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lunarie.gitbook.io/lunarie-docs/arquitetura/05-seguranca.md).

# Segurança

> **Última atualização:** 08/10/2026 Medidas em vigor e pontos de atenção, conferidos no banco, nas Edge Functions e nos Security Advisors do Supabase em 08/10/2026.

## Banco de dados

* **RLS em todas as tabelas** do schema `public`, com isolamento por `auth.uid() = usuario_id`.
* As tabelas de serviço `storage_delete_audit`, `invite_attempts` e `kindle_bounce_seen` têm RLS sem policies, e só o `service_role` acessa.
* **Sem planos nem limites no banco** desde 08/10/2026: tabelas de planos, triggers de limite e policies de cota foram removidos (ADR-095). Não há mais o que uma pessoa possa se auto-promover pela API.
* **Rota `/admin` restrita à conta admin** (ADR-095): a rota usa `beforeLoad` e responde 404 para qualquer outra conta, inclusive por acesso direto pela URL. É uma camada de interface; os dados continuam protegidos pela RLS das tabelas de admin (`convites`, `ai_usage_logs`, `kindle_envios`), que reconhece a conta admin.
* Funções `SECURITY DEFINER` de trigger e de operação têm `EXECUTE` revogado de `anon` e `authenticated`, com as exceções listadas em "Pontos de atenção".

## Privacidade e LGPD

* A política `/privacidade` descreve os dados, os terceiros e os direitos. É um rascunho escrito sem revisão jurídica (ADR-050), atualizado em 08/10/2026 (ADR-096).
* Na exclusão de conta, além das tabelas da biblioteca, saem as entradas em `fila_da_lua` e `convites` (pelo e-mail) e os eventos da pessoa no PostHog.
* Lacunas conhecidas, ainda sem decisão: controlador e base legal não identificados na política, transferência internacional (Groq, Resend, Stripe, Google), retenção por dado, canal e encarregado dedicados, Termos de Uso e plano de resposta a incidente. Estão no [Backlog Futuro](/lunarie-docs/roadmap/03-backlog-futuro.md).

## Storage

* Buckets privados: `ebooks` e `avatares`. Acesso por URL assinada de 1 hora, gerada sob demanda. O banco guarda o caminho (`arquivo_path`), nunca a URL.
* O bucket `capas` é público (ADR-011), porque capas não são dado sensível e a URL pública é estável. `capa_url` guarda essa URL.
* Policies por pasta: o primeiro nível do caminho é o `usuario_id`.
* O trigger `trg_audit_storage_delete` registra exclusões do bucket `ebooks` em `storage_delete_audit`, e o trigger `protect_objects_delete` protege contra exclusão indevida.
* A Edge Function `storage-integrity-check` verifica exclusões e fichas órfãs. Ela é executada sob demanda: nenhum job agendado a chama.

## Autenticação e contas

* Cadastro fechado: a entrada é só por convite (Fila da Lua, depois convite), por e-mail e senha ou por Google. O trigger `check_invite_before_signup` em `auth.users` exige o código mesmo em chamadas diretas ao Auth.
* Código de convite com RNG criptográfico, validade de 7 dias e uso único.
* Limite de 10 tentativas inválidas de convite por hora por IP (`invite_attempts`, com limpeza diária às 03:30).
* Senha com mínimo de 8 caracteres e verificação no HaveIBeenPwned (k-anonimato) no cadastro e na redefinição, feita pelo app. O indicador de força orienta a pessoa.

## Edge Functions e segredos

Todas as Edge Functions estão com `verify_jwt` desligado, e cada uma valida a própria autorização no código.

| Tipo                      | Funções                                                                                                                                                | Autorização                                                                                     |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------- |
| Pessoa usuária            | `send-to-kindle`, `create-checkout`, `verify-checkout`, `delete-account`, `google-books`                                                               | JWT validado com `auth.getUser`                                                                 |
| Administração e agendadas | `kindle-bounce-check`, `kindle-resumo-semanal`, `feedback-30-dias`, `notify-admin`, `send-fila-confirmation`, `storage-integrity-check`, `send-invite` | Bearer `ADMIN_SECRET_KEY` (`send-invite` também confere a sessão)                               |
| Webhook                   | `stripe-webhook`                                                                                                                                       | Assinatura do Stripe (`STRIPE_WEBHOOK_SECRET`)                                                  |
| Públicas por natureza     | `validate-invite`, `check-invite-code`, `send-magic-link`, `send-password-reset`, `posthog-proxy`                                                      | Sem login. Operam com `service_role` ou encaminham dados, limitadas pela lógica de cada função. |

Os segredos ficam só em variáveis de ambiente (Supabase, Lovable e GitHub Actions), nunca em código ou chat. O token de acesso do Supabase já foi rotacionado e o token do CLI foi revogado.

## Monitoramento

* Security Advisors do Supabase revisados depois de cada migração.
* Logs das Edge Functions e auditorias consultados em investigações.
* Erros do app capturados no PostHog e pelo ErrorBoundary global ([Monitoramento](/lunarie-docs/qualidade/04-monitoramento.md)).

## Pontos de atenção (Advisors, 08/10/2026; revisado em 09/11/2026)

> **Crítico (09/11/2026):** a service role key legada está no histórico do git (commit `676d5ab`) e segue válida até a revogação do JWT secret legado. Plano em [ADR-101](/lunarie-docs/arquitetura/06-decisoes-arquiteturais.md).

| Achado                                                                                                                                 | Nível       | Detalhe                                                                                                                                                                                                             |
| -------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 2 funções `SECURITY DEFINER` executáveis por `anon` e `authenticated`                                                                  | Aviso       | `audit_storage_object_delete` e `check_invite_before_signup` aparecem como chamáveis via `/rest/v1/rpc`. As duas são funções de trigger. A `check_storage_quota`, que também aparecia aqui, foi removida (ADR-095). |
| Proteção contra senha vazada desligada no Supabase Auth                                                                                | Aviso       | A verificação existe no app (HaveIBeenPwned), mas o recurso nativo do Auth está desativado. Como o cadastro exige convite, o risco prático é baixo.                                                                 |
| 3 tabelas com RLS sem policies                                                                                                         | Informativo | São as tabelas de serviço acima, e o comportamento é intencional.                                                                                                                                                   |
| `ADMIN_SECRET_KEY` em texto puro no comando de 3 `cron.job` (`feedback-30-dias-daily`, `kindle-bounce-check`, `kindle-resumo-semanal`) | Atenção     | Não é a chave de serviço do Supabase, e só quem já administra o banco lê `cron.job`. Mover para o Vault é higiene, não bloqueio. Corrigido em 09/11/2026: a avaliação anterior citava 1 job e "chave de serviço".   |

## Documentos relacionados

* [Regras de Dados](/lunarie-docs/banco-de-dados/06-regras-de-dados.md)
* [Requisitos Não Funcionais](/lunarie-docs/requisitos/03-requisitos-nao-funcionais.md)
* [Decisões Arquiteturais](/lunarie-docs/arquitetura/06-decisoes-arquiteturais.md)
