@kwirthmagnify/kwirth-docs-pinocchio 0.2.31 → 0.2.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/admin/01-setup.md +98 -98
- package/admin/02-ai-config.md +125 -125
- package/admin/03-tools.md +132 -131
- package/admin/05-rbac.md +89 -89
- package/admin/06-limits.md +113 -113
- package/index.md +42 -42
- package/package.json +3 -3
- package/user/00-how-it-works.md +88 -88
- package/user/02-ui-tour.md +96 -96
- package/user/05-findings.md +108 -108
package/admin/03-tools.md
CHANGED
|
@@ -1,131 +1,132 @@
|
|
|
1
|
-
# Tools y pasos del agente
|
|
2
|
-
|
|
3
|
-
Las **tools** son lo que separa a Pinocchio de un chat al que le pegas un YAML. Son funciones reales,
|
|
4
|
-
ejecutadas dentro del clúster, que el modelo puede invocar por su cuenta mientras razona. Esta página
|
|
5
|
-
explica el catálogo, cómo se controla el gasto y —lo más importante— **por qué `Auto` es peligroso**.
|
|
6
|
-
|
|
7
|
-
## Cómo funciona la ejecución con tools
|
|
8
|
-
|
|
9
|
-
Cuando un trigger se dispara, el backend construye una llamada al modelo con:
|
|
10
|
-
|
|
11
|
-
- el `system` y el `prompt`,
|
|
12
|
-
- el subconjunto de tools que la versión declara,
|
|
13
|
-
- un tope de pasos: `stopWhen(stepCountIs(steps))`.
|
|
14
|
-
|
|
15
|
-
El modelo decide si necesita datos. Si los necesita, llama a una tool; el backend la ejecuta, le devuelve el
|
|
16
|
-
resultado, y eso cuenta como **un paso**. El ciclo se repite hasta que el modelo responde o se agotan los
|
|
17
|
-
pasos. Cada paso es una llamada de pago, con todo el contexto acumulado en la entrada.
|
|
18
|
-
|
|
19
|
-
> Si `steps` es 0 o está vacío, el backend **no usa 0**: usa **15**. Es el error de configuración más caro
|
|
20
|
-
> que se puede cometer en este plugin.
|
|
21
|
-
|
|
22
|
-
Todas las llamadas y respuestas de tools se registran como trazas en el log del backend
|
|
23
|
-
(`[pinocchio] tool <nombre> ...`), así que se puede auditar qué consultó el modelo.
|
|
24
|
-
|
|
25
|
-
## El catálogo
|
|
26
|
-
|
|
27
|
-
El catálogo lo aporta `kwirth-common-ai` y es el mismo para todos los plugins de IA de
|
|
28
|
-
envía al front al arrancar, así que el selector siempre muestra lo que el backend soporta de verdad.
|
|
29
|
-
|
|
30
|
-

