Commit 1cf476a4 authored by Cesar Cajas's avatar Cesar Cajas
Browse files

OCF239-rulesets-for-visibility-control-api: initial doc proposal of rulesets

parent 3a480f22
Loading
Loading
Loading
Loading
Loading
+115 −0
Changes for services/helper/helper_service/services/visibility_control/RULESETS_EXEC_SUMMARY.md: 115 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Rulesets - Executive Summary (10 min presentation)

## El Problema en 30 segundos

```
Hoy:        Provider registra reglas una por una
            → Difícil saber cuál es el estado actual
            → Imposible revertir cambios
            → Conflictos entre reglas viejas y nuevas
```

## La Solución en 30 segundos

```
Mañana:     Provider publica todas sus reglas como "Ruleset"
            → Versión 1, Versión 2, Versión 3...
            → Solo 1 versión activa = estado claro
            → Revertir es cambiar de versión (1 click)
            → Historial completo para auditoría
```

---

## 3 Ejemplos Rápidos

### Ejemplo 1: Operación Normal
```
Provider "Payment API" publica Ruleset v2:
  • Premium Partners → ALLOW
  • Startup Program → ALLOW (trial)
  • Competitors → DENY

Resultado: v1 se depreca, v2 es ACTIVE
Invokers ven los permisos de v2
```

### Ejemplo 2: Algo Salió Mal
```
Provider se da cuenta que el trial a Startup Program está activo
después de 3 meses (debería haber terminado)

Solución: PUT /rules/activate-ruleset/v1
Resultado: En 1 segundo, v1 vuelve ACTIVE
```

### Ejemplo 3: Auditoría
```
Invoker pregunta: "¿Cuándo me quitaron acceso?"

Respuesta clara:
  • v1: Tenías acceso (2026-05-01)
  • v2: Se te quitó (2026-05-15) ← Aquí pasó
  • v3: Sigue sin acceso (2026-05-20)
```

---

## Beneficios Concretos

| Beneficio | Impacto |
|-----------|---------|
| **Sin conflictos** | Menos bugs, menos bugs report |
| **Rollback rápido** | Recuperación de errores en segundos |
| **Historial claro** | Auditoría completa = compliance |
| **Escalable** | Providers pueden tener infinitas reglas |
| **Simple** | Un ruleset = una "foto" del estado |

---

## Cómo Funciona (Imagen Mental)

```
Es como Git para reglas:

  v1 ─── v2 ─── v3 (ACTIVE)
  │               │
  DEPRECATED    EN USO
  
Si v3 falla → git checkout v2
```

---

## Implementación: 3 Fases

| Fase | Tiempo | Qué | Resultado |
|------|--------|-----|-----------|
| **1** | Semana 1 | Crear Ruleset model + 2 endpoints | Publish & Activate |
| **2** | Semana 2 | Migrar reglas existentes + tests | Todo funciona |
| **3** | Semana 3 | Validación + Dashboard | Listo para producción |

---

## ¿Preguntas Cortas?

**P: ¿Se pierden las versiones viejas?**  
R: No, están guardadas. Se pueden activar.

**P: ¿Cuánto ocupa storage?**  
R: Mínimo. ~50KB por ruleset con 100 reglas.

**P: ¿Qué si cambio solo 1 regla?**  
R: Provider descarga v actual, cambia 1, publica como v(n+1).

**P: ¿Quién puede cambiar versiones?**  
R: El provider (o admin). Igual que ahora.

---

## Siguiente Paso

✅ Aprobación de concepto  
→ Diseño de endpoints  
→ Desarrollo Fase 1  
→ Testing  
+266 −0
Changes for services/helper/helper_service/services/visibility_control/RULESETS_PROPOSAL.md: 266 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Visibility Control Rulesets - Proposal

## El Problema Actual

Cuando un **Provider** registra reglas de visibilidad una por una:
- Regla 1: ALLOW api-001 para invoker-A
- Regla 2: DENY api-001 para invoker-B  
- Regla 3: ALLOW api-002 para invoker-A
- ...

