> ## Documentation Index
> Fetch the complete documentation index at: https://docs.befailproof.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Gestión de Tenants (organizaciones y miembros)

> Documentación de gestión de tenants de AgentEye (organizaciones y miembros).

Un único despliegue de AgentEye sirve a múltiples **organizaciones** (tenants) completamente aisladas, de modo que una sola instancia puede alojar equipos, unidades de negocio o clientes distintos sin exponer los datos de un tenant a otro. Cada fila de datos (eventos, evaluaciones, sesiones, paneles, consultas guardadas, alertas, claves API y miembros) pertenece exactamente a una organización. El aislamiento principal se aplica en el código de la aplicación: cada solicitud está limitada a su organización mediante predicados `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ón `default` integrada no necesita nada):

* **PostgreSQL 15+.** El esquema de membresía de organizaciones utiliza una clave foránea `ON DELETE SET NULL` con lista de columnas que requiere PostgreSQL 15+. Actualiza PostgreSQL antes de aprovisionar una segunda organización.
* **Un `ORG_CH_SECRET` robusto y estable.** La contraseña de ClickHouse de cada organización se deriva como `HMAC(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 create` **se niega a ejecutarse mientras `ORG_CH_SECRET` no esté configurado o se deje en el valor predeterminado de desarrollo integrado**. Establece tu propio valor primero (consulta [Despliegue → variables de entorno](/es/agenteye/deployment) y, en Kubernetes, el [§2.6 de la guía de Kubernetes](/es/agenteye/kubernetes-deployment#26-multi-tenant-org-isolation-key-optional)). 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:**

```bash theme={null}
kubectl -n agenteye exec deploy/server -- agenteye-orgctl <args>
```

**Docker Compose:**

```bash theme={null}
docker compose exec server agenteye-orgctl <args>
```

Los ejemplos a continuación muestran el `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 `delete`d. 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.)                                                                                                                                                                    |

Una persona puede ser miembro de más de una organización con permisos **distintos** en cada una, p. ej., administrador en una organización y de solo lectura en otra. Cada membresía se administra de forma independiente por organización: otorgar o cambiar los permisos de una persona en una organización no tiene ningún efecto sobre su membresía en ninguna otra.

### 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.

<img src="https://mintcdn.com/exosphere/RgxYS1UZshqb4m7m/agenteye/images/users.png?fit=max&auto=format&n=RgxYS1UZshqb4m7m&q=85&s=00099f45dd3d40bd7e31b337a678bfed" alt="La página de Usuarios: una tarjeta por usuario del panel con su correo electrónico, permisos concedidos y controles de edición/desactivación" width="2880" height="1800" data-path="agenteye/images/users.png" />

Para evitarlo, marca un miembro como **protegido**:

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl member add --org acme --email owner@acme.example --set admin --protected
```

Un miembro protegido **no puede ser eliminado ni degradado a través del panel**; esas acciones devuelven un error. Solo un operador puede modificarlo, y únicamente a través de esta CLI: ejecuta primero `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.                                          |

Parte de un conjunto con `--set`, luego ajusta con `--add` / `--remove` usando los tokens de permisos individuales listados en [Claves API](/es/agenteye/api-keys). Los propios tokens de permisos son idénticos a los utilizados para las claves API.

***

## Ejemplo práctico

Aprovisiona un nuevo tenant `acme`, 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):

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl org create --slug acme --name "Acme Corp"
```

**2. Añadir el primer miembro como administrador de la organización:**

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl member add --org acme --email alice@acme.example --set admin
```

Alice recibe un OTP la primera vez que inicia sesión en el panel. A partir de entonces trabaja íntegramente en la interfaz de usuario bajo el prefijo de URL de su organización (p. ej., `/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](/es/agenteye/api-keys).

**4. Ajustar un miembro posteriormente:**

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl member update --org acme --email alice@acme.example --add alerts:write

kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl member list --org acme
```

**5. Eliminación lógica de la organización** (revoca el acceso y elimina su usuario ClickHouse; los datos se conservan):

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl org delete --slug acme
```

**6. Purgar la organización** (irreversible; solo después de una eliminación lógica; nunca la organización `default`):

```bash theme={null}
kubectl -n agenteye exec deploy/server -- \
  agenteye-orgctl org purge --slug acme
```

En Docker Compose, reemplaza cada prefijo `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](/es/agenteye/api-keys).
* **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.

El operador, usando `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](/es/agenteye/deployment): `ORG_CH_SECRET` y el resto del entorno del servidor.
* [Despliegue en Kubernetes](/es/agenteye/kubernetes-deployment): el §2.6 crea el Secret `agenteye-org-ch-secret` antes de tu primera organización multi-tenant.
* [Claves API](/es/agenteye/api-keys): el modelo de clave por organización y los tokens de permisos usados por `--add` / `--remove`.
* [Resolución de problemas](/es/agenteye/troubleshooting): aprovisionamiento multi-tenant y problemas de aislamiento en ClickHouse.