|
|
31
|
-
|
|
32
|
-
### Lectura — inventario y configuración
|
|
33
|
-
|
|
34
|
-
| Tool | Para qué |
|
|
35
|
-
|------|----------|
|
|
36
|
-
| `list_namespaces` | Namespaces con estado y etiquetas. |
|
|
37
|
-
| `get_cluster_data` | Nombre, sabor (AKS/EKS/GKE/k3s/k3d), vCPUs, memoria, nodos. |
|
|
38
|
-
| `get_node_data` | Configuración de los nodos (nombre, IP). |
|
|
39
|
-
| `get_workload_data` | Todos los workloads del clúster; filtrable por namespace. |
|
|
40
|
-
| `get_space_data` | Todo lo que hay en un namespace. |
|
|
41
|
-
| `list_services` / `get_service_yaml` | Services del clúster / manifiesto completo de uno. |
|
|
42
|
-
| `list_ingresses` / `get_ingress_yaml` | Ingresses / manifiesto completo de uno. |
|
|
43
|
-
| `get_pod_yaml` / `get_deployment_yaml` | Manifiesto completo de un Pod o Deployment. |
|
|
44
|
-
|
|
45
|
-
### Lectura — diagnóstico
|
|
46
|
-
|
|
47
|
-
| Tool | Para qué |
|
|
48
|
-
|------|----------|
|
|
49
|
-
| `describe_pod` | Equivalente a `kubectl describe pod`: motivo de espera/terminación, exitCode (OOMKilled, CrashLoop…), reinicios, probes. |
|
|
50
|
-
| `get_pod_logs` | Logs del contenedor. Con `previous:true`, los de la instancia que petó — la causa raíz de un CrashLoopBackOff. |
|
|
51
|
-
| `get_cluster_events` / `get_object_events` | Eventos de Kubernetes del clúster o de un objeto concreto. |
|
|
52
|
-
| `get_rollout_history` | Revisiones de un Deployment: qué imagen y qué env tenía cada una. Para ver **qué cambió** justo antes de romperse. |
|
|
53
|
-
| `get_configmap` / `get_secret` | Datos de un ConfigMap / claves de un Secret (**valores redactados**). Un cambio de valor no genera revisión de rollout: por eso hay que mirarlos aparte. |
|
|
54
|
-
| `get_workload_config_refs` | Qué ConfigMaps y Secrets consume un Deployment, con su fecha de última modificación. |
|
|
55
|
-
| `get_source_file` | Trae un fichero de un repo Git (GitHub/GitLab) en una ref, para seguir un stack trace hasta el fichero:línea culpable. |
|
|
56
|
-
| `
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
`
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
>
|
|
91
|
-
> el
|
|
92
|
-
>
|
|
93
|
-
>
|
|
94
|
-
>
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
| `Deployment` + `
|
|
114
|
-
| `
|
|
115
|
-
| `Pod` + `
|
|
116
|
-
| `Pod` +
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
tokens
|
|
1
|
+
# Tools y pasos del agente
|
|
2
|
+
|
|
3
|
+
Las **tools** son lo que separa a Pinocchio de un chat al que le pegas un YAML. Son funciones reales,
|
|
4
|
+
ejecutadas dentro del clúster, que el modelo puede invocar por su cuenta mientras razona. Esta página
|
|
5
|
+
explica el catálogo, cómo se controla el gasto y —lo más importante— **por qué `Auto` es peligroso**.
|
|
6
|
+
|
|
7
|
+
## Cómo funciona la ejecución con tools
|
|
8
|
+
|
|
9
|
+
Cuando un trigger se dispara, el backend construye una llamada al modelo con:
|
|
10
|
+
|
|
11
|
+
- el `system` y el `prompt`,
|
|
12
|
+
- el subconjunto de tools que la versión declara,
|
|
13
|
+
- un tope de pasos: `stopWhen(stepCountIs(steps))`.
|
|
14
|
+
|
|
15
|
+
El modelo decide si necesita datos. Si los necesita, llama a una tool; el backend la ejecuta, le devuelve el
|
|
16
|
+
resultado, y eso cuenta como **un paso**. El ciclo se repite hasta que el modelo responde o se agotan los
|
|
17
|
+
pasos. Cada paso es una llamada de pago, con todo el contexto acumulado en la entrada.
|
|
18
|
+
|
|
19
|
+
> Si `steps` es 0 o está vacío, el backend **no usa 0**: usa **15**. Es el error de configuración más caro
|
|
20
|
+
> que se puede cometer en este plugin.
|
|
21
|
+
|
|
22
|
+
Todas las llamadas y respuestas de tools se registran como trazas en el log del backend
|
|
23
|
+
(`[pinocchio] tool <nombre> ...`), así que se puede auditar qué consultó el modelo.
|
|
24
|
+
|
|
25
|
+
## El catálogo
|
|
26
|
+
|
|
27
|
+
El catálogo lo aporta `kwirth-common-ai` y es el mismo para todos los plugins de IA de Kwirth. El canal se lo
|
|
28
|
+
envía al front al arrancar, así que el selector siempre muestra lo que el backend soporta de verdad.
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
### Lectura — inventario y configuración
|
|
33
|
+
|
|
34
|
+
| Tool | Para qué |
|
|
35
|
+
|------|----------|
|
|
36
|
+
| `list_namespaces` | Namespaces con estado y etiquetas. |
|
|
37
|
+
| `get_cluster_data` | Nombre, sabor (AKS/EKS/GKE/k3s/k3d), vCPUs, memoria, nodos. |
|
|
38
|
+
| `get_node_data` | Configuración de los nodos (nombre, IP). |
|
|
39
|
+
| `get_workload_data` | Todos los workloads del clúster; filtrable por namespace. |
|
|
40
|
+
| `get_space_data` | Todo lo que hay en un namespace. |
|
|
41
|
+
| `list_services` / `get_service_yaml` | Services del clúster / manifiesto completo de uno. |
|
|
42
|
+
| `list_ingresses` / `get_ingress_yaml` | Ingresses / manifiesto completo de uno. |
|
|
43
|
+
| `get_pod_yaml` / `get_deployment_yaml` | Manifiesto completo de un Pod o Deployment. |
|
|
44
|
+
|
|
45
|
+
### Lectura — diagnóstico
|
|
46
|
+
|
|
47
|
+
| Tool | Para qué |
|
|
48
|
+
|------|----------|
|
|
49
|
+
| `describe_pod` | Equivalente a `kubectl describe pod`: motivo de espera/terminación, exitCode (OOMKilled, CrashLoop…), reinicios, probes. |
|
|
50
|
+
| `get_pod_logs` | Logs del contenedor. Con `previous:true`, los de la instancia que petó — la causa raíz de un CrashLoopBackOff. |
|
|
51
|
+
| `get_cluster_events` / `get_object_events` | Eventos de Kubernetes del clúster o de un objeto concreto. |
|
|
52
|
+
| `get_rollout_history` | Revisiones de un Deployment: qué imagen y qué env tenía cada una. Para ver **qué cambió** justo antes de romperse. |
|
|
53
|
+
| `get_configmap` / `get_secret` | Datos de un ConfigMap / claves de un Secret (**valores redactados**). Un cambio de valor no genera revisión de rollout: por eso hay que mirarlos aparte. |
|
|
54
|
+
| `get_workload_config_refs` | Qué ConfigMaps y Secrets consume un Deployment, con su fecha de última modificación. |
|
|
55
|
+
| `get_source_file` | Trae un fichero de un repo Git (GitHub/GitLab) en una ref, para seguir un stack trace hasta el fichero:línea culpable. |
|
|
56
|
+
| `compare_revisions` | Qué entró entre dos revisiones de un repo Git: commits y ficheros tocados. Para explicar una regresión que llegó con un deploy — el diff solo si se pide, y avisa cuando el rango es tan ancho que ha tenido que recortar. |
|
|
57
|
+
| `get_certificate_info` | Detalles del certificado TLS de un host: emisor, validez, SANs, huella. |
|
|
58
|
+
|
|
59
|
+
### Lectura — uso de recursos
|
|
60
|
+
|
|
61
|
+
`get_cluster_usage`, `get_node_usage`, `get_deployment_usage` y sus versiones históricas
|
|
62
|
+
`get_prev_cluster_usage`, `get_prev_node_usage`, `get_prev_deployment_usage`, `get_prev_space_data`.
|
|
63
|
+
|
|
64
|
+
Estas tools se alimentan del **buffer de métricas** del canal: las últimas 100 lecturas del provider
|
|
65
|
+
`metrics`. Si acabas de abrir el canal, el histórico estará casi vacío.
|
|
66
|
+
|
|
67
|
+
### Escritura — ⚠️ modifican el clúster
|
|
68
|
+
|
|
69
|
+
| Tool | Qué hace |
|
|
70
|
+
|------|----------|
|
|
71
|
+
| `add_replica` / `remove_replica` | Escala un Deployment arriba o abajo (mínimo 1 réplica). |
|
|
72
|
+
| `restart_deployment` | Rollout-restart de un Deployment. |
|
|
73
|
+
| `delete_pod` | Borra un pod; su controlador lo recrea. |
|
|
74
|
+
| `add_node` / `remove_node` | Añade o quita un nodo del clúster (en k3d, vía `k3d node create/delete`). |
|
|
75
|
+
| `start_node` / `stop_node` | Arranca o para un nodo. |
|
|
76
|
+
|
|
77
|
+
### De prueba
|
|
78
|
+
|
|
79
|
+
`times_two` y `father_of` son tools de juguete para verificar que la cadena de tool-calling funciona. No las
|
|
80
|
+
pongas en un trigger real.
|
|
81
|
+
|
|
82
|
+
## El interruptor `Auto`: léelo antes de usarlo
|
|
83
|
+
|
|
84
|
+
El selector de tools tiene un interruptor **Auto**. Lo que hace **depende de dónde estés**, y la diferencia
|
|
85
|
+
es importante:
|
|
86
|
+
|
|
87
|
+
**En un trigger real** — `Auto` entrega al modelo el **catálogo completo, sin filtrar**. Sin selección previa
|
|
88
|
+
y, sobre todo, **sin quitar las tools de escritura**.
|
|
89
|
+
|
|
90
|
+
> ⚠️ **Un trigger con `Auto` activado puede escalar, reiniciar, borrar pods y quitar nodos.** El plugin no
|
|
91
|
+
> aplica ningún filtro de sólo-lectura. Si el modelo decide que la forma de arreglar lo que ve es reiniciar
|
|
92
|
+
> el Deployment, tiene la herramienta para hacerlo.
|
|
93
|
+
>
|
|
94
|
+
> **Recomendación: no uses `Auto` en triggers.** Marca a mano las tools de lectura que el análisis necesite.
|
|
95
|
+
> Es más trabajo una vez y te ahorra una sorpresa en producción.
|
|
96
|
+
|
|
97
|
+
**En el Playground** — `Auto` hace una **llamada previa** al modelo pidiéndole que elija qué tools necesita, y
|
|
98
|
+
sólo le pasa esas. Es más barato en tokens de contexto pero más caro en llamadas, y te muestra la elección
|
|
99
|
+
como `[Auto tools] selected: ...`. Sigue sin filtrar las de escritura.
|
|
100
|
+
|
|
101
|
+
## El coste, con números
|
|
102
|
+
|
|
103
|
+
El gasto de un trigger es, aproximadamente:
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
coste ≈ (nº de disparos) × (nº de pasos) × (tokens de contexto acumulados)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Los tres factores se multiplican, y el primero es el que se dispara sin que te des cuenta:
|
|
110
|
+
|
|
111
|
+
| Trigger | Disparos al día en un clúster mediano |
|
|
112
|
+
|---------|----------------------------------------|
|
|
113
|
+
| `Deployment` + `ADDED` | decenas |
|
|
114
|
+
| `Deployment` + `MODIFIED` | cientos |
|
|
115
|
+
| `Pod` + `ADDED` | cientos |
|
|
116
|
+
| `Pod` + `MODIFIED` | **miles** — cada cambio de estado, cada probe, cada reinicio |
|
|
117
|
+
| `Pod` + *Any* | lo anterior, por tres |
|
|
118
|
+
|
|
119
|
+
Reglas prácticas:
|
|
120
|
+
|
|
121
|
+
1. **Empieza siempre por `ADDED`**, nunca por *Any*. Analiza lo que nace, no lo que respira.
|
|
122
|
+
2. **Evita `Pod`.** Analiza el `Deployment`, que es donde está la decisión de diseño; los pods sólo la
|
|
123
|
+
ejecutan, y hay muchos más.
|
|
124
|
+
3. **`steps` bajo para empezar** (3–5). Súbelo sólo si el campo `not_visible` de los análisis te dice que al
|
|
125
|
+
modelo le faltó información.
|
|
126
|
+
4. **Mira los tokens** en la línea de cabecera de cada análisis (`IN:`/`OUT:`). Es la medida real, no una
|
|
127
|
+
estimación.
|
|
128
|
+
5. **Prueba en el Playground.** Un prompt mal calibrado que hace 15 llamadas a tools se detecta gratis ahí,
|
|
129
|
+
no en producción.
|
|
130
|
+
|
|
131
|
+
Los campos `Input / Output cost per M tokens` del diálogo de LLM existen justo para que puedas traducir esos
|
|
132
|
+
tokens a dinero.
|
package/admin/05-rbac.md
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
# Permisos y acceso
|
|
2
|
-
|
|
3
|
-
## Los scopes del canal
|
|
4
|
-
|
|
5
|
-
Pinocchio declara al core sólo **dos** scopes válidos para su canal, en este orden de menor a mayor:
|
|
6
|
-
|
|
7
|
-
| Scope | Nivel | Significado |
|
|
8
|
-
|-------|-------|-------------|
|
|
9
|
-
| `none` | 1 | Nivel mínimo. Suficiente para abrir el canal. |
|
|
10
|
-
| `cluster` | 2 | Nivel de administración. Cubre todo lo anterior. |
|
|
11
|
-
|
|
12
|
-
Una clave de acceso concede permiso sobre el canal `pinocchio` con uno de esos dos valores. El canal pide
|
|
13
|
-
como scope de instancia `NONE`, así que **cualquiera de los dos basta para abrirlo y usarlo entero**.
|
|
14
|
-
|
|
15
|
-
Cualquier otro literal en el scope (`view`, `restart`, `filter`, …) es **inválido para este canal**: el core
|
|
16
|
-
lo rechaza con un aviso muy visible en el log de autorización:
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
***************** Inexistent scope 'view' on channel 'pinocchio' *****************
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
Si un usuario no consigue abrir el canal, ese log es el primer sitio donde mirar.
|
|
23
|
-
|
|
24
|
-
## Lo que hay que entender antes de repartir claves
|
|
25
|
-
|
|
26
|
-
Pinocchio **no tiene permisos granulares**. No hay un scope para "sólo leer los findings" y otro para
|
|
27
|
-
"editar triggers". Quien puede abrir el canal, puede hacerlo todo. Esto es lo que "todo" incluye:
|
|
28
|
-
|
|
29
|
-
**1. Leer los análisis de todos los demás.** Los análisis se guardan en el canal, no por usuario. Cualquiera
|
|
30
|
-
que abra el canal recibe de golpe los últimos 50, con los manifiestos y los findings que contengan. Si un
|
|
31
|
-
trigger analiza recursos de un namespace sensible, esos datos son visibles para todos los que tengan acceso
|
|
32
|
-
al canal.
|
|
33
|
-
|
|
34
|
-
**2. Borrar los análisis de todos los demás.** El botón **Clear back** vacía la memoria del canal para todo
|
|
35
|
-
el mundo, sin confirmación adicional más allá del propio diálogo.
|
|
36
|
-
|
|
37
|
-
**3. Editar la configuración de IA compartida.** Los diálogos *Provider* y *LLM* escriben en el almacén
|
|
38
|
-
**común** de
|
|
39
|
-
usan los demás plugins de IA del clúster.
|
|
40
|
-
|
|
41
|
-
**4. Ver y cambiar las API keys.** El diálogo de provider tiene un botón de ojo que revela la clave, y un
|
|
42
|
-
botón **Export** que descarga todos los providers **con las claves en claro**.
|
|
43
|
-
|
|
44
|
-
**5. Crear triggers que ejecutan acciones de escritura.** Ver el apartado siguiente.
|
|
45
|
-
|
|
46
|
-
> **Conclusión operativa: trata el acceso al canal `pinocchio` como un permiso de administración.** No es un
|
|
47
|
-
> visor de logs. Concédelo al equipo que gobierna la plataforma, no a los usuarios de aplicación.
|
|
48
|
-
|
|
49
|
-
## Las tools de escritura y el service account del backend
|
|
50
|
-
|
|
51
|
-
Este es el punto que más atención merece.
|
|
52
|
-
|
|
53
|
-
El catálogo de tools incluye acciones que **modifican el clúster**: `add_replica`, `remove_replica`,
|
|
54
|
-
`restart_deployment`, `delete_pod`, `add_node`, `remove_node`, `start_node`, `stop_node`. Pinocchio **no
|
|
55
|
-
filtra las tools de escritura**: si una versión de trigger las tiene marcadas —o tiene el interruptor
|
|
56
|
-
**`Auto`** activado, que entrega el catálogo entero— el modelo puede invocarlas.
|
|
57
|
-
|
|
58
|
-
Y cuando las invoca, se ejecutan con el **service account del backend de
|
|
59
|
-
usuario que configuró el trigger. Un usuario con el scope mínimo puede, a través de un trigger, provocar
|
|
60
|
-
acciones que su propio nivel de acceso no le permitiría hacer directamente.
|
|
61
|
-
|
|
62
|
-
Tres medidas concretas:
|
|
63
|
-
|
|
64
|
-
1. **Prohíbe `Auto` en triggers** como norma de equipo. Que las tools se marquen a mano, una a una.
|
|
65
|
-
2. **Revisa los triggers como revisarías código.** El diálogo *Import / Export* permite volcarlos a JSON:
|
|
66
|
-
ese fichero se puede versionar y revisar en un pull request.
|
|
67
|
-
3. **Ajusta el RBAC del service account del backend** a lo que de verdad necesites. Si en tu instalación
|
|
68
|
-
Pinocchio sólo tiene que auditar, el backend no debería poder escalar deployments ni borrar pods. Ésa es
|
|
69
|
-
la barrera que de verdad detiene el problema, y está fuera del plugin: es el RBAC de
|
|
70
|
-
|
|
71
|
-
## Auditoría
|
|
72
|
-
|
|
73
|
-
Todas las invocaciones de tools quedan como trazas en el log del backend:
|
|
74
|
-
|
|
75
|
-
```
|
|
76
|
-
[pinocchio] tool get_pod_logs {"namespace":"prod","name":"api-gateway-7d9f"}
|
|
77
|
-
[pinocchio] tool get_pod_logs response: {...}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Además, cada análisis muestra en su cabecera qué LLM lo produjo y cuántos tokens costó, y la traza completa
|
|
81
|
-
de la conversación con las tools es visible en las pestañas **IN**/**OUT** del Playground cuando se ejecuta
|
|
82
|
-
desde allí.
|
|
83
|
-
|
|
84
|
-
## Superficie de red
|
|
85
|
-
|
|
86
|
-
El Playground dispara sus eventos con un `POST {clusterUrl}/provider/business`, autenticado con la clave de
|
|
87
|
-
acceso del usuario. Es el mismo endpoint por el que los sistemas externos inyectan eventos de negocio: quien
|
|
88
|
-
tenga una clave válida para ese provider puede inyectar eventos y, por tanto, disparar los triggers
|
|
89
|
-
`business`. Ténlo en cuenta al repartir claves con acceso al provider `business`.
|
|
1
|
+
# Permisos y acceso
|
|
2
|
+
|
|
3
|
+
## Los scopes del canal
|
|
4
|
+
|
|
5
|
+
Pinocchio declara al core sólo **dos** scopes válidos para su canal, en este orden de menor a mayor:
|
|
6
|
+
|
|
7
|
+
| Scope | Nivel | Significado |
|
|
8
|
+
|-------|-------|-------------|
|
|
9
|
+
| `none` | 1 | Nivel mínimo. Suficiente para abrir el canal. |
|
|
10
|
+
| `cluster` | 2 | Nivel de administración. Cubre todo lo anterior. |
|
|
11
|
+
|
|
12
|
+
Una clave de acceso concede permiso sobre el canal `pinocchio` con uno de esos dos valores. El canal pide
|
|
13
|
+
como scope de instancia `NONE`, así que **cualquiera de los dos basta para abrirlo y usarlo entero**.
|
|
14
|
+
|
|
15
|
+
Cualquier otro literal en el scope (`view`, `restart`, `filter`, …) es **inválido para este canal**: el core
|
|
16
|
+
lo rechaza con un aviso muy visible en el log de autorización:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
***************** Inexistent scope 'view' on channel 'pinocchio' *****************
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Si un usuario no consigue abrir el canal, ese log es el primer sitio donde mirar.
|
|
23
|
+
|
|
24
|
+
## Lo que hay que entender antes de repartir claves
|
|
25
|
+
|
|
26
|
+
Pinocchio **no tiene permisos granulares**. No hay un scope para "sólo leer los findings" y otro para
|
|
27
|
+
"editar triggers". Quien puede abrir el canal, puede hacerlo todo. Esto es lo que "todo" incluye:
|
|
28
|
+
|
|
29
|
+
**1. Leer los análisis de todos los demás.** Los análisis se guardan en el canal, no por usuario. Cualquiera
|
|
30
|
+
que abra el canal recibe de golpe los últimos 50, con los manifiestos y los findings que contengan. Si un
|
|
31
|
+
trigger analiza recursos de un namespace sensible, esos datos son visibles para todos los que tengan acceso
|
|
32
|
+
al canal.
|
|
33
|
+
|
|
34
|
+
**2. Borrar los análisis de todos los demás.** El botón **Clear back** vacía la memoria del canal para todo
|
|
35
|
+
el mundo, sin confirmación adicional más allá del propio diálogo.
|
|
36
|
+
|
|
37
|
+
**3. Editar la configuración de IA compartida.** Los diálogos *Provider* y *LLM* escriben en el almacén
|
|
38
|
+
**común** de Kwirth. Un usuario de Pinocchio puede añadir, modificar o **borrar** los providers y modelos que
|
|
39
|
+
usan los demás plugins de IA del clúster.
|
|
40
|
+
|
|
41
|
+
**4. Ver y cambiar las API keys.** El diálogo de provider tiene un botón de ojo que revela la clave, y un
|
|
42
|
+
botón **Export** que descarga todos los providers **con las claves en claro**.
|
|
43
|
+
|
|
44
|
+
**5. Crear triggers que ejecutan acciones de escritura.** Ver el apartado siguiente.
|
|
45
|
+
|
|
46
|
+
> **Conclusión operativa: trata el acceso al canal `pinocchio` como un permiso de administración.** No es un
|
|
47
|
+
> visor de logs. Concédelo al equipo que gobierna la plataforma, no a los usuarios de aplicación.
|
|
48
|
+
|
|
49
|
+
## Las tools de escritura y el service account del backend
|
|
50
|
+
|
|
51
|
+
Este es el punto que más atención merece.
|
|
52
|
+
|
|
53
|
+
El catálogo de tools incluye acciones que **modifican el clúster**: `add_replica`, `remove_replica`,
|
|
54
|
+
`restart_deployment`, `delete_pod`, `add_node`, `remove_node`, `start_node`, `stop_node`. Pinocchio **no
|
|
55
|
+
filtra las tools de escritura**: si una versión de trigger las tiene marcadas —o tiene el interruptor
|
|
56
|
+
**`Auto`** activado, que entrega el catálogo entero— el modelo puede invocarlas.
|
|
57
|
+
|
|
58
|
+
Y cuando las invoca, se ejecutan con el **service account del backend de Kwirth**, no con los permisos del
|
|
59
|
+
usuario que configuró el trigger. Un usuario con el scope mínimo puede, a través de un trigger, provocar
|
|
60
|
+
acciones que su propio nivel de acceso no le permitiría hacer directamente.
|
|
61
|
+
|
|
62
|
+
Tres medidas concretas:
|
|
63
|
+
|
|
64
|
+
1. **Prohíbe `Auto` en triggers** como norma de equipo. Que las tools se marquen a mano, una a una.
|
|
65
|
+
2. **Revisa los triggers como revisarías código.** El diálogo *Import / Export* permite volcarlos a JSON:
|
|
66
|
+
ese fichero se puede versionar y revisar en un pull request.
|
|
67
|
+
3. **Ajusta el RBAC del service account del backend** a lo que de verdad necesites. Si en tu instalación
|
|
68
|
+
Pinocchio sólo tiene que auditar, el backend no debería poder escalar deployments ni borrar pods. Ésa es
|
|
69
|
+
la barrera que de verdad detiene el problema, y está fuera del plugin: es el RBAC de Kwirth en el clúster.
|
|
70
|
+
|
|
71
|
+
## Auditoría
|
|
72
|
+
|
|
73
|
+
Todas las invocaciones de tools quedan como trazas en el log del backend:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
[pinocchio] tool get_pod_logs {"namespace":"prod","name":"api-gateway-7d9f"}
|
|
77
|
+
[pinocchio] tool get_pod_logs response: {...}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Además, cada análisis muestra en su cabecera qué LLM lo produjo y cuántos tokens costó, y la traza completa
|
|
81
|
+
de la conversación con las tools es visible en las pestañas **IN**/**OUT** del Playground cuando se ejecuta
|
|
82
|
+
desde allí.
|
|
83
|
+
|
|
84
|
+
## Superficie de red
|
|
85
|
+
|
|
86
|
+
El Playground dispara sus eventos con un `POST {clusterUrl}/provider/business`, autenticado con la clave de
|
|
87
|
+
acceso del usuario. Es el mismo endpoint por el que los sistemas externos inyectan eventos de negocio: quien
|
|
88
|
+
tenga una clave válida para ese provider puede inyectar eventos y, por tanto, disparar los triggers
|
|
89
|
+
`business`. Ténlo en cuenta al repartir claves con acceso al provider `business`.
|