**Problemas:**
- ❌ Conflictos entre reglas viejas y nuevas
- ❌ No hay forma de "revertir" cambios
- ❌ Difícil saber cuál es el estado actual intacto
- ❌ Sin historial claro de cambios
- ❌ Un invoker ve resultados inconsistentes si hay overlap

---

## La Solución: Rulesets Versionados

### Concepto Simple

**Ruleset** = Un "paquete" con todas las reglas de un provider en un momento específico

```
Provider "capif-prov-001"
│
├─ Ruleset v1 (ACTIVE)
│  ├─ Regla: ALLOW api-001 para invoker-A
│  ├─ Regla: DENY api-001 para invoker-B
│  └─ Regla: ALLOW api-002 para invoker-A
│
├─ Ruleset v2 (DEPRECATED)
│  ├─ Regla: ALLOW api-001 para invoker-A
│  └─ Regla: ALLOW api-002 para invoker-A
│
└─ Ruleset v3 (CREATING...)
   └─ [Provider está preparando las nuevas reglas]
```

### Cómo Funciona

#### Situación 1: Provider registra nuevas reglas
```
1. Provider envía: POST /rules/publish-ruleset
   {
     "rules": [
       {"invokerSelector": "invoker-A", "apiId": "api-001", "decision": "ALLOW"},
       {"invokerSelector": "invoker-B", "apiId": "api-001", "decision": "DENY"},
       {"invokerSelector": "invoker-A", "apiId": "api-002", "decision": "ALLOW"}
     ]
   }

2. Sistema valida: ¿Hay conflictos internos? ✅ OK

3. Sistema crea: Ruleset v2 con estado ACTIVE

4. Sistema desactiva: Ruleset v1 → DEPRECATED (guarda en historial)

5. Resultado: Invoker-A ve [api-001, api-002]
              Invoker-B ve [] (api-001 negado)
```

#### Situación 2: Algo salió mal, revertir rápido
```
Provider envía: PUT /rules/activate-ruleset/v1

Sistema:
1. Desactiva v2 (DEPRECATED)
2. Activa v1 (ACTIVE)
3. Guarda cambio en historial

→ En 1 segundo estamos de vuelta al estado anterior ✅
```

#### Situación 3: Consultar historial
```
GET /rules/history/capif-prov-001

Respuesta:
[
  {version: 3, status: "ACTIVE", activatedAt: "2026-05-21 10:00"},
  {version: 2, status: "DEPRECATED", activatedAt: "2026-05-20", deactivatedAt: "2026-05-21 10:00"},
  {version: 1, status: "DEPRECATED", activatedAt: "2026-05-19", deactivatedAt: "2026-05-20"}
]
```

---

## Ventajas Clave

| Aspecto | Antes (Sin Rulesets) | Después (Con Rulesets) |
|--------|----------------------|--------------------------|
| **Conflictos** | Posibles ⚠️ | Prevenidos ✅ |
| **Revertir cambios** | Manual/Difícil | Un click (1 línea) |
| **Historial** | No existe | Completo con timestamps |
| **Auditoría** | Confusa | Clara: quién, cuándo, qué versión |
| **Testing** | Difícil | Fácil: test v1, v2, v3 |
| **Estado actual** | Confuso | Obvio: solo 1 ruleset ACTIVE |
| **Límite de reglas** | Ilimitado pero caótico | Ilimitado por versión, ordenado |

---

## Ejemplo Práctico para la Audiencia

### Analogía: Control de Versiones

Es como **Git para reglas de visibilidad**:

```
Provider es como un "desarrollador":
- Crea Ruleset v1 (git commit 1)
- Crea Ruleset v2 (git commit 2)  
- Si v2 tiene bugs, revierte a v1 (git checkout v1)
- El historial queda registrado
```

### Escenario Real: E-commerce

