org_id explícitos. En ClickHouse — donde viven los eventos y evaluaciones de alto volumen — esto está respaldado por una aplicación sólida a nivel de motor: cada organización obtiene un usuario ClickHouse de solo lectura dedicado con una política de filas por organización, de modo que incluso el SQL analítico no confiable nunca puede leer las filas de otro tenant. En PostgreSQL, la seguridad a nivel de fila añade defensa en profundidad en la ruta de consulta de solo lectura (/queries/run), restringiendo lo que esa ruta puede ver aunque llegara a faltar un filtro a nivel de aplicación; la propia conexión de escritura del servidor se ejecuta como propietario de la tabla y por tanto opera mediante el mismo ámbito org_id a nivel de aplicación.
El ciclo de vida del tenant está controlado por el operador, mientras que todo lo que los miembros hacen en el día a día permanece como autoservicio en el panel. Las organizaciones y sus membresías se crean y gestionan con la CLI agenteye-orgctl, que se incluye dentro de la imagen del servidor y se ejecuta dentro del pod del servidor existente. La creación y eliminación de tenants se mantienen deliberadamente fuera del panel y la API HTTP: no existe una API HTTP ni un botón en el panel para el ciclo de vida de los tenants, por lo que está restringido al acceso shell del clúster/pod en lugar de la superficie de la aplicación.
Dentro de una organización, los miembros trabajan íntegramente en el panel y la API: inician sesión, cambian entre las organizaciones a las que pertenecen, gestionan sus propias claves API, crean paneles y consultas guardadas, y configuran alertas para su organización. La división es clara: los operadores aprovisionan y desactivan tenants y sus miembros a través de la CLI; los miembros gestionan todo dentro de un tenant a través de la interfaz de usuario.
Los despliegues de un solo tenant no necesitan nada de esto. Una instalación de un solo tenant funciona sin ninguna acción del operador. Todos los datos, usuarios y claves viven en una organización default integrada que se aprovisiona automáticamente. Solo necesitas esta guía cuando decides añadir una segunda organización.
Requisitos previos
Antes de crear tu segunda organización (la organizacióndefault integrada no necesita nada):
- PostgreSQL 15+. El esquema de membresía de organizaciones utiliza una clave foránea
ON DELETE SET NULLcon lista de columnas que requiere PostgreSQL 15+. Actualiza PostgreSQL antes de aprovisionar una segunda organización. - Un
ORG_CH_SECRETrobusto y estable. La contraseña de ClickHouse de cada organización se deriva comoHMAC(ORG_CH_SECRET, org_id), por lo que el valor predeterminado de desarrollo integrado, de conocimiento público, produciría credenciales por organización derivables públicamente.agenteye-orgctl org createse niega a ejecutarse mientrasORG_CH_SECRETno esté configurado o se deje en el valor predeterminado de desarrollo integrado. Establece tu propio valor primero (consulta Despliegue → variables de entorno y, en Kubernetes, el §2.6 de la guía de Kubernetes). Mantenlo idéntico en todas las réplicas del servidor y no lo rotes de forma descuidada; rotarlo deja huérfano el usuario ClickHouse de cada organización hasta que el próximo arranque los vuelva a aprovisionar.
Ejecutar la CLI
agenteye-orgctl se incluye en la misma imagen que el servidor (junto a agenteye-server). No despliegas un pod, Job o Deployment separado para ello; lo ejecutas dentro del pod del servidor que ya está en marcha, de modo que lee el mismo DATABASE_URL, CLICKHOUSE_URL y ORG_CH_SECRET que usa el servidor.
Kubernetes:
agenteye-orgctl <args> escueto por brevedad; antepón a cada uno la línea correspondiente según tu despliegue.
Referencia de comandos
Organizaciones
| Comando | Qué hace |
|---|---|
org create --slug <slug> --name <name> | Crea una nueva organización. Se niega a ejecutarse mientras ORG_CH_SECRET no esté configurado o se deje en el valor predeterminado de desarrollo integrado (establece el tuyo primero, consulta los Requisitos previos). Aprovisiona el usuario ClickHouse de solo lectura de la organización y la política de filas. |
org list | Lista todas las organizaciones (slug, nombre y estado del ciclo de vida). |
org rename --slug <slug> --name <new name> | Cambia el nombre para mostrar de una organización. El slug (usado en URLs y claves) no cambia. |
org delete --slug <slug> | Eliminación lógica de la organización y borrado de su usuario ClickHouse. Los datos se conservan. Esto revoca el acceso y libera la credencial ClickHouse por organización, pero no borra los eventos. Reversible por los operadores; primer paso seguro antes de un purgado. |
org purge --slug <slug> | Borrado de datos irreversible. La organización ya debe estar deleted. Nunca permitido en la organización default integrada. Úsalo solo cuando estés seguro de que los datos del tenant deben destruirse. |
Miembros
| Comando | Qué hace |
|---|---|
member add --org <slug> --email <email> [--set <permission-set>] [--add perm1,perm2] [--remove perm3] [--protected] | Añade un miembro a una organización. Opcionalmente parte de un conjunto de permisos integrado, luego añade/elimina permisos individuales. --protected fija al miembro para que el panel no pueda eliminarlo ni degradarlo (ver más abajo). El nuevo miembro recibe un OTP en su primer inicio de sesión en el panel. |
member list --org <slug> | Lista los miembros de la organización. Las columnas de salida son EMAIL, SET (el conjunto integrado del que partió el miembro, o -), PROT (si el miembro está protegido) y PERMISSIONS (sus permisos efectivos). Un correo electrónico que aparece con un * al final es un administrador de instancia; tiene acceso a todas las organizaciones. |
member update --org <slug> --email <email> [--set ...] [--add ...] [--remove ...] [--protected | --unprotect] | Cambia los permisos de un miembro y/o su indicador de protección. --set reemplaza desde un conjunto integrado; --add / --remove ajustan permisos individuales; --protected / --unprotect activan o desactivan la protección. Pasar solo --protected/--unprotect (sin indicadores de concesión) cambia únicamente la protección y deja los permisos existentes intactos. |
member remove --org <slug> --email <email> | Elimina un miembro de la organización. Se niega si el miembro está protegido; primero aplica --unprotect. (Una persona puede ser miembro de varias organizaciones; esto solo afecta a la organización indicada.) |
Miembros protegidos (un administrador de organización no eliminable)
La protección garantiza que una organización nunca pueda bloquearse accidentalmente a sí misma en la autogestión. Por defecto, los propios administradores de una organización pueden añadirse y eliminarse mutuamente a través de la página de usuarios de autoservicio del panel, por lo que podrían eliminar al último administrador y dejar la organización sin nadie que la gestione.
member update --org acme --email owner@acme.example --unprotect, luego elimina o degrada. Esto garantiza que cada organización conserve al menos un administrador que sus propios miembros no puedan bloquear, manteniendo el control del tenant exclusivamente en manos del operador. La protección es por organización; proteger a alguien en una organización no tiene ningún efecto sobre su membresía en otra.
Conjuntos de permisos integrados
--set acepta uno de tres conjuntos integrados, aplicados por organización:
| Conjunto | Destinado a |
|---|---|
admin | Acceso completo dentro de la organización, incluida la gestión de las claves API y usuarios de la organización. |
standard | Uso cotidiano: leer y ejecutar consultas, crear paneles, reconocer incidentes. |
read-only | Acceso de solo visualización a los datos y paneles de la organización. |
--set, luego ajusta con --add / --remove usando los tokens de permisos individuales listados en Claves API. Los propios tokens de permisos son idénticos a los utilizados para las claves API.
Ejemplo práctico
Aprovisiona un nuevo tenantacme, añade su primer administrador, permite que genere una clave y luego desactiva la organización.
1. Crear la organización (ORG_CH_SECRET ya debe estar configurado con un valor robusto y estable, no sin configurar ni con el valor predeterminado de desarrollo integrado):
/acme/sessions).
3. Generar una clave API por organización (en el panel):
El operador no genera claves de datos por organización desde la CLI. Alice (o cualquier miembro de la organización con keys:create) crea claves de colector/panel para la organización acme desde la página Keys del panel. Cada clave que crea se marca automáticamente con su organización y solo puede leer o escribir datos de acme. Consulta Claves API.
4. Ajustar un miembro posteriormente:
default):
kubectl -n agenteye exec deploy/server -- con docker compose exec server.
División de responsabilidades
Todo lo que un miembro de la organización necesita en el día a día es autoservicio en el panel y la API, limitado automáticamente a su organización actual:- Las claves API por organización son creadas y gestionadas por los miembros de la organización en el panel (o a través de la API de claves con una clave que lleve
keys:create). La CLI no genera claves de datos. Consulta Claves API. - El cambio de organización está integrado en el panel; los miembros cambian entre las organizaciones a las que pertenecen desde el selector de organizaciones, y las páginas con ámbito de organización viven bajo
/<org-slug>/…. - Los paneles, consultas guardadas, alertas y todo el uso de datos ocurren íntegramente en la interfaz de usuario y la API, limitados a la organización actual del miembro.
agenteye-orgctl, es responsable únicamente del ciclo de vida de la organización y los miembros: crear / renombrar / eliminar / purgar una organización, y añadir / listar / actualizar / eliminar un miembro.
Ver también
- Despliegue:
ORG_CH_SECRETy el resto del entorno del servidor. - Despliegue en Kubernetes: el §2.6 crea el Secret
agenteye-org-ch-secretantes de tu primera organización multi-tenant. - Claves API: el modelo de clave por organización y los tokens de permisos usados por
--add/--remove. - Resolución de problemas: aprovisionamiento multi-tenant y problemas de aislamiento en ClickHouse.

