Nacre
Camada de contexto autocontrolada e ciente de permissões. A busca retorna apenas o que o chamador pode ler.
Documentação
Nacre
Seu índice. Suas regras de acesso. Seu perímetro.
Agentes veem exatamente o que têm permissão para ver.
Nacre é um índice de conhecimento auto-hospedado com controle de acesso refinado. Agentes o acessam via MCP, aplicações via API REST. Sem interface de chat, sem assistente corporativo — apenas a camada de contexto por baixo deles.
Por quê
Busca vetorial é um problema resolvido. O que não está resolvido: garantir que um agente consultando um índice corporativo veja exatamente os documentos para os quais o usuário solicitante tem autorização — e poder provar isso a um auditor.
- Permissões que herdam. Workspaces → camadas, com
read/write/adminherdados de cima para baixo.writenão implicaread;adminimplica ambos. Concessões em nível de documento e regras de negação são comerciais — esta compilação as recusa e diz isso, em vez de aceitar uma regra que não pode propagar. - A filtragem acontece dentro do índice. Filtros de acesso são aplicados durante
a travessia HNSW, não após a classificação, então
top_kretorna k resultados permitidos em vez de k menos o que foi removido. - MCP como superfície de primeira classe. HTTP transmissível conforme a especificação de 2026-07-28, e STDIO local para agentes de desenvolvimento. Agentes autenticam com uma chave de conta de serviço; a descoberta OAuth é servida (RFC 9728), e o registro de clientes é responsabilidade do servidor de autorização, não nossa.
- Recuperação híbrida, porque agentes pedem identificadores. Vetores densos e
BM25 fundidos com fusão de classificação recíproca, além de um reordenador cross-encoder onde
uma implantação o configura. Não oferecido como diferencial — a linha acima
é a honesta — mas um agente buscando por
SQLSTATE 23505, um número de nota fiscal ou um nome de variável precisa da correspondência literal, e um índice apenas denso não a retorna de forma confiável. - Traga seus próprios modelos. Embeddings através de qualquer endpoint compatível com OpenAI, vinculado por camada. Trocar o modelo em uma camada existente é um reindexação que mantém a busca respondendo durante todo o processo, e é condicionada à recall contra um conjunto de consultas que você fornece antes da troca.
- Um cliente de linha de comando.
npx @nacre.work/clifaz login, cria uma camada, percorre um diretório e busca — as quatro invocaçõescurlque o início rápido detalha, para quando você quer o resultado em vez do contrato. Um documento que falha ao indexar gera saída com código de erro diferente de zero, então uma ingestão noturna não pode reportar sucesso tendo indexado nada. - Permanece dentro da sua rede. Docker Compose, sem telefone para casa.
Início rápido
git clone https://github.com/nacre-work/nacre && cd nacre
cp .env.example .env
docker compose --profile minimal up -d
Passo a passo completo: docs/quickstart.md.
Em um Mac com Apple Silicon, leia docs/apple-silicon.md primeiro — as imagens são arm64 e a pilha é nativa, mas o embedder é a única peça que você executa no host.
Estrutura
packages/api REST API and authorization service
packages/mcp MCP server (Streamable HTTP + STDIO)
packages/worker indexing pipeline: parse, chunk, embed
packages/core data model, permission resolver, shared types
packages/sdk TypeScript SDK
packages/admin community admin UI
services/parser Python sidecar: bytes → {text, blocks, metadata}
docs/ specifications — normative, and ahead of the code
Estado
Inicial, e funciona. O ciclo funciona de ponta a ponta e foi dirigido manualmente
contra um PostgreSQL real e um Qdrant real: criar uma organização, criar uma
camada, conceder a alguém read, ingerir um documento, consultar o job até indexed,
buscar e obter o trecho de volta — e buscar como alguém sem a concessão e obter
nada enquanto os vetores ainda estão no índice. Ambas as superfícies funcionam,
REST e MCP sobre Streamable HTTP e STDIO igualmente. Revogar uma concessão remove o
documento dos resultados, e a recomputação que atualiza as tags do índice é executada
no worker com uma métrica sobre o quão atrasada está.
A busca é limitada por taxa por organização, métodos inseguros usam um
Idempotency-Key, coleções paginam por cursor, e a reordenação é executada no caminho
de busca quando uma implantação configura um reordenador. Vetores com tombstone são coletados,
e o SDK e a interface de administração estão escritos.
O login funciona: e-mail e senha, com tokens de atualização rotativos que encerram a
sessão se um for reutilizado. init cria o primeiro administrador e imprime uma
senha gerada uma única vez. SSO é um módulo comercial.
O log de acesso é legível: GET /v1/audit, mais recente primeiro, paginado por cursor, como
JSON, JSONL ou CSV. org_admin vê quais documentos foram lidos — a pergunta
que um log de auditoria existe para responder — e platform_admin vê ações administrativas
e nunca isso, que é a regra 2 aplicada ao diário.
Uma camada pode ser movida para um modelo de embedding diferente. Qdrant não adicionará um vetor nomeado a uma coleção que já existe, então a coleção é substituída em vez de alterada: cada ponto copiado sem embeddings computados, uma declaração para trocar o ponteiro, depois re-embedding uma camada por vez. A busca permanece disponível e continua sendo uma consulta durante todo o processo. Antes de uma camada trocar, seu conjunto de consultas de referência é pontuado contra o novo modelo e uma migração que perdeu recall para em vez de entrar em produção — essa trava está desligada até você escrever um conjunto, porque precisa de documentos que só você pode escolher.
Um documento pode ser enviado como formulário além de JSON, e um PDF é
extraído pelo sidecar do parser. Ambos os sinais precisam concordar — a parte declara
application/pdf e os bytes começam com %PDF- — porque um tipo declarado que os
bytes contradizem é um desacordo, e apenas farejar tornaria o tipo declarado
decoração. Qualquer outro formato binário ainda é recusado na borda, e um
PDF escaneado sem camada de texto é recusado em vez de indexado como nada.
Tokens podem ser assinados com uma chave Ed25519 em vez de um segredo compartilhado, caso em
que a metade pública é publicada em /.well-known/jwks.json e apenas o
processo que emite tokens detém a privada.
docker compose --profile minimal up foi executado a partir de um clone limpo, e
todo o ciclo foi dirigido através dele.
O que não está construído é o que uma licença comercial cobre, e docs/licensing.md
lista: multi-tenancy, SSO, permissões em nível de documento e regras de negação,
ID-JAG, exportação SIEM, um administrador global, cotas e gráficos Helm de alta disponibilidade.
docs/ é a especificação, e ainda avança à frente do código em alguns lugares —
comece com docs/authz.md, do qual tudo o mais depende.
Invariantes
Seis regras. Quebrar qualquer uma delas é um incidente de segurança, não um bug. Detalhes em docs/authz.md.
- A organização vem do token e de nenhum outro lugar.
- A filtragem de acesso é um pré-filtro, nunca um pós-filtro.
- Uma falha ao avaliar permissões nega o acesso.
- "Sem permissão" e "objeto inexistente" retornam respostas idênticas.
- Um documento excluído nunca é retornado, inclusive antes da coleta de lixo.
writenão implicaread.
Licença
Apache 2.0 — tudo isso. Tudo acima está neste repositório e permanece aqui.
Multi-tenancy, SSO/SCIM, regras de negação em nível de documento, EMA, exportação SIEM, administrador global e backup são módulos comerciais. Eles vivem em um repositório privado separado sob uma licença separada e não são distribuídos com este — veja docs/licensing.md para a linha entre os dois e a única pergunta que a decide.
Onde esta compilação encontra um deles, recusa abertamente: uma regra deny ou uma
concessão em escopo de documento é respondida 400 com o motivo, em vez de aceita
e silenciosamente não aplicada.
O nome e a marca Nacre são marcas registradas; veja TRADEMARK.md.
Apoiando isto
Não há camada hospedada, contagem de assentos ou nada medido aqui, então a metade aberta não ganha nada por ser usada — que é o ponto, e também por que vale a pena dizer quem paga por isso. Os módulos comerciais pagam, e são para as organizações que precisam deles; um desenvolvedor executando isso em um laptop nunca é a pessoa sendo cobrada.
Se economizou uma semana para você, o botão Sponsor no topo deste repositório é a outra forma de dizer isso. Nada neste repositório está atrás dele, e nada estará.