Trust policy por flow — quién confía en quién
Este conteúdo não está disponível em sua língua ainda.
Cuando un usuario llega a un onboarding nuevo con su wallet ya verificado en
otro tenant, el comercio que recibe la solicitud tiene que tomar una decisión:
¿confío en la verificación que hizo el otro tenant, o exijo mi propio KYC
desde cero? El campo flow.trust_policy deja esa decisión en manos del
tenant, por flow.
Las tres posturas
Sección titulada «Las tres posturas»Tres modos canónicos, en orden de menor a mayor riesgo aceptado:
Ciego — accept_wallet_reuse: false
Sección titulada «Ciego — accept_wallet_reuse: false»{ "accept_wallet_reuse": false}El flow nunca consume verificaciones de otros tenants. Cada usuario nuevo hace KYC desde cero, sin importar si ya tiene wallet activo. Es el default para flows nuevos — el tenant tiene que activar el reuso explícitamente vía PATCH al flow.
Cuándo elegirlo: banca regulada con SARLAFT estricto, gobierno, sectores donde la auditoría regulatoria exige verificación de identidad propia por entidad.
Selectivo curado — trusted_issuers específicos
Sección titulada «Selectivo curado — trusted_issuers específicos»{ "accept_wallet_reuse": true, "minimum_loa": "LoA3", "trusted_issuers": [ "cashpaya-tenant-id", "cooperativa-x-tenant-id" ], "max_credential_age_days": 180, "claims_required": ["full_name", "document_id", "address"]}El tenant acepta wallets que hayan pasado por una lista cerrada de origenes de confianza. Es el modelo de las redes cooperativas — un grupo de fintechs o cooperativas que se conocen, se auditan mutuamente, y aceptan los KYCs del grupo.
Cuándo elegirlo: ecosistemas de partners formales con acuerdos bilaterales de KYC; redes cooperativas donde se hace due diligence sobre los verificadores.
Abierto — trusted_issuers: ["*"]
Sección titulada «Abierto — trusted_issuers: ["*"]»{ "accept_wallet_reuse": true, "minimum_loa": "LoA3", "trusted_issuers": ["*"], "max_credential_age_days": 90, "require_revalidation_steps": ["face_match"]}El tenant acepta wallets de cualquier origen del ecosistema bjungle, siempre que cumplan el LoA mínimo y los claims requeridos. Maximiza el efecto de red — el primer usuario que llega con wallet ahorra 8 minutos de KYC.
require_revalidation_steps opcionalmente puede pedir que pasos específicos
del flow (ej. face_match) se ejecuten de todos modos aunque el wallet ya
los tenga firmados. Útil para acoplar reuso con biometría fresca, cubriendo
el caso “el documento ya estaba verificado pero quiero confirmar que la
persona presente hoy es la misma”.
Cuándo elegirlo: e-commerce, productos de bajo riesgo, comercios donde la fricción del KYC es el bloqueador principal del crecimiento.
El campo en detalle
Sección titulada «El campo en detalle»interface TrustPolicy { accept_wallet_reuse: boolean; // default false minimum_loa: "LoA1" | "LoA2" | "LoA3" | "LoA4"; // default LoA3 trusted_issuers: string[]; // [] = none, ["*"] = any max_credential_age_days: number; // default 180 require_revalidation_steps: string[]; // ej. ["face_match"] claims_required: string[]; // ej. ["full_name", "document_id"]}Persistido como jsonb en la columna flows.trust_policy (migración
0006). Por flow porque un mismo tenant puede tener una política estricta
para onboarding-banca y una abierta para onboarding-loyalty.
Cómo lo usa el engine
Sección titulada «Cómo lo usa el engine»- Antes de que el usuario empiece el onboarding, el frontend del tenant
puede llamar
POST /v1/wallet/discovercon el documento para preguntar “¿este usuario ya tiene wallet?”. - Si la respuesta es positiva y la
trust_policydel flow del tenant lo permite, el frontend redirige al usuario al flujo de consent en lugar del onboarding completo. - Si el usuario aprueba el consent, el tenant recibe los claims firmados
via webhook
bmonkey.presentation.grantedy crea su subject local sin ejecutar el flow. - Si el wallet no tiene los claims requeridos al LoA pedido (
claims_requiredminimum_loa), el approve emitebmonkey.presentation.deniedconreason: claims_unavailabley el frontend cae al onboarding completo.
Decisión pendiente
Sección titulada «Decisión pendiente»El BACKLOG marca como decisión pendiente el default para el sprint+1:
¿el default de accept_wallet_reuse debería ser false (postura
conservadora actual) o true con un curado central por bjungle (postura
network-effect)?
| Opción | Pro | Contra |
|---|---|---|
| Ciego por default | seguro, el tenant opta in conscientemente | el reuso casi nunca pasa |
| Abierto LoA3+ por default | máxima velocidad de adopción | el tenant nuevo no sabe lo que está aceptando |
| Selectivo curado por bjungle | bjungle audita el origen | bjungle se vuelve árbitro de confianza |
Mi recomendación arquitectónica: ciego por default + onboarding-wizard del admin-console que pregunta al tenant en la creación del flow. Convierte la decisión en consciente sin sacrificar adoption.
Estado de la implementación
Sección titulada «Estado de la implementación»| Componente | Estado |
|---|---|
Migración con campo trust_policy jsonb | ✅ 0006 |
| Domain types Go + repo | ✅ T6 |
| Engine bifurca onboarding según policy | ⏳ pendiente |
| UI del builder del portal para configurar | ⏳ pendiente |
Los dos pendientes están agrupados en el ticket “bmonkey — modelo multi-tenant y trust policy por flow” del BACKLOG.
Referencias
Sección titulada «Referencias»- Migración:
bmonkey/backend/db-bmonkey/migrations/0006_flow_trust_policy.up.sql - Domain:
bmonkey/backend/go-bmonkey-api/internal/domain/wallet.go(TrustPolicy) - BACKLOG: sección “bmonkey — modelo multi-tenant”