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

# Autenticación

> Tokens de servicio, rotación, IP allowlist y qué guarda EdTools de tu token.

El Client API se autentica con **tokens de servicio** (no con sesiones, ni cookies, ni OAuth). Se crean en **Ajustes → API e integraciones → API Keys**.

```bash theme={null}
curl https://app.edtools.co/api/client/v1/me \
  -H "Authorization: Bearer $EDTOOLS_API_KEY"
```

<Warning>
  El token completo se muestra **una sola vez**: al crearlo y al rotarlo. EdTools guarda un hash HMAC-SHA256 con el pepper `EDTOOLS_API_KEY_PEPPER`, así que no puede recuperarlo por ti. Si se pierde, se rota.
</Warning>

## Crear el primer token

<Steps>
  <Step title="Identifica la integración, no a la persona">
    Nombre operativo, responsable, correo de contacto, sistema de origen y ambiente. Un token por sistema y por ambiente: cuando haya que revocar uno, no se cae el resto.
  </Step>

  <Step title="Da solo los scopes activos que ese sistema necesita">
    Si el SIS solo lee estudiantes, `students:read` y nada más. Ver [Scopes](/client-api/scopes).
  </Step>

  <Step title="Define expiración, recordatorio de rotación y tope de peticiones">
    El rate limit es por token y por minuto. Súbelo con criterio, no por defecto.
  </Step>

  <Step title="Agrega la IP allowlist si el cliente ya conoce sus salidas">
    Acepta IPv4 literal o CIDR IPv4. Es la defensa más barata contra un token filtrado.
  </Step>

  <Step title="Guarda el token en el gestor de secretos del cliente">
    Nunca por chat, nunca en un ticket, nunca en el repositorio.
  </Step>
</Steps>

## Qué valida el servidor en cada petición

`clientApiAuthMiddleware` revisa, en este orden, y falla en el primero que no pase:

| Comprobación                                    | Si falla                  |
| ----------------------------------------------- | ------------------------- |
| El token existe, no está revocado ni expirado   | `401 INVALID_TOKEN`       |
| La IP de origen está en la allowlist (si hay)   | `403 IP_NOT_ALLOWED`      |
| El token tiene el scope que el endpoint exige   | `403 SCOPE_REQUIRED`      |
| La institución tiene los módulos del endpoint   | `403 MODULE_DISABLED`     |
| En escrituras: el token manda sobre ese dominio | `403 SOR_WRITE_FORBIDDEN` |
| No se pasó del tope de peticiones               | `429 RATE_LIMITED`        |

## Permisos del lado de EdTools

Quien administra las keys dentro del dashboard necesita:

* `settings.api.read` — ver keys, actividad y catálogo de endpoints.
* `settings.api.manage` — crear, editar, rotar y revocar.

## Rotar sin cortar el servicio

Rotar emite un token nuevo e invalida el anterior. El orden que no rompe nada:

<Steps>
  <Step title="Crea una key nueva con los mismos scopes">
    Dos tokens válidos a la vez es una situación normal y transitoria.
  </Step>

  <Step title="Despliega el token nuevo en el sistema externo">
    Confirma con una llamada a `/me` que responde con el `apiKey.id` nuevo.
  </Step>

  <Step title="Revoca el viejo">
    Y revisa la actividad: si algo seguía usándolo, aparecerá como `401` con el nombre de la key.
  </Step>
</Steps>

## Cuando algo falla

En **Ajustes → API e integraciones → Actividad** puedes buscar por path, API key, IP, user-agent o `requestId`. Cada detalle trae el endpoint, el scope exigido, el Source of Record, los módulos requeridos, el código de error y el estado del rate limit — con un resumen copiable que **no incluye payloads sensibles ni el header `Authorization`**.

Para pedir soporte a EdTools, manda ese resumen: `requestId`, nombre de la key, sistema de origen y ventana horaria. Nunca el token.
