Cómo aplicar filtros de permisos de Okta directamente en la búsqueda vectorial RAG interna
Incrustar documentos de la wiki corporativa para levantar un asistente de IA interno es algo que se puede terminar en medio día. El verdadero problema explota el lunes por la mañana de la semana siguiente. Ocurre en el momento en que un desarrollador becario le pregunta al chat de IA: "¿Cuáles son los criterios de cálculo para los bonos ejecutivos de este año?", y el sistema resume cuidadosamente y muestra los documentos confidenciales del equipo financiero.
Cualquier ingeniero de plataforma con entre 3 y 7 años de experiencia que construya bases de conocimiento corporativas intuye este problema. La mayoría de las arquitecturas RAG fragmentan los documentos y los convierten en vectores de incrustación, destruyendo por completo el esquema de permisos del documento original. Esto sucede porque las reglas de control de acceso ligadas a Okta o Azure AD desaparecen por completo dentro de la base de datos vectorial. Si este vacío de permisos no se bloquea a nivel de infraestructura en lugar de en el código de la aplicación, la base de conocimiento privada se convierte prácticamente en un canal de filtración de información interna.
Sincronizar las declaraciones de grupos de IdP en los metadatos de la base de datos vectorial
La discrepancia de permisos entre el sistema de autenticación corporativo y el almacenamiento vectorial debe resolverse con una tubería de sincronización de metadatos de ciclo regular, no con consultas en tiempo real. El enfoque de llamar a la API del IdP corporativo para preguntar por los permisos cada vez que entra una consulta aumenta la latencia de búsqueda en más de 200 milisegundos y llena rápidamente el límite de llamadas por segundo (Rate Limit) del IdP.
Se debe ejecutar un proceso por lotes usando Airflow o Celery para actualizar la lista de grupos propietarios de los documentos cada hora en el campo de matriz de metadatos del registro vectorial. Tomando a Qdrant como ejemplo, se coloca un campo allowed_groups en cada carga útil de fragmento (chunk payload), y los ID de grupo de Okta se introducen directamente en él.
json { "chunk_id": "doc_9281_chunk_04", "text": "Presupuesto de transición de infraestructura de servidores para el segundo semestre de 2026...", "allowed_groups": ["group_devops_lead", "group_finance_managers"] }
Cuando los permisos de los documentos cambian, se detecta el evento de cambio del documento original y solo se actualizan de forma independiente los metadatos de la base de datos vectorial. No es necesario volver a calcular todas las incrustaciones, por lo que no se generan costos de cálculo. Cuando un usuario lanza una pregunta, el reclamo (claim) groups extraído del JWT se inyecta obligatoriamente como parámetro de filtro de búsqueda. Si se coloca un sidecar de Open Policy Agent (OPA) frente a la base de datos vectorial, se puede rechazar inmediatamente con un HTTP 403 la solicitud misma cuando el filtro del grupo autorizado del usuario falte en la consulta enviada por el cliente. Según un informe de auditoría de permisos RAG publicado en 2024 por el grupo de investigación de seguridad de San Francisco Bishop Fox, el 78% de los incidentes de pruebas de penetración de LLM internos ocurrieron debido a la omisión de filtros de metadatos. Forzar los filtros en la puerta de enlace de la infraestructura permite ahorrar más de 8 horas de trabajo semanales dedicadas a revisiones manuales de permisos.
Configuración de una tubería de aprobación de conocimiento basada en CODEOWNERS
Si se permite que el asistente de IA resuma automáticamente los documentos internos o actualice el contexto, la cola de espera de aprobación se atasca rápidamente. Si las solicitudes de revisión de seguridad van a la bandeja de entrada de correo electrónico o a tickets del backlog, se tardan un promedio de 72 horas en confirmarse. Si se ignora este retraso, los ingenieros terminarán viendo cómo el asistente interno responde con especificaciones de API heredadas de hace varios meses.
La aprobación del conocimiento debe manejarse mediante PRs (Pull Requests) en un repositorio de Git, de la misma manera que el sistema de revisión de código interno. Se debe hacer que el agente de IA cree una rama en forma de archivo Markdown para generar un PR cuando proponga un nuevo cambio de conocimiento.
Lea el archivo CODEOWNERS en la raíz del repositorio para asignar automáticamente el equipo de ingeniería responsable de la ruta del documento modificado.
`
CODEOWNERS
/docs/architecture/payment/ @team-fintech-core
/docs/infrastructure/k8s/ @team-platform-infra
/docs/security/auth/ @team-infosec
`
El webhook del PR generado por el agente se conecta al canal exclusivo de Slack del equipo responsable, mostrando simultáneamente el diff antes y después del cambio junto con un botón de aprobación. Cuando un miembro del equipo presiona el botón de aprobación en Slack, la API de GitHub actúa fusionando la rama, y la tubería de despliegue opera inmediatamente para volver a incrustar solo ese fragmento de documento en la base de datos vectorial. Alinear el flujo de modificación de la base de conocimiento con el ciclo de desarrollo habitual permite reducir el tiempo de cuello de botella de aprobación a menos de 4 horas.
Filtrado de secretos y datos personales antes de la etapa de incrustación
Al recopilar documentos de infraestructura, a menudo se filtran por accidente claves de acceso de AWS o cadenas de conexión de bases de datos de ensayo que los ingenieros dejaron insertadas por error como ejemplos de configuración. Si esto se envía tal cual al modelo de incrustación, las credenciales corporativas quedan registradas en los registros de caché del proveedor de LLM SaaS externo y son vulnerables a ataques de inyección de prompts que roban el contexto de documentos aumentados por búsqueda. Según el análisis de filtración de datos en la nube de la firma de ciberseguridad Wiz en 2023, se encontraron cadenas de credenciales válidas en aproximadamente el 12% de los documentos internos dentro de entornos empresariales.
Es obligatorio colocar un middleware proxy de enmascaramiento basado en expresiones regulares de alta velocidad en la primera puerta de enlace de la tubería de incrustación. La estructura de pasar por un contenedor proxy basado en Rust antes de pasar el texto a tiktoken de Python o a los scripts de fragmentación es estable.
`python
import re
PATTERNS = {
"AWS_KEY": r"(?<![A-Z0-9])[A-Z0-9]{20}(?![A-Z0-9])",
"BEARER_TOKEN": r"Bearer\s+[a-zA-Z0-9_-.=]+",
"SLACK_TOKEN": r"xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24,32}",
"GENERIC_SECRET": r'(?i)(password|secret|api_key|access_token)\s*[:=]\s*["\x27]?([^"\x27\s]+)["\x27]?'
}
def scrub_sensitive_data(text: str) -> str:
cleaned = text
for name, pattern in PATTERNS.items():
cleaned = re.sub(pattern, f"[REDACTED_{name}]", cleaned)
return cleaned
`
Si este filtrado se acopla firmemente frente al modelo de incrustación, incluso si un ingeniero de infraestructura escribe por error un token de servidor de producción en la wiki original, solo la cadena [REDACTED_SECRET] ingresará a la base de datos vectorial y al contexto del modelo de lenguaje. Para bloquear las amenazas de filtración de credenciales a nivel de infraestructura, se debe mantener un estado en el que incluso un usuario con permisos de acceso deba acceder directamente al repositorio de GitHub original o a Vault para poder ver los secretos.