Skip to content
StableAudienceDevSécuritéAudit banqueComplianceOwner@security-teamDernière revue2026-05-21

Service Risk Engine

Moteur d'évaluation des risques (fraude, AML, conformité) sur chaque demande de paiement ou transfert. Retourne une décision typée approved / challenged / blocked avec score, raisons audit et trace complète.

Voir aussi /services/risk-engine/preflight pour le mode prefetch utilisé par l'orchestrator en pré-confirmation d'intent (ADR-0007).

Identité

AttributValeur
Package@nex/service-risk-engine v0.0.1
Port3000
Schéma DBrisk_engine (PostgreSQL)
Swaggerservices/risk-engine/src/main.ts:54 — actif, tags risk-rules, risk-evaluation, fraud-detection
README❌ absent
Owner@security-team

Surface API

ControllerRouteEndpoints
risk-engine.controller.ts/risk3 (POST /evaluate, GET /evaluations/:id, GET /evaluations/:id/archive)
app.controller.ts/1 (health)

Pipeline d'évaluation

services/risk-engine/src/application/evaluate-risk.use-case.ts

  1. Idempotency check (style Stripe, TTL 24 h) — cache hit → retour immédiat de la décision précédente avec son policyId.
  2. Build context — en parallèle :
    • sender KYC level + rejection status (KycStatusHttpAdapter)
    • receiver KYC level + rejection status
    • ResolvedTransactionPolicy (TransactionPolicyHttpAdapter)
    • velocity aggregates (LedgerAggregatesHttpAdapter)
  3. Run rule engine — chain of responsibility, court-circuit critique.
  4. Compose score + decisionRiskScoringService.
  5. Build RiskDecision — enrichissement des raisons depuis RISK_REASON_CATALOG.
  6. Persist — audit append-only en DB + register idempotency key.

Fail-closed strict V1

Toute DependencyUnavailableError (KYC, configuration, ledger) → RiskDecision blocked avec RuleCode = DEPENDENCY_UNAVAILABLE. Pas de fail-open. Pas de retry au runtime (timeout 80 ms par adapter, configurable).

Règles V1 (8 rules, 2 couches actives)

LayerRuleComportement
0EligibilityFromPolicyRuleVérifie l'éligibilité depuis la policy résolue
0KycRejectedRuleCourt-circuite avant KycLevel — si rejeté → blocked
0KycLevelRuleVérifie le niveau KYC requis par la policy
0SamePartyForbiddenRulesender.accountId === receiver.accountId → blocked
1PerTransactionLimitRuleLimite par transaction (depuis policy)
2CumulativeCapRule (daily)Plafond journalier cumulé
2CumulativeCapRule (weekly)Plafond hebdomadaire
2CumulativeCapRule (monthly)Plafond mensuel

Trust boundary prefetched

Le champ RiskEvaluationRequest.prefetched accepte un snapshot de contexte (sender KYC, receiver KYC, sender balance) uniquement depuis un caller avec le scope JWT risk:evaluate:trusted.

Garanties (cf. ADR-0007) :

  • prefetched n'accepte jamais policy, eligibility ou limits — 3 barrières : type DTO, ValidationPipe, sanitize runtime.
  • La ResolvedTransactionPolicy est toujours re-résolue côté risk-engine via TransactionPolicyHttpAdapter.

Modèle de données

src/infrastructure/persistence/entities/ :

EntityRôle
RiskEvaluationTrace append-only des évaluations (input snapshot, output decision, policyId, durée, rules déclenchées)
RiskIdempotencyKeyClés d'idempotency avec TTL 24 h, purgées par cron horaire

Migrations : src/migrations/. Purge automatique des idempotency keys via @nestjs/schedule (cron horaire).

Dépendances

TypeDétails
Intra-monorepo@nex/shared-types (brand types, RiskEvaluationRequest/RiskDecision) · @nex/shared-utils (PhaseTimer, RISK_REASON_CATALOG)
Inter-services NexHTTP synchrone vers configuration (policy resolution), ledger-wallets (velocity aggregates), customer-profiles-kyc (KYC status)
Externes notables@nestjs/schedule, typeorm, pg, jsonwebtoken

Adapters HTTP (fail-closed)

AdapterCibleTimeout
TransactionPolicyHttpAdapterPOST /v1/configuration/transaction-policy/resolve80 ms
LedgerAggregatesHttpAdaptervelocity aggregates (ledger-wallets)80 ms
KycStatusHttpAdapterKYC level + rejection status (customer-profiles-kyc)80 ms

Note importante : TransactionPolicyHttpAdapter désérialise les valeurs bigint depuis des string JSON pour préserver la précision monétaire.

Pages à produire

  • data-model.md — schéma complet risk_evaluations + risk_idempotency_keys
  • rules.md — détail de chaque rule (input, output, code retourné)
  • runbook.md — alertes (taux de blocage anormal, latence adapters)
  • threat-model.md — STRIDE focalisé sur la manipulation de prefetched

Nex — Plateforme fintech CEMAC