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

# Eventos webhook de Seguridad e IAM

> Notificaciones en tiempo real de autenticación, miembros, roles y configuración de seguridad de Gu1 — para integraciones SIEM y monitoreo de seguridad.

## Descripción general

Los eventos webhook de seguridad notifican a su SIEM o herramientas de monitoreo cuando ocurren acciones de IAM en Gu1: ciclo de vida de miembros, cambios de roles, inicio/cierre de sesión, logins fallidos, acciones admin sobre contraseñas y ciertos parámetros de seguridad.

Configúrelos como cualquier otro webhook en **Configuración → Webhooks** y suscríbase solo a los eventos `security.*` que necesite.

## Forma del payload (todos los eventos de seguridad)

Cada webhook de seguridad usa el sobre estándar más un payload interno normalizado:

```json theme={null}
{
  "event": "security.auth.login_succeeded",
  "timestamp": "2026-06-18T12:00:00.000Z",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "payload": {
    "actionAt": "2026-06-18T12:00:00.000Z",
    "actor": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "email": "admin@example.com",
      "displayName": "Jane Admin"
    },
    "affectedUser": {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "email": "user@example.com",
      "displayName": "John User"
    },
    "description": "User logged in successfully",
    "changes": {
      "permissions": {
        "added": ["entities:write"],
        "removed": [],
        "current": ["entities:read", "entities:write"]
      }
    },
    "context": {
      "ipAddress": "203.0.113.10",
      "userAgent": "Mozilla/5.0 ...",
      "scope": "sandbox",
      "roleId": "uuid",
      "roleName": "Analyst"
    }
  }
}
```

| Campo          | Descripción                                                                                                             |
| -------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `actionAt`     | Fecha/hora de la acción (ISO 8601)                                                                                      |
| `actor`        | Usuario que realizó la acción (`id` = UUID en DB Gu1 cuando existe)                                                     |
| `affectedUser` | Usuario afectado (cuando aplica)                                                                                        |
| `description`  | Resumen legible                                                                                                         |
| `changes`      | Mapa de campos modificados. Para permisos de rol: `{ added, removed, current }`. Otros campos: `{ previous, current }`. |
| `context`      | IP, user agent, ámbito de settings, metadata de rol                                                                     |

## Eventos disponibles

### Miembros (`security.member.*`)

| Evento                                | Cuándo se dispara                                                                                |
| ------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `security.member.invited`             | Un admin invita a un nuevo miembro                                                               |
| `security.member.created`             | El miembro acepta la invitación / se crea en la org                                              |
| `security.member.removed`             | Miembro eliminado de la organización                                                             |
| `security.member.activated`           | Miembro habilitado / reactivado                                                                  |
| `security.member.deactivated`         | Miembro deshabilitado                                                                            |
| `security.member.profile_updated`     | Admin actualiza nombre (`firstName` / `lastName`)                                                |
| `security.member.password_reset`      | Admin resetea contraseña del miembro                                                             |
| `security.member.password_generated`  | Admin genera contraseña temporal                                                                 |
| `security.member.team_added`          | Miembro agregado a un equipo                                                                     |
| `security.member.team_removed`        | Miembro quitado de un equipo                                                                     |
| `security.member.team_role_changed`   | Cambia el rol del miembro dentro del equipo                                                      |
| `security.member.channel_granted`     | Se otorga acceso a un canal (org hija)                                                           |
| `security.member.channel_revoked`     | Se revoca acceso a un canal                                                                      |
| `security.member.environment_granted` | Se otorga acceso al ambiente production o sandbox                                                |
| `security.member.environment_revoked` | Se revoca acceso al ambiente production o sandbox                                                |
| `security.member.environment_changed` | Un admin cambia el acceso prod/sandbox de un miembro en un solo paso (`fromAccess` → `toAccess`) |

`context.teamType` (p. ej. `production`, `sandbox`) y `context.teamRole` aplican en eventos de equipo. Para acceso a entornos, `context.environment` es `"production"` o `"sandbox"`, con `context.environmentOrganizationId` y `context.environmentOrganizationName`. En `security.member.environment_changed`, use `context.fromAccess` / `context.toAccess` (`"both"` | `"production"` | `"sandbox"` | `"none"`) y `changes.environmentAccess`. Para canales, los webhooks se emiten en la **org padre**; `context.channelOrganizationId` identifica el canal.

