Ruff‑autofix puede desactivar silenciosamente RBAC en KubeIntellect
Un cambio de tipo que parece inofensivo en un linter convierte la verificación de roles en un no‑op, dejando a los comandos con privilegios de administrador.

KubeIntellect es un agente AI que ejecuta kubectl contra clusters en vivo y, para evitar abusos, coloca una comprobación de rol y un paso de aprobación humana en cada herramienta. Ambas dependencias se resuelven al inyectar la configuración RunnableConfig que el grafo entrega a la herramienta.
El código original declara la configuración así:
config: Annotated[RunnableConfig, InjectedToolArg] = None
El valor por defecto es None, pero la anotación no indica explícitamente | None. mypy marca una advertencia y el autor añade # type: ignore. Ruff, al analizar el archivo, sugiere convertirlo a RunnableConfig | None, una transformación que el linter clasifica como safe.
La trampa surge porque LangChain busca el argumento a inyectar inspeccionando las anotaciones de tipo. El algoritmo compara el tipo con la clase exacta RunnableConfig. Cuando la anotación contiene RunnableConfig | None o Optional[RunnableConfig], el objeto de tipo es una UnionType y no coincide con RunnableConfig. Como resultado, el parámetro no se selecciona, y la herramienta recibe config=None en todas las llamadas.
Sin la configuración, la lógica de autorización cae al valor por defecto:
user_role = "admin"
if config:
user_role = config.get("configurable", {}).get("user_role", "admin")
Con config siempre None, cada ejecución se ejecuta como admin. El control de acceso basado en roles (RBAC) se abre de forma inadvertida, mientras que la comprobación de permiso de API key sigue pasando las pruebas unitarias porque nunca se dispara.
El problema no es un error aislado: el mismo patrón aparece en cuatro verbos de lectura propios. En esos casos la autorización no se consulta, pero el mismo defecto de configuración puede propagarse a una herramienta crítica en un futuro.
La solución propuesta es reemplazar la simple corrección de tipo por un guardia de prueba que falle si la anotación cambia. El guardia inspecciona todas las firmas de parámetros Annotated[..., InjectedToolArg] y exige que el tipo sea exactamente RunnableConfig. Además, los tests dinámicos construyen herramientas con distintas formas de anotación y verifican que solo la forma correcta sea inyectada.
El repositorio completo y los tests están disponibles en GitHub: Repositorio en GitHub.
En resumen, cualquier refactor de tipos que se perciba como “limpieza” puede alterar la lógica de autorización en frameworks que dependen de la identidad de tipos para la inyección de dependencias. Los equipos deben incluir pruebas que detecten cambios inesperados en las anotaciones de tipo cuando se usan como contratos de ejecución.

