Pular para o conteúdo

Níveis e segurança

O servidor é a única autoridade. O app nunca “executa” uma decisão: ele só envia uma intenção de resposta, e o servidor aceita se ela for válida, estiver no prazo e no nível exigido.

Níveis de decisão de 0 a 4O serviço pede um nível mínimo; o workspace só pode subir. Vale o maior nível entre as perguntas. Nível 0 é um toque, nível 1 aparelho desbloqueado, nível 2 biometria ou código 2FA (a janela do 2FA pode cobrir), nível 3 biometria ou código 2FA a cada ação, online e com prazo curto, nível 4 é o nível 3 mais quórum de pessoas.Nível do serviçolevel: 0–4 no ask()(padrão 1)Mínimo do workspacepode subir,nunca baixarNível efetivoo maior entreas perguntas0 · toquemarcar lido, ver1 · aparelho desbloqueadoreiniciar container2 · biometria ou 2FAa janela do 2FA pode cobrir3 · biometria ou 2FA, toda açãoonline · prazo curto4 · nível 3 + quórumex.: 2 de 3 aprovam (app)
Nível Exige Exemplo
0 Um toque Ver um painel, marcar como lido
1 Aparelho desbloqueado (sessão aberta) Reiniciar um container, responder um lead
2 Biometria ou senha do aparelho, ou o código 2FA Um agente de IA quer agir, aprovar um deploy
3 Biometria ou código 2FA a cada ação, online e com prazo curto Apagar dados, liberar acesso, movimentar dinheiro
4 Nível 3 e quórum 2 de 3 diretores aprovam

O serviço define o nível no ask(). O workspace pode endurecer a regra, e o serviço nunca consegue baixá-la. Vale o maior nível entre as perguntas.

No app nativo, a chave privada é criada no Secure Enclave (iOS) ou no Keystore (Android) com a regra “só assina após autenticação do usuário”. Sem digital, rosto ou senha do aparelho, o próprio chip se recusa a assinar.

  • O aparelho gera uma chave por vínculo/servidor, então uma organização revoga a sua sem afetar as outras.
  • A resposta assinada inclui id do grupo de perguntas, versão, respostas, horário, nonce e o hash do conteúdo exibido.
  • O pedido de biometria mostra o resumo do que está sendo assinado, para ninguém aprovar às cegas.
  • A biometria é sempre um pedido por decisão.

Nem todo aparelho tem leitor de digital, e no navegador não há biometria. Para os níveis 2 e 3, a pessoa pode ativar a verificação em duas etapas em Conta com qualquer app autenticador TOTP (Google Authenticator, Microsoft Authenticator, 1Password, Authy ou o app da própria empresa) e assinar com o código de 6 dígitos.

Assinando uma decisão com o código 2FASem biometria, quem ativou o 2FA assina decisões de nível 2 e 3 com o código de 6 dígitos do app autenticador. O nível 3 sempre pede o código. No nível 2, se a sessão estiver dentro da janela do 2FA escolhida pela pessoa, a assinatura sai sem digitar código; senão a pessoa digita o código, o servidor confere (±30 segundos, uso único, 5 erros em 15 minutos bloqueiam) e um código válido abre a janela para aquela sessão.Abre a decisãosem biometria aqui(navegador, PWA)Nível?2 ou 3Digita o código de 6 dígitosdo app autenticadorServidor confere±30 s · uso único5 erros / 15 min = bloqueioJanela do 2FA aberta?nesta sessão,0–240 min, você escolheResposta aceitaauth_method: "totp"(código válido abre a janela)Assina sem códigosó nível 2nível 3válidonível 2nãosim
  • O código é conferido no servidor (±30 segundos) e vale uma vez só. 5 códigos errados em 15 minutos bloqueiam novas tentativas.
  • A resposta registra auth_method: "totp" e o nível comprovado.
  • O nível 3 sempre pede um código, a cada ação.
  • O nível 4 (quórum) continua exigindo o app com biometria.
  • Desativar o 2FA exige um código válido, então quem pegar a sessão não consegue desligar.

Com 50 aprovações esperando, digitar um código em cada uma não dá. Em Conta, cada pessoa escolhe uma janela do 2FA: desligada (pedir sempre), 5, 15, 30, 60, 120 ou 240 minutos. Depois de um código válido, aquela sessão assina decisões de nível 2 sem digitar o código de novo até a janela acabar.

  • A janela é da sessão: outros navegadores e aparelhos precisam do próprio código.
  • Ela só cobre o nível 2. O nível 3 sempre pede um código novo.
  • Desligar o 2FA limpa a janela de todas as sessões.
  • Cada grupo de perguntas declara offline: allowed | denied e um prazo.
  • O servidor rejeita resposta para versão antiga ou pergunta expirada, e o app explica o motivo (“sua resposta não foi aceita porque a pergunta expirou às 12:30”).
  • Idempotência: a mesma resposta enviada duas vezes executa uma vez só.
  • Nível 3 ou mais nunca é aceito offline.
UPDATE question_sets
SET status = 'answered', answered_by = $3, answered_at = now()
WHERE id = $1 AND version = $2 AND status = 'open';
-- 0 linhas = já decidido, expirado ou versão diferente

A resposta e o aviso ao seu sistema são gravados na mesma transação (outbox transacional). Um processo separado entrega o webhook assinado com novas tentativas automáticas, então a decisão nunca se perde.

A resposta que o seu sistema recebe é assinada com a chave Ed25519 do servidor. As chaves públicas ficam em <api>/.well-known/notificme-keys.json, e o SDK confere para você. Veja Webhooks.

  • Revogação de aparelho perdido pelo app web (Dispositivos).
  • Trilha de auditoria: quem, qual aparelho, qual nível, quando e o hash do conteúdo, imutável e exportável.
  • Tokens de serviço têm escopos, e tokens de agentes de IA podem exigir aprovação humana a cada escrita. Veja Agentes de IA e MCP.