#### Ciclo de invitación (`security.member.invited` → `security.member.created`)

Si se suscribe a ambos eventos, espere **dos entregas separadas** en este orden:

| Evento                    | Cuándo lo envía Gu1                                                                              | `organizationId` en el sobre              |
| ------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------- |
| `security.member.invited` | Cuando un admin envía la invitación desde Gu1 (Equipos / flujo de invite)                        | Organización donde se emite la invitación |
| `security.member.created` | Después de que el invitado complete el alta y quede establecida la membresía en esa organización | Misma organización que la invitación      |

**Qué debe esperar el integrador:**

* **No** espere `security.member.created` al mismo instante que `security.member.invited`. El invitado debe aceptar primero; la entrega suele ser segundos o minutos después.
* En `security.member.created`, `actor` y `affectedUser` suelen ser el **nuevo miembro** (mismo UUID de usuario Gu1). `affectedUser.email` es el correo invitado.
* `payload.description` suele ser `"Member accepted organization invitation"`. En casos poco frecuentes en los que la configuración secundaria (acceso al sandbox emparejado, roles granulares o asignación a equipo) no pudo aplicarse por completo en el mismo paso, la descripción puede ser `"Member accepted organization invitation (environment sync incomplete)"`. El miembro **sí** tiene acceso en el contexto de organización de la invitación — trate el webhook como creación exitosa del miembro para SIEM y gobernanza de accesos.
* Si recibe `invited` pero nunca `created` después de que el usuario confirme que ingresó a Gu1, verifique que su endpoint respondió HTTP 2xx en eventos cercanos al momento de aceptación y contacte a soporte Gu1 con timestamp aproximado y `organizationId`.
* Use `payload.context.invitationId` para correlacionar `invited` y `created` de la misma invitación (mismo UUID en ambos eventos cuando la aceptación fue exitosa).

**Campos de `context` en invitaciones** (en `security.member.invited` y `security.member.created` cuando aplique):

| Campo                    | Tipo    | Descripción                                                                                                                                                                                                                        |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `invitationId`           | UUID    | Registro de invitación Gu1 — correlaciona invited → created                                                                                                                                                                        |
| `granularRoleIds`        | UUID\[] | Roles granulares para la org production                                                                                                                                                                                            |
| `granularRoleIdsSandbox` | UUID\[] | Roles granulares para la org sandbox emparejada                                                                                                                                                                                    |
| `includeProduction`      | boolean | La invitación otorga acceso a production                                                                                                                                                                                           |
| `includeSandbox`         | boolean | La invitación otorga acceso a sandbox                                                                                                                                                                                              |
| `teamId`                 | UUID    | Equipo production asignado al aceptar                                                                                                                                                                                              |
| `teamIdSandbox`          | UUID    | Equipo sandbox asignado al aceptar                                                                                                                                                                                                 |
| `hasEnvironmentAccess`   | boolean | Si el miembro puede **entrar** a ese entorno (`organization_members.has_environment_access`). Independiente de roles granulares y equipos, que siempre se provisionan según la invitación en prod y sandbox cuando estén definidos |
| `environment`            | string  | `"production"` o `"sandbox"` según la org del sobre                                                                                                                                                                                |
| `invitedByUserId`        | UUID    | Usuario Gu1 que envió la invitación                                                                                                                                                                                                |
| `acceptedVia`            | string  | En `created`: `"invitation"` cuando ingresó por invitación                                                                                                                                                                         |
| `syncPartialFailure`     | boolean | Solo en `created`: la configuración secundaria (sandbox, roles granulares, equipos) no se completó por completo                                                                                                                    |
| `syncErrorMessage`       | string  | En `created` con `syncPartialFailure`: resumen interno del error                                                                                                                                                                   |

Ejemplo de payload `security.member.invited`:

```json theme={null}
{
  "event": "security.member.invited",
  "timestamp": "2026-06-18T12:00:00.000Z",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "payload": {
    "actionAt": "2026-06-18T12:00:00.000Z",
    "actor": {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "email": "admin@example.com",
      "displayName": "Jane Admin"
    },
    "affectedUser": {
      "email": "new@example.com"
    },
    "description": "User invited with role developer",
    "changes": {
      "role": { "previous": null, "current": "developer" }
    },
    "context": {
      "invitationId": "550e8400-e29b-41d4-a716-446655440099",
      "granularRoleIds": ["550e8400-e29b-41d4-a716-446655440011"],
      "granularRoleIdsSandbox": ["550e8400-e29b-41d4-a716-446655440012"],
      "includeProduction": true,
      "includeSandbox": true,
      "teamId": "550e8400-e29b-41d4-a716-446655440010",
      "teamIdSandbox": "550e8400-e29b-41d4-a716-446655440013",
      "hasEnvironmentAccess": true,
      "environment": "production",
      "invitedByUserId": "550e8400-e29b-41d4-a716-446655440001",
      "ipAddress": "203.0.113.10",
      "userAgent": "Mozilla/5.0 ..."
    }
  }
}
```

Ejemplo de payload `security.member.created`:

```json theme={null}
{
  "event": "security.member.created",
  "timestamp": "2026-06-18T12:05:00.000Z",
  "organizationId": "550e8400-e29b-41d4-a716-446655440000",
  "payload": {
    "actionAt": "2026-06-18T12:05:00.000Z",
    "actor": {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "email": "new@example.com"
    },
    "affectedUser": {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "email": "new@example.com"
    },
    "description": "Member accepted organization invitation",
    "context": {
      "invitationId": "550e8400-e29b-41d4-a716-446655440099",
      "granularRoleIds": ["550e8400-e29b-41d4-a716-446655440011"],
      "granularRoleIdsSandbox": ["550e8400-e29b-41d4-a716-446655440012"],
      "includeProduction": true,
      "includeSandbox": true,
      "teamId": "550e8400-e29b-41d4-a716-446655440010",
      "hasEnvironmentAccess": true,
      "environment": "production",
      "acceptedVia": "invitation",
      "invitedByUserId": "550e8400-e29b-41d4-a716-446655440001"
    }
  }
}
```

Eventos de seguimiento relacionados (mismo miembro, webhooks aparte cuando aplique): `security.member.environment_granted`, `security.member.team_added`, `security.member.channel_granted`, `security.role.assigned`.

### Roles y RBAC (`security.role.*`, `security.rbac.*`)

| Evento                           | Cuándo se dispara                                          |
| -------------------------------- | ---------------------------------------------------------- |
| `security.role.created`          | Rol granular creado                                        |
| `security.role.updated`          | Rol modificado (incluye diff de permisos cuando hay datos) |
| `security.role.deleted`          | Rol eliminado                                              |
| `security.role.assigned`         | Rol asignado a usuario                                     |
| `security.role.revoked`          | Rol revocado de usuario                                    |
| `security.rbac.granular_toggled` | RBAC granular habilitado o deshabilitado                   |

### Autenticación (`security.auth.*`)

| Evento                          | Cuándo se dispara                                    |
| ------------------------------- | ---------------------------------------------------- |
| `security.auth.login_succeeded` | Inicio de sesión exitoso (web Gu1)                   |
| `security.auth.logout`          | Cierre de sesión                                     |
| `security.auth.login_failed`    | Intento fallido (cuando el email resuelve a una org) |

### Configuración de seguridad

| Evento                      | Cuándo se dispara                                                                                       |
| --------------------------- | ------------------------------------------------------------------------------------------------------- |
| `security.settings.updated` | Modo sandbox, settings generales/de riesgo u otros cambios auditados (`context.scope` indica el ámbito) |

## Limitaciones

**No** están cubiertos hoy por webhooks de seguridad Gu1:

* Cambio de contraseña **self-service** del usuario en Clerk (solo IdP)
* Cambios MFA / SSO en Clerk
* Autenticación **API key** M2M (distinta del login de usuario)
* Revocaciones de sesión hechas solo en el dashboard Clerk

Las acciones admin de reset/generación de contraseña **sí** se cubren con `security.member.password_*`.

## Relacionado

* [Overview de webhooks](/es/webhooks/overview)
* [Seguridad y firmas](/es/webhooks/security)
* [Configuración](/es/webhooks/configuration)