```
Provider: "Payment API" 

Ruleset v1 (Inicial):
├─ Invoker: "Premium Partners" → ALLOW payment-api
└─ Invoker: "Others" → DENY payment-api

Ruleset v2 (3 meses después - Expansión):
├─ Invoker: "Premium Partners" → ALLOW payment-api
├─ Invoker: "Startup Program" → ALLOW payment-api (trial)
├─ Invoker: "Others" → DENY payment-api
└─ Invoker: "Competitor-X" → DENY payment-api (específicamente)

Ruleset v3 (1 mes después - Ajuste):
├─ Invoker: "Premium Partners" → ALLOW payment-api
├─ Invoker: "Startup Program" → DENY payment-api (trial ended)
├─ Invoker: "Others" → DENY payment-api
└─ Invoker: "Competitor-X" → DENY payment-api

Si Startup Program se queja: "Antes me funcionaba"
→ Fácil verificar: Sí, en v2 tenían acceso. Pero se terminó el trial en v3.
```

---

## Implementación Técnica (Visión General)

### Cambios en MongoDB

**Antes:**
```javascript
{
  "_id": "rule-123",
  "providerId": "capif-prov-001",
  "invokerSelector": {...},
  "providerSelector": {...},
  "decision": "ALLOW",
  "enabled": true,
  "createdAt": "2026-05-20"
}
```

**Después:**
```javascript
{
  "rulesetId": "ruleset-capif-prov-001-v3",
  "providerId": "capif-prov-001",
  "version": 3,
  "status": "ACTIVE",  // ACTIVE, DEPRECATED
  "rules": [
    {
      "ruleId": "r1",
      "invokerSelector": {...},
      "providerSelector": {...},
      "decision": "ALLOW"
    },
    // ... más reglas
  ],
  "createdAt": "2026-05-21 10:00",
  "activatedAt": "2026-05-21 10:00",
  "deactivatedAt": null,
  "history": [
    {"version": 2, "activatedAt": "...", "deactivatedAt": "..."},
    {"version": 1, "activatedAt": "...", "deactivatedAt": "..."}
  ]
}
```

### Cambios en APIs

**Nuevos Endpoints:**

```
POST /rules/publish-ruleset
  Body: { rules: [...] }
  Returns: { rulesetId, version, status }
  Effect: Crea v(N+1), desactiva vN

PUT /rules/activate-ruleset/{version}
  Effect: Cambia a esa versión (ACTIVE)

GET /rules/history/{providerId}
  Returns: Historial de todas las versiones

DELETE /rules/deactivate-provider
  Effect: Sin ruleset activo = default ALLOW (fallback)
```

---

## Ventajas para CAPIF

1. **Escalabilidad**: Providers pueden tener infinitas reglas sin preocuparse de conflictos
2. **Confiabilidad**: Un ruleset = una "foto" consistente del estado
3. **Velocidad**: Cambiar entre versiones es instantáneo
4. **Transparencia**: Auditoría clara de quién cambió qué y cuándo
5. **Debugging**: Si hay problema, es fácil saber cuándo empezó
6. **Seguridad**: Rollback rápido si hay un cambio malintencionado

---

## Propuesta de Implementación

### Fase 1 (Semana 1):
- [ ] Crear modelo `Ruleset` en MongoDB
- [ ] Endpoint `POST /rules/publish-ruleset`
- [ ] Endpoint `PUT /rules/activate-ruleset/{version}`

### Fase 2 (Semana 2):
- [ ] Endpoint `GET /rules/history/{providerId}`
- [ ] Migrar reglas existentes a v1 de cada provider
- [ ] Tests de integración

### Fase 3 (Semana 3):
- [ ] Dashboard para visualizar versiones
- [ ] Validación anti-conflicto en publish
- [ ] Documentación

---

## Preguntas Anticipadas

**P: ¿Y si un provider tiene 1000 reglas y quiere cambiar solo una?**  
R: El provider descarga la v actual, modifica la regla, y publica como nueva versión. El sistema valida que sea consistente.

**P: ¿Se pierden las versiones viejas?**  
R: No. Están en `history`. Pueden ser reactivadas en cualquier momento.

**P: ¿Cuánta storage ocupa cada ruleset?**  
R: Minimal. Un ruleset con 100 reglas ~50KB. Historizar 10 versiones = ~500KB por provider.

**P: ¿Cómo manejamos validación de conflictos?**  
R: Al publicar, validamos:
- No hay 2 reglas ALLOW y DENY para el mismo (invoker, api)
- Las más específicas tienen prioridad
- El "default" es claro

---

## Conclusión

**Rulesets** = Versionado inteligente de reglas de visibilidad

**Beneficio Principal:** Un provider controla **todas sus reglas juntas** en versiones limpias, sin conflictos, con rollback rápido.

**Para CAPIF:** Escalable, auditable, confiable.
+222 −0
Changes for services/helper/helper_service/services/visibility_control/RULESETS_VISUAL_GUIDE.md: 222 added lines, 0 removed lines.
Original line number Diff line number Diff line
# Rulesets - Visual Guide for Presentation

## Slide 1: El Problema Actual

```
SIN RULESETS:

Provider "API-X"
│
├─ Regla 1: invoker-A → ALLOW       ← Creada hace 2 meses
├─ Regla 2: invoker-B → DENY        ← Creada hace 1 mes
├─ Regla 3: invoker-A → DENY        ← Creada ayer (CONFLICTO!)
├─ Regla 4: invoker-C → ALLOW       ← Creada hace 1 semana
└─ Regla 5: invoker-B → ALLOW       ← Creada esta mañana (CONFLICTO!)

❓ ¿Cuál es el estado actual?
❌ invoker-A: ¿ALLOW o DENY?
❌ invoker-B: ¿DENY o ALLOW?
❌ ¿Cómo revertir a hace 2 semanas?
```

## Slide 2: La Solución - Rulesets

```
CON RULESETS:

Provider "API-X"
│
├─ Ruleset v1 [DEPRECATED]
│  ├─ Regla: invoker-A → ALLOW
│  ├─ Regla: invoker-B → DENY
│  └─ Regla: invoker-C → ALLOW
│
├─ Ruleset v2 [DEPRECATED]
│  ├─ Regla: invoker-A → ALLOW
│  ├─ Regla: invoker-B → ALLOW        ← Solo cambió esto
│  └─ Regla: invoker-C → ALLOW
│
└─ Ruleset v3 [ACTIVE] ← EN USO
   ├─ Regla: invoker-A → DENY         ← Y esto
   ├─ Regla: invoker-B → ALLOW
   └─ Regla: invoker-C → ALLOW

✅ Estado claro: solo v3 está ACTIVE
✅ Revertir: PUT /activate-ruleset/v2
✅ Auditoría: cuándo cambió cada versión
```

## Slide 3: Estado Actual = Claro

```
INVOKER VE (con Ruleset v3 ACTIVE):
│
├─ API-X: ✅ DENY (invoker-A)
├─ API-Y: ✅ ALLOW (invoker-B, no está en ruleset = default ALLOW)
└─ API-Z: ✅ ALLOW (invoker-C)

NO HAY AMBIGÜEDAD
```

## Slide 4: Historial Completo

```
GET /rules/history/provider-api-x

[
  ✅ v3  | ACTIVE      | 2026-05-21 10:00 | Hoy
  ⏸️ v2  | DEPRECATED  | 2026-05-20 14:30 | Ayer
  ⏸️ v1  | DEPRECATED  | 2026-05-19 09:00 | Anteayer
]

AUDITORÍA COMPLETA:
- Quién cambió: El provider
- Cuándo: Timestamps precisos
- Qué cambió: Diferencia entre versiones visible
- Rollback: Cambiar a v2 si algo falla
```

## Slide 5: Caso de Uso - E-commerce

```
INICIO (v1):
┌─────────────────────────────────┐
│ Payment API                     │
├─────────────────────────────────┤
│ • Premium Partners → ALLOW      │
│ • Otros            → DENY       │
└─────────────────────────────────┘
        ↓
    (3 meses)
        ↓
EXPANSIÓN (v2):
┌─────────────────────────────────┐
│ Payment API                     │
├─────────────────────────────────┤
│ • Premium Partners → ALLOW      │
│ • Startup Program  → ALLOW (T)  │ ← Nuevo!
│ • Otros            → DENY       │
└─────────────────────────────────┘
        ↓
    (1 mes)
        ↓
AJUSTE (v3):
┌─────────────────────────────────┐
│ Payment API                     │
├─────────────────────────────────┤
│ • Premium Partners → ALLOW      │
│ • Startup Program  → DENY (T✗)  │ ← Trial terminado
│ • Otros            → DENY       │
└─────────────────────────────────┘

VENTAJA: Startup Program pregunta "¿Cuándo me quitaron acceso?"
RESPUESTA: v2 a v3. Claro. Auditable.
```

## Slide 6: API Endpoints (Simplificado)

```
1️⃣  CREAR NUEVA VERSIÓN
    POST /rules/publish-ruleset
    Body: { rules: [...] }
    → Crea v3, depreca v2, activa v3
    ✅ Todas las reglas juntas (sin conflictos)

2️⃣  CAMBIAR A VERSIÓN ANTERIOR
    PUT /rules/activate-ruleset/v2
    → Activa v2, depreca v3
    ✅ Rollback instantáneo

3️⃣  VER HISTORIAL
    GET /rules/history/provider-id
    → Muestra todas las versiones
    ✅ Auditoría completa
```

## Slide 7: Comparación Visual

```
ANTES (Sin Rulesets):
┌──────────────────────────────────────┐
│ ❌ Reglas sueltas                    │
│ ❌ Conflictos posibles               │
│ ❌ No hay rollback                   │
│ ❌ Auditoría confusa                 │
│ ❌ Estado actual ambiguo             │
└──────────────────────────────────────┘

DESPUÉS (Con Rulesets):
┌──────────────────────────────────────┐
│ ✅ Versiones ordenadas               │
│ ✅ Sin conflictos (una v activa)     │
│ ✅ Rollback: cambiar versión         │
│ ✅ Historial completo                │
│ ✅ Estado actual claro               │
└──────────────────────────────────────┘
```

## Slide 8: Plan de Implementación

```
Fundación
┌─────────────────────────────────────┐
│ • Crear modelo Ruleset              │
│ • POST /publish-ruleset             │
│ • PUT /activate-ruleset/{version}   │
│ Resultado: Versiones funcionales    │
└─────────────────────────────────────┘
           ↓
Integración
┌─────────────────────────────────────┐
│ • GET /history                      │
│ • Migrar reglas existentes          │
│ • Tests e2e                         │
│ Resultado: Todo en producción       │
└─────────────────────────────────────┘
           ↓
Pulido
┌─────────────────────────────────────┐
│ • Validación anti-conflicto         │
│ • Dashboard de versiones            │
│ • Documentación                     │
│ Resultado: Listo para usuarios      │
└─────────────────────────────────────┘
```

## Slide 9: Preguntas & Respuestas (Cheat Sheet)

```
P: ¿Se pierden las versiones viejas?
R: No. v1, v2, v3... todas guardadas. Se puede activar cualquiera.

P: ¿Cuánto storage?
R: Mínimo. 100 reglas = ~50KB por versión.

P: ¿Y si cambio solo 1 regla?
R: Descargas v3, editas 1, publicas como v4.

P: ¿Quién puede cambiar versiones?
R: El provider que creó las reglas (misma autenticación que ahora).

P: ¿Validación de conflictos?
R: Al publicar, el sistema verifica que no haya contradicciones.

P: ¿Diferencia con Git?
R: Es parecido: cada Ruleset es un "commit", puedes hacer checkout.
```

## Slide 10: Conclusión

```
RULESETS = Control de versiones para reglas de visibilidad

BENEFICIOS:
  ✅ Escalable (infinitas reglas por versión)
  ✅ Confiable (sin conflictos)
  ✅ Auditable (historial completo)
  ✅ Reversible (rollback rápido)
  ✅ Simple (una versión = un estado)

```

---