Visão Geral
Os eventos de webhook de regras permitem que você receba notificações em tempo real quando regras de conformidade ou negócio são acionadas para entidades na plataforma Gu1. Esses eventos permitem que você automatize ações de conformidade, alerte sua equipe e mantenha trilhas de auditoria quando condições de risco são detectadas.
Por Que Usar Eventos de Regras?
Conformidade em Tempo Real Receba alertas instantâneos quando regras de risco são acionadas
Ações Automatizadas Bloqueie, sinalize ou escale entidades automaticamente
Trilha de Auditoria Rastreie todos os acionamentos de regras para relatórios de conformidade
Gestão de Riscos Responda a condições de alto risco imediatamente
Eventos Disponíveis
rule.triggered
O evento rule.triggered é disparado quando uma regra de conformidade ou negócio é avaliada como verdadeira para uma entidade.
Quando dispara :
Uma condição de regra é atendida durante criação ou atualização de entidade
Avaliação periódica de regras detecta uma correspondência
Regras de monitoramento de transações identificam atividade suspeita
Verificações de conformidade (PEP, sanções, mídia adversa) retornam correspondências positivas
Filtros disponíveis :
ruleIds: Receber apenas eventos para regras específicas
ruleSeverity: Filtrar por nível de severidade (low, medium, high, critical)
entityTypes: Filtrar por tipo de entidade
Payload do Evento
Payload de rule.triggered
{
"event" : "rule.triggered" ,
"timestamp" : "2025-01-07T14:00:00.000Z" ,
"payload" : {
"ruleId" : "550e8400-e29b-41d4-a716-446655440000" ,
"rule" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"name" : "High Risk Country Check" ,
"description" : "Flags entities from high-risk countries" ,
"severity" : "high" ,
"category" : "geographic_risk" ,
"isActive" : true
},
"entityId" : "123e4567-e89b-12d3-a456-426614174000" ,
"entity" : {
"id" : "123e4567-e89b-12d3-a456-426614174000" ,
"externalId" : "customer_xyz789" ,
"name" : "John Doe" ,
"type" : "person" ,
"countryCode" : "KP" ,
"status" : "blocked"
},
"evaluationId" : "eval_abc123" ,
"triggerData" : {
"countryCode" : "KP" ,
"riskLevel" : "critical" ,
"matchedCriteria" : [
"sanctioned_country" ,
"high_risk_jurisdiction"
],
"additionalInfo" : {
"sanctionList" : [ "OFAC" , "UN" ],
"riskScore" : 95
}
},
"action" : {
"type" : "block" ,
"reason" : "Entity from sanctioned country" ,
"automaticAction" : true ,
"previousStatus" : "under_review" ,
"newStatus" : "blocked"
},
"triggeredAt" : "2025-01-07T14:00:00.000Z"
}
}
Campos Chave do Payload
Identificador único da regra acionada
Informações completas da regra incluindo nome, descrição, severidade e categoria
Nível de severidade: low, medium, high, ou critical
A entidade que acionou a regra
Informações completas da entidade incluindo seu externalId
Identificador único para esta avaliação de regra
Dados que causaram o acionamento da regra, incluindo critérios correspondentes e pontuações de risco
Ação tomada como resultado do acionamento da regra (opcional)
Tipo de ação: block, flag, review, alert, ou none
Se a ação foi tomada automaticamente pelo Gu1
Categorias de Regras e Exemplos
Regras de Risco Geográfico
Acionadas quando entidades são de países ou jurisdições de alto risco:
{
"rule" : {
"name" : "Sanctioned Country Check" ,
"category" : "geographic_risk" ,
"severity" : "critical"
},
"triggerData" : {
"countryCode" : "IR" ,
"sanctionList" : [ "OFAC" , "EU" ],
"riskLevel" : "critical"
},
"action" : {
"type" : "block" ,
"automaticAction" : true
}
}
Regras PEP (Pessoa Politicamente Exposta)
Acionadas quando a entidade corresponde a bancos de dados PEP:
{
"rule" : {
"name" : "PEP Screening" ,
"category" : "pep_check" ,
"severity" : "high"
},
"triggerData" : {
"pepStatus" : "confirmed" ,
"position" : "Former Government Official" ,
"country" : "XX" ,
"matchConfidence" : 0.95 ,
"source" : "World-Check"
},
"action" : {
"type" : "review" ,
"automaticAction" : true
}
}
Regras de Triagem de Sanções
Acionadas quando a entidade aparece em listas de sanções:
{
"rule" : {
"name" : "OFAC Sanctions Screening" ,
"category" : "sanctions" ,
"severity" : "critical"
},
"triggerData" : {
"matchType" : "exact" ,
"sanctionList" : "OFAC SDN" ,
"matchedName" : "John Doe" ,
"listingDate" : "2020-01-15" ,
"program" : "Counter Terrorism"
},
"action" : {
"type" : "block" ,
"automaticAction" : true
}
}
Configuração de Filtros
Filtrar por ID de Regra
Receber apenas eventos para regras específicas:
{
"eventTypes" : [ "rule.triggered" ],
"filters" : {
"ruleIds" : [
"rule_sanctions_ofac" ,
"rule_high_risk_country"
]
}
}
Filtrar por Severidade
Receber apenas alertas de severidade alta e crítica:
{
"eventTypes" : [ "rule.triggered" ],
"filters" : {
"ruleSeverity" : [ "high" , "critical" ]
}
}
Filtrar por Tipo de Entidade
Receber apenas regras acionadas para pessoas:
{
"eventTypes" : [ "rule.triggered" ],
"filters" : {
"entityTypes" : [ "person" ]
}
}
Exemplos de Código
const express = require ( 'express' );
const app = express ();
app . use ( express . json ({
verify : ( req , res , buf ) => {
req . rawBody = buf . toString ( 'utf8' );
}
}));
app . post ( '/webhooks/rules' , async ( req , res ) => {
try {
// Verificar assinatura (veja guia de segurança)
if ( ! verifySignature ( req . rawBody , req . headers [ 'x-webhook-signature' ])) {
return res . status ( 401 ). json ({ error: 'Invalid signature' });
}
const { event , payload } = req . body ;
if ( event === 'rule.triggered' ) {
await handleRuleTriggered ( payload );
}
res . status ( 200 ). json ({ success: true });
} catch ( error ) {
console . error ( 'Webhook error:' , error );
res . status ( 500 ). json ({ error: error . message });
}
});
async function handleRuleTriggered ( payload ) {
const { rule , entity , triggerData , action , evaluationId } = payload ;
console . log ( `Rule triggered: ${ rule . name } for ${ entity . name } ` );
// Registrar acionamento de regra
await db . ruleTriggers . create ({
data: {
ruleId: rule . id ,
ruleName: rule . name ,
entityId: entity . id ,
externalId: entity . externalId ,
severity: rule . severity ,
triggerData ,
evaluationId ,
triggeredAt: new Date ()
}
});
// Lidar com base na severidade
switch ( rule . severity ) {
case 'critical' :
await handleCriticalRule ( rule , entity , triggerData , action );
break ;
case 'high' :
await handleHighSeverityRule ( rule , entity , triggerData , action );
break ;
case 'medium' :
await handleMediumSeverityRule ( rule , entity , triggerData , action );
break ;
case 'low' :
await handleLowSeverityRule ( rule , entity , triggerData , action );
break ;
}
// Lidar com base no tipo de ação
if ( action ) {
switch ( action . type ) {
case 'block' :
await handleBlockAction ( entity , action );
break ;
case 'review' :
await handleReviewAction ( entity , rule , action );
break ;
case 'flag' :
await handleFlagAction ( entity , rule , action );
break ;
case 'alert' :
await handleAlertAction ( entity , rule , action );
break ;
}
}
}
async function handleCriticalRule ( rule , entity , triggerData , action ) {
console . log ( `🚨 CRITICAL: ${ rule . name } triggered for ${ entity . name } ` );
// Bloquear entidade imediatamente se ainda não estiver bloqueada
if ( entity . status !== 'blocked' ) {
await blockEntity ( entity . id , rule . name );
}
// Alertar equipe de conformidade imediatamente
await slack . send ({
channel: '#compliance-critical' ,
priority: 'critical' ,
message: `🚨 CRITICAL RULE TRIGGERED` ,
fields: {
'Rule' : rule . name ,
'Entity' : entity . name ,
'External ID' : entity . externalId ,
'Severity' : rule . severity ,
'Action Taken' : action ?. type || 'none' ,
'Details' : JSON . stringify ( triggerData , null , 2 )
}
});
// Criar caso de alta prioridade
await compliance . createCase ({
entityId: entity . id ,
ruleId: rule . id ,
priority: 'critical' ,
type: 'rule_trigger' ,
data: { rule , entity , triggerData , action },
assignTo: 'compliance-lead'
});
}
app . listen ( 3000 );
from flask import Flask, request, jsonify
import logging
app = Flask( __name__ )
@app.route ( '/webhooks/rules' , methods = [ 'POST' ])
def rules_webhook ():
try :
# Verificar assinatura (veja guia de segurança)
signature = request.headers.get( 'X-Webhook-Signature' )
raw_body = request.get_data( as_text = True )
if not verify_signature(raw_body, signature):
return jsonify({ 'error' : 'Invalid signature' }), 401
# Analisar webhook
payload = request.json
event = payload[ 'event' ]
data = payload[ 'payload' ]
if event == 'rule.triggered' :
handle_rule_triggered(data)
return jsonify({ 'success' : True }), 200
except Exception as e:
logging.error( f 'Webhook error: { e } ' )
return jsonify({ 'error' : str (e)}), 500
def handle_rule_triggered ( data ):
rule = data[ 'rule' ]
entity = data[ 'entity' ]
trigger_data = data[ 'triggerData' ]
action = data.get( 'action' )
logging.info( f "Rule triggered: { rule[ 'name' ] } for { entity[ 'name' ] } " )
# Registrar acionamento
db.rule_triggers.insert({
'rule_id' : rule[ 'id' ],
'rule_name' : rule[ 'name' ],
'entity_id' : entity[ 'id' ],
'external_id' : entity[ 'externalId' ],
'severity' : rule[ 'severity' ],
'trigger_data' : trigger_data,
'evaluation_id' : data[ 'evaluationId' ]
})
# Lidar com base na severidade
severity_handlers = {
'critical' : handle_critical_rule,
'high' : handle_high_severity_rule,
'medium' : handle_medium_severity_rule,
'low' : handle_low_severity_rule
}
handler = severity_handlers.get(rule[ 'severity' ])
if handler:
handler(rule, entity, trigger_data, action)
def handle_critical_rule ( rule , entity , trigger_data , action ):
logging.critical( f "CRITICAL: { rule[ 'name' ] } triggered for { entity[ 'name' ] } " )
# Bloquear entidade
if entity[ 'status' ] != 'blocked' :
block_entity(entity[ 'id' ], rule[ 'name' ])
# Alertar equipe
slack.send({
'channel' : '#compliance-critical' ,
'message' : f "🚨 CRITICAL RULE TRIGGERED: { rule[ 'name' ] } " ,
'fields' : {
'Entity' : entity[ 'name' ],
'External ID' : entity[ 'externalId' ],
'Severity' : rule[ 'severity' ]
}
})
if __name__ == '__main__' :
app.run( port = 3000 )
Melhores Práticas
Armazene Acionamentos de Regras para Auditoria
Sempre registre acionamentos de regras para trilhas de auditoria de conformidade: await db . ruleTriggers . create ({
data: {
ruleId: rule . id ,
entityId: entity . id ,
evaluationId: evaluationId ,
triggerData ,
triggeredAt: new Date (),
webhook: req . body
}
});
Lide com Severidade Apropriadamente
Use ID de avaliação para prevenir processamento duplicado: const processed = await db . webhookLog . findUnique ({
where: { evaluationId: payload . evaluationId }
});
if ( processed ) {
return ; // Pular duplicado
}
Próximos Passos