Monitoramento de Processos em Segredo de Justiça#
Esta seção descreve como o cliente pode configurar o webhook de segredo de justiça, cadastrar processos para monitoramento contínuo e descriptografar os dados recebidos.
Nota
O monitoramento exige uma credencial previamente cadastrada e habilitada. Consulte Gerenciamento de Credenciais para o passo a passo de cadastro.
Módulos necessários#
Os módulos abaixo devem estar habilitados para a empresa antes de usar este fluxo. Entre em contato com o suporte para ativá-los.
Módulo |
Finalidade |
|---|---|
|
Associar e dissociar credenciais de processos monitorados em segredo de justiça. |
|
Criar, listar, visualizar e arquivar processos monitorados em segredo de justiça. |
Configuração do webhook de segredo#
Importante
A configuração do webhook é um pré-requisito para o cadastro de processos. Sem uma URL de destino ativa e uma chave pública registrada, a criação de monitoramentos não é permitida. Configure o webhook antes de registrar qualquer processo monitorado.
Para receber eventos de segredo de justiça, o cliente precisa:
Gerar um par de chaves RSA-4096.
Registrar a chave pública e a URL de destino via
PATCH /api/webhook_config/{id}ou pelo painel.Habilitar a entrega com
is_segredo_active: true.
A configuração também pode ser feita pelo painel em Configurações → Webhook — Segredo de Justiça:
Formulário do painel com os campos URL, habilitação e Chave Pública (RSA/PEM).#
Nota
Permissões (POST e PATCH): além das roles do módulo listadas acima
(que controlam o acesso às credenciais/processos), os endpoints
POST /api/webhook_config e PATCH /api/webhook_config/{id} exigem
também a role companyadmin ou admin — é um requisito
adicional, não substituído pelas roles de segredo de justiça. Ao setar
qualquer campo de segredo (segredo_url, is_segredo_active ou
public_key), a API também verifica se o módulo
api.monitoramento.proc.segredo-justica está habilitado para a empresa —
retornando 403 Forbidden caso contrário.
Gerando o par de chaves:
# Chave privada — guarde em segurança, nunca compartilhe
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 \
-out chave_privada.pem
# Chave pública para envio ao OP
openssl rsa -pubout -in chave_privada.pem -out chave_publica.pem
Aviso
Formato do PEM no JSON: o campo public_key precisa conter
quebras de linha reais (\n) separando o cabeçalho, o corpo em
Base64 e o rodapé — sem isso, a validação do PEM falha com
400 Bad Request. Se você gerou a chave com openssl (comando
acima), o arquivo já vem com as quebras de linha; ao colar o conteúdo
em uma string JSON, troque cada quebra de linha real por \n
(a maioria das bibliotecas HTTP faz isso automaticamente ao serializar
uma string multi-linha — o problema costuma aparecer só ao montar o
JSON manualmente, como num curl -d).
Criando a configuração pela primeira vez (POST):
Se a empresa ainda não tem nenhum webhook_config cadastrado (verifique
com um GET /api/webhook_config), use POST — note que
user_company_id é obrigatório no corpo e não é preenchido
automaticamente a partir do usuário autenticado:
POST /api/webhook_config
Authorization: Bearer <token>
Content-Type: application/json
{
"user_company_id": 123,
"segredo_url": "https://seu-servidor.com/webhooks/segredo-justica",
"is_segredo_active": true,
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkq...\n-----END PUBLIC KEY-----\n"
}
A resposta traz o id gerado para essa configuração — guarde-o, é
o valor usado no {id} das próximas atualizações via PATCH.
Atualizando uma configuração existente (PATCH):
Se a empresa já tem um webhook_config (o caso comum após o cadastro
inicial), use PATCH no id retornado pelo POST — ou obtido via
GET /api/webhook_config:
PATCH /api/webhook_config/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"segredo_url": "https://seu-servidor.com/webhooks/segredo-justica",
"is_segredo_active": true,
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkq...\n-----END PUBLIC KEY-----\n"
}
Nota
O {id} acima é o identificador da própria linha de
webhook_config — não é o user_company_id nem qualquer
outro identificador. Diferente do fluxo de webhook regular (que
expõe o atalho current_webhook_config para a empresa não
precisar descobrir esse id), o canal de segredo de justiça exige
o id explícito.
Campo |
Tipo |
Descrição |
|---|---|---|
|
string |
URL do endpoint do cliente que receberá os eventos de segredo. |
|
boolean |
Habilita ( |
|
string |
Chave pública RSA-4096 do cliente em formato PEM
( |
Nota
Eventos de segredo de justiça são entregues exclusivamente ao
segredo_url, nunca ao url padrão do webhook. Os demais eventos
(não-segredo) continuam sendo entregues ao url configurado normalmente.
Resumo de roles#
A tabela abaixo lista todas as roles específicas de segredo de justiça e o endpoint que cada uma desbloqueia.
Role |
O que libera |
|---|---|
|
|
|
|
|
|
Criando um processo monitorado#
Nota
Role necessária (POST): api.monitoramento.proc.segredo-justica.gerenciar.
Além disso, a API valida que o webhook já está configurado: se
is_segredo_active não for true ou public_key não estiver
preenchida, a requisição retorna 400 Bad Request. Esse comportamento
reforça a obrigatoriedade do webhook como pré-requisito.
Para registrar um processo em segredo de justiça, utilize POST /api/monitoramento/proc
informando o número CNJ e a credencial que será usada na coleta.
Requisição:
POST /api/monitoramento/proc
Authorization: Bearer <token>
Content-Type: application/json
{
"numero": "0001234-56.2024.8.26.0100",
"credencial_id": 42
}
Resposta (200):
{
"$uri": "/api/monitoramento/proc/98765",
"numero": "0001234-56.2024.8.26.0100",
"credencial_id": 42,
"is_monitored_diario": false,
"is_monitored_tribunal": false
}
Nota
Processos em segredo de justiça têm is_monitored_diario e
is_monitored_tribunal sempre false — a coleta é disparada pela
credencial cadastrada, não pelo fluxo diário ou de tribunal. O campo
credencial_id deve ser o id inteiro retornado pelo endpoint de
criação de credencial. O mesmo CNJ pode ser monitorado por credenciais
distintas (cada par numero + credencial_id é um monitoramento
independente). Não é possível converter um processo regular em segredo de
justiça via PATCH.
A coleta é executada automaticamente por um job diário (0 2 * * *) que
percorre os processos monitorados e enfileira uma consulta para cada
credencial ativa. O resultado chega ao cliente via webhook.
Listando e visualizando monitoramentos#
Nota
Role necessária (GET): api.monitoramento.proc.segredo-justica.listar
ou .gerenciar (quem gerencia também pode visualizar). Sem nenhuma das
duas, tentativas de acessar GET /api/monitoramento/proc/{id} retornam
404 Not Found — propositalmente, para não confirmar que aquele ID
corresponde a um monitoramento em segredo de justiça.
Para listar todos os monitoramentos ativos:
GET /api/monitoramento/proc
Authorization: Bearer <token>
Para visualizar um monitoramento específico:
GET /api/monitoramento/proc/{id}
Authorization: Bearer <token>
Resposta (200):
{
"$uri": "/api/monitoramento/proc/98765",
"numero": "0001234-56.2024.8.26.0100",
"credencial_id": 42,
"is_monitored_diario": false,
"is_monitored_tribunal": false,
"archived_at": null
}
Alterando um monitoramento#
Nota
Role necessária (PATCH): api.monitoramento.proc.segredo-justica.gerenciar.
Restrições:
Não é possível transformar um processo regular em segredo de justiça via
PATCH(adicionarcredencial_idonde antes era nulo retorna403).Os campos
is_monitored_diarioeis_monitored_tribunalnão podem ser alterados paratrueem processos de segredo de justiça.
O principal uso do PATCH é trocar a credencial associada ao
monitoramento (por exemplo, ao renovar um certificado A1):
PATCH /api/monitoramento/proc/{id}
Authorization: Bearer <token>
Content-Type: application/json
{
"credencial_id": 99
}
Resposta (200): retorna o objeto atualizado no mesmo formato do
GET /api/monitoramento/proc/{id}.
Arquivando um monitoramento#
Nota
Role necessária (DELETE): api.monitoramento.proc.segredo-justica.gerenciar.
A operação é um arquivamento soft-delete — o monitoramento recebe um
archived_at e deixa de ser processado, mas o registro permanece
acessível via filtro archived_at!=null.
DELETE /api/monitoramento/proc/{id}
Authorization: Bearer <token>
Resposta: 204 No Content.
Listando eventos monitorados#
Os eventos gerados pelo monitoramento de processos em segredo de justiça
(tipos 22, 23 e 24) são entregues via webhook, mas também ficam
disponíveis para consulta no endpoint de eventos monitorados.
Nota
Role necessária (GET): api.monitoramento.proc.segredo-justica.eventos.
Sem esta role, os eventos dos tipos 22, 23 e 24 são
automaticamente removidos da listagem — a resposta retorna 200
mas omite silenciosamente esses tipos. Os demais tipos de evento
continuam visíveis normalmente.
GET /api/monitoramento/monitored_event
Authorization: Bearer <token>
É possível filtrar por tipo de evento usando o parâmetro where:
GET /api/monitoramento/monitored_event?where={"evt_type":23}
Authorization: Bearer <token>
Eventos gerados#
O monitoramento gera três tipos de evento, todos entregues ao segredo_url
configurado:
Tipo |
Nome |
Quando é gerado |
|---|---|---|
|
|
Ao final de uma validação de login (sucesso ou falha) para a credencial. |
|
|
Quando a consulta retorna dados de um processo. O campo |
|
|
Quando a coleta termina com erro (ex: credencial inválida, tribunal indisponível). |
VALIDACAO_LOGIN (tipo 22)#
O campo data não é criptografado. Exemplo de login bem-sucedido:
{
"credencial_id": "999",
"status": "CONECTADO",
"acesso_id": 2001
}
Exemplo de falha de login:
{
"credencial_id": "999",
"status": "FALHOU",
"acesso_id": 2001,
"erro": "Descrição técnica do erro"
}
Os valores possíveis de status são CONECTADO e FALHOU. O campo
acesso_id contém o ID da execução de um dos nossos workers para o login da credencial.
COLETA_SEGREDO_JUSTICA (tipo 23)#
O campo data contém o payload criptografado em base64. Consulte
Descriptografia do payload para o formato e o exemplo de código.
Após a descriptografia, o JSON resultante é uma lista com um elemento no seguinte formato:
[
{
"id": "123456",
"data": "2024-01-15T10:30:00",
"tipo": "Intimação",
"magistrado": "Dr. Fulano de Tal",
"processo": {
"id": 98765,
"numero": "0001234-56.2024.8.26.0100",
"instancia": "1",
"codigo_classe_natureza_tribunal": "456",
"classe_natureza": "Ação Ordinária",
"assunto": "Responsabilidade Civil",
"vara": "3ª Vara Cível",
"orgao": null,
"parte_interessada": "Empresa XYZ Ltda",
"valor": "R$ 50.000,00",
"processos_relacionados": null,
"perfil": null,
"partes": null,
"estado_sigla": "SP",
"tribunal": "TJSP",
"audiencia": null,
"sessao_julgamento": null,
"numero_processo_antigo": null,
"situacao": null,
"sistema": {
"nome": "esaj",
"id": 3
}
}
}
]
COLETA_SEGREDO_JUSTICA_ERROR (tipo 24)#
Gerado quando a coleta termina com status_job = 'error' — por
exemplo, credencial expirada ou tribunal indisponível. Quando a consulta é
bem-sucedida mas não retorna notificações, nenhum evento é criado.
O campo data não é criptografado:
{
"credencial_id": "a1b2c3d4-...",
"erro": "Descrição técnica do erro (ex: credencial expirada)"
}
Descriptografia do payload#
O payload do evento COLETA_SEGREDO_JUSTICA é cifrado com criptografia
híbrida RSA-4096-OAEP + AES-256-GCM, garantindo que apenas o cliente
— detentor da chave privada RSA — consiga acessar o conteúdo.
Formato do blob (após decodificação base64)#
[ dek_ct (512 bytes) | nonce (12 bytes) | ciphertext (variável) ]
dek_ct — A data encryption key (DEK) AES-256 cifrada com a chave pública RSA-4096 do cliente via RSA-OAEP (SHA-256). Sempre 512 bytes (tamanho da chave RSA-4096).
nonce — 12 bytes aleatórios gerados para cada mensagem, usados no AES-GCM.
ciphertext — Dados da notificação cifrados com AES-256-GCM usando a DEK e o
user_company_id(em string) como AAD (additional authenticated data).
Exemplo de descriptografia em Python#
import base64
import json
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.backends import default_backend
def descriptografar_payload(
payload_b64: str,
chave_privada_pem: bytes,
user_company_id: int,
) -> list:
"""
Descriptografa o campo ``data`` de um evento COLETA_SEGREDO_JUSTICA.
:param payload_b64: Valor do campo ``data`` do evento (base64).
:param chave_privada_pem: Chave privada RSA em PEM (bytes).
:param user_company_id: ID da empresa no OP (mesmo valor do evento).
:returns: Lista de notificações (JSON decodificado).
"""
raw = base64.b64decode(payload_b64)
dek_ct = raw[:512] # DEK cifrada com RSA-4096
nonce = raw[512:524] # 12 bytes
ct = raw[524:] # ciphertext AES-GCM
private_key = serialization.load_pem_private_key(
chave_privada_pem,
password=None,
backend=default_backend(),
)
# Decifra a DEK com RSA-OAEP
dek = private_key.decrypt(
dek_ct,
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
# Decifra os dados com AES-256-GCM
# AAD = str(user_company_id) vincula o blob ao tenant
aesgcm = AESGCM(dek)
plaintext = aesgcm.decrypt(
nonce,
ct,
str(user_company_id).encode(),
)
return json.loads(plaintext)
# Exemplo de uso:
#
# with open('chave_privada.pem', 'rb') as f:
# chave_privada_pem = f.read()
#
# notificacoes = descriptografar_payload(
# payload_b64=event['data'],
# chave_privada_pem=chave_privada_pem,
# user_company_id=event['user_company_id'],
# )
# print(notificacoes[0]['processo']['numero'])
Nota
O user_company_id está presente no corpo do evento entregue ao webhook.
Usar um valor incorreto resulta em InvalidTag (falha na autenticação
AES-GCM), indicando que AAD não confere — verifique o ID da empresa
antes de tentar novamente.