> ## Documentation Index
> Fetch the complete documentation index at: https://supastack.dev/llms.txt
> Use this file to discover all available pages before exploring further.
> For the full documentation corpus in one file, fetch: https://supastack.dev/llms-full.txt

# Como construir um SaaS com extensão Chrome (MV3) compartilhando auth web e API

A maioria das equipes constrói um segundo backend para a extensão de navegador. Veja como ligar um companheiro Manifest V3 ao seu SaaS existente via chaves de API workspace — sem auth duplicada nem segundo banco.

_Publicado 2026-11-07._
_Atualizado em 2026-11-07._

> **Como construir uma extensão Chrome que compartilhe o backend do seu SaaS?**
> Não construindo um segundo backend. Uma extensão MV3 não pode depender de cookies HttpOnly, então autentique com chaves de API workspace: a extensão chama a API REST versionada do app (/api/v1) com uma chave com escopo ligada a exatamente um workspace, reusando o mesmo modelo de auth, o mesmo escopo de tenant e o mesmo banco Postgres do app web. O scaffold MV3 do supastack — popup, página de opções, worker em segundo plano, manifesto de mínimos privilégios — é ligado exatamente assim.

## A armadilha: construir um segundo backend sem perceber

A história de sempre: seu SaaS precisa de uma extensão companheira para capturar páginas, clipar conteúdo ou anotar a web. Seis meses depois, você mantém dois sistemas de auth (cookies para a web, algo artesanal para a extensão), uma API paralela que a extensão consegue de fato chamar e uma camada de sync que alinha dois armazenamentos de dados que deveriam ser um só.

Nada disso é necessário. A extensão é só mais um cliente do seu produto existente — precisa de uma credencial que consiga segurar e de uma API feita para acesso programático. O erro é estender a mão para um backend novo em vez de usar as chaves de API workspace e a superfície REST versionada que um SaaS sério já tem.


## O que o Manifest V3 realmente permite

O MV3 trocou background pages por service workers de vida curta e empurra as extensões para o mínimo privilégio. Na prática: nada de estado em memória persistente; nada de raspar cookies para reusar sessões (cookies HttpOnly são inalcançáveis de qualquer jeito); e cada permissão de host é uma pergunta na revisão da web store.

A resposta limpa é o que a plataforma já oferece: uma credencial com escopo no `chrome.storage.local` e chamadas HTTPS para a origem do seu app — pedidas como permissões de host opcionais na hora do setup, não da instalação.


## O scaffold MV3 do supastack: o que já vem ligado

O `apps/extension` do supastack é um companheiro Manifest V3 deliberadamente pequeno e sem framework — «salvar página no workspace» — que mostra o padrão inteiro de ponta a ponta. Ele salva título, URL e texto selecionado da aba ativa como content entry do workspace via a API REST versionada `POST /api/v1/content-entries`.

O auth usa uma chave de API workspace (`sk_…`) criada em Settings → Developers: a chave é ligada a exatamente um workspace, então a ligação em si é a seleção do workspace — ela nunca pode escrever em outro lugar. A página de opções persiste a URL do app e a chave no `chrome.storage.local`, pede acesso só a essa origem e verifica a conexão com `GET /api/v1/workspaces/current`.

```
apps/extension/
  manifest.json        MV3: service worker, least-privilege permissions
  src/
    background.js      context-menu save + badge feedback
    popup.html/.js     capture UI — title, URL, selection, note
    options.html/.js   app URL + workspace API key setup
    lib/
      api.mjs          versioned /api/v1 client (key auth)
      capture.mjs      active-tab + selection capture
      config.mjs       chrome.storage.local persistence
```


## Mínimo privilégio por padrão

O scaffold traz só o conjunto mínimo de permissões que o trabalho exige — importante para a revisão da store e a confiança do usuário:

- Sem `tabs`, sem `<all_urls>`, sem cookies/webRequest/declarativeNetRequest — um scaffold que declara honestamente o que não precisa.

| Permissão | Para quê |
|---|---|
| activeTab | Ler título/URL da página atual só quando invocado |
| scripting | Ler o texto selecionado na aba invocada |
| contextMenus | Registrar o item «salvar» do botão direito |
| storage | Persistir URL do app, chave de API e workspace em cache |
| optional_host_permissions | A origem do app é pedida no setup — zero acesso a sites na instalação |


## Do scaffold ao companheiro do seu produto

Rebrandear é renomear o `manifest.json`; a parte interessante é estender — e continua dentro do mesmo padrão: novos tipos de captura chamam novos endpoints `/api/v1` com a mesma chave, e o `@supastack/api-sdk` tipado gerado do documento OpenAPI do app mantém as formas de request exatas.

Como a extensão lê e escreve pela mesma API com escopo de tenant que qualquer outro cliente, as páginas salvas caem nas mesmas linhas Postgres que o dashboard web lista — um banco, um modelo de auth, escopo `workspaceId` imposto num único lugar. Sem segundo backend, sem sync, sem drift. Compare níveis na [página de preços](https://supastack.dev/#pricing).

|  | Abordagem DIY de segundo backend | Scaffold MV3 do supastack |
|---|---|---|
| Auth | Sistema de tokens artesanal ao lado de cookies | Chaves de API workspace — mesmo modelo de auth da web |
| API | Endpoints novos inventados para a extensão | /api/v1 versionada + SDK tipado do OpenAPI |
| Dados | Segundo armazenamento + lógica de sync | Mesmas linhas Postgres, com escopo de workspace |
| Permissões | Acesso amplo por conveniência | Manifesto de mínimos privilégios, amigável à revisão |


## FAQ: SaaS + extensão Chrome num backend só

Perguntas que desenvolvedores fazem antes de lançar um companheiro de extensão:

- Por que chave de API em vez do cookie de sessão do usuário?, Cookies HttpOnly são invisíveis ao JS da extensão por design e service workers MV3 têm vida curta — uma chave `sk_…` com escopo no `chrome.storage.local` é persistente, revogável e ligada a um workspace, incapaz de escrever fora dele.
- A extensão funciona no Firefox?, O MV3 suporta a mesma superfície; o código usa um shim de namespace `browser ?? chrome` e é desenvolvido Chromium-first — Firefox é um port, não uma reescrita.
- Está pronta para a store assim que instala?, É um scaffold de padrão de produção, não uma submissão à store — você vai renomear o manifesto, adicionar sua lógica de captura e escrever o texto da listagem. A parte difícil (auth, API, escopo de tenant) está pronta.
- Qual nível inclui a extensão?, O Full Bundle de $299 entrega as cinco superfícies — dois motores web, Expo, Tauri e o scaffold de extensão — num repo.
