
# Lister les événements d'audit

`GET /v1/audit-events` · autorisation `audit-events:read`

Liste les enregistrements d'audit de l'environnement avec une pagination par curseur, du plus récent au plus ancien. Le flux `admin` contient les modifications effectuées via l'API de gestion, le tableau de bord et la plateforme ; le flux `application` contient les événements écrits par votre application. Chaque enregistrement fait partie d'une chaîne de hachage par environnement et par flux, de sorte que l'historique peut être vérifié indépendamment à l'aide d'un export (`POST /v1/audit-exports`).

L'environnement provient toujours de la clé API ; il n'existe pas de paramètre d'environnement.

## Requête

| Paramètre | Dans | Obligatoire | Description |
|---|---|---|---|
| `limit` | query | non | Taille de page, de 1 à 100. Valeur par défaut : 20. |
| `after` | query | non | Curseur opaque issu de `list_metadata.after` (enregistrements plus anciens). Exclusif avec `before`. |
| `before` | query | non | Curseur opaque issu de `list_metadata.before` (enregistrements plus récents). Exclusif avec `after`. |
| `stream` | query | non | `admin` (par défaut) ou `application`. |
| `from` | query | non | Heure RFC 3339 ; enregistrements à cette heure ou après. Par défaut, la plus tardive entre le début de la fenêtre de conservation et `to` moins 92 jours. |
| `to` | query | non | Heure RFC 3339 ; enregistrements antérieurs à cette heure. Par défaut, maintenant. La plage de `from` à `to` ne dépasse pas 92 jours. |
| `action` | query | non | Préfixe d'action, tel que `user.` ou `connection.updated`. |
| `category` | query | non | `authentication`, `session`, `token`, `administration`, `provisioning`, `federation`, `authorization`, `data_access`, `security`, `key_management`, `configuration` ou `application`. |
| `actor_type` | query | non | Type d'acteur, tel que `api_key`, `dashboard_user`, `m2m_client`, `agent` ou `system`. |
| `actor_id` | query | non | Identifiant exact de l'acteur tel qu'enregistré (`key_…`, `usr_…`, `system:<service>`). |
| `target_type` | query | non | Type de cible, tel que `user`, `organization` ou `audit_export`. |
| `target_id` | query | non | Identifiant exact de la cible. Avec `target_type`, les deux doivent correspondre à la même cible. |
| `org_id` | query | non | Enregistrements concernant une organisation (`org_…`). |
| `outcome` | query | non | `success`, `failure`, `denied` ou `error`. |
| `request_id` | query | non | `Idp-Request-Id` d'une requête (UUID). |
| `correlation_id` | query | non | `Idp-Correlation-Id` d'un workflow (UUID). |
| `agent_only` | query | non | `true` ne renvoie que les actions d'agents : `actor_type` `agent` ou un `act_chain` non vide. |
| `client` | query | non | Type de client ayant effectué l'appel : `mcp` (le serveur MCP de gestion, `metadata.client` = `mcp/<version>`) ou `cli` (la CLI KeenAuth, `cli/<version>`). Le client déclare lui-même cette valeur ; elle ne prouve pas qui a agi, c'est l'acteur de l'enregistrement qui le fait. Liste uniquement : un export n'a pas de filtre `client`. |

Les enregistrements sont toujours triés par `occurred_at` (puis `id`), du plus récent au plus ancien ; il n'existe pas de paramètre `order` (`order=desc` est accepté, toute autre valeur échoue avec `validation_failed`). Un curseur n'est valide qu'avec les filtres et l'environnement pour lesquels il a été émis. Aucun nombre total n'est renvoyé.

Une recherche dépassant 10 secondes s'interrompt avec `422 search_too_broad` : restreignez les filtres ou la plage de temps, ou utilisez un export pour les plages étendues.

## Réponse

`200 OK`. `data` contient les enregistrements de la page ; `list_metadata.after` pointe vers les enregistrements plus anciens et `list_metadata.before` vers les plus récents (`null` lorsqu'il n'y en a pas). Les champs vides valent `null`.

`ip` et `user_agent` ne sont présents que si la clé possède l'autorisation `audit-events:read_ip`, et ne sont renseignés que pour les enregistrements de moins de 13 mois. Sans cette autorisation, les champs sont entièrement omis (aucune valeur masquée). `ip_prefix`, `ip_country`, `ip_asn` et `user_agent_family` sont toujours renvoyés. `prev_hash`, `org_prev_hash` et `record_hash` sont des valeurs SHA-256 en base64url sans remplissage.

```json
{
  "data": [
    {
      "id": "evt_01j9xk3m7q8r2s4t6v8w0y2z4a",
      "stream": "admin",
      "seq": 4182,
      "schema_version": 1,
      "action": "user.blocked",
      "category": "administration",
      "outcome": "success",
      "reason_code": null,
      "occurred_at": "2026-10-01T08:15:42.120Z",
      "received_at": "2026-10-01T08:15:42.131Z",
      "recorded_at": "2026-10-01T08:15:42.140Z",
      "clock_anomaly": false,
      "actor_type": "api_key",
      "actor_id": "key_01j9xk3m7q8r2s4t6v8w0y2z4d",
      "act_chain": null,
      "session_id": null,
      "auth_context": null,
      "elevation_ref": null,
      "org_id": null,
      "targets": [
        {"type": "user", "id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p", "org_id": null, "name": null}
      ],
      "application_id": null,
      "ip_prefix": "203.0.113.0/24",
      "ip_country": "DE",
      "ip_asn": 64500,
      "user_agent_family": "keenauth-go",
      "request_id": "0192a6c1-7d3e-7a10-9b2c-3d4e5f607182",
      "correlation_id": null,
      "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
      "producer_service": "directory",
      "policy_ref": "perm:users:write",
      "changes": {"status": {"old": "active", "new": "blocked"}},
      "metadata": null,
      "prev_hash": "n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg",
      "org_prev_hash": null,
      "record_hash": "LCa0a2j_xo_5m0U8HTBBNBNCLXBkg7-g-YpeiGJm564"
    }
  ],
  "list_metadata": {
    "before": null,
    "after": "<opaque cursor>"
  }
}
```

## Erreurs

Chaque erreur est un corps `application/problem+json` avec un `code` stable.

| HTTP | `code` | Quand |
|---|---|---|
| 400 | `invalid_cursor` | Le curseur est mal formé ou n'a pas été émis pour cette requête. |
| 400 | `invalid_filter` | Le service d'audit a rejeté un filtre, par exemple une plage de plus de 92 jours. |
| 400 | `range_outside_retention` | `from` ou `to` est en dehors de la fenêtre de conservation des audits de votre offre. |
| 422 | `validation_failed` | Un paramètre de requête est invalide (`limit` hors plage, horodatage incorrect, `to` non postérieur à `from`, `stream`, `category` ou `outcome` inconnu, identifiant mal formé, paramètre répété, `order` autre que `desc`). |
| 422 | `search_too_broad` | La recherche a dépassé 10 secondes ; restreignez-la. |
| 401 | `unauthenticated` | La clé API est absente, invalide ou révoquée. |
| 403 | `insufficient_permissions` | La clé ne possède pas `audit-events:read`. |
| 429 | `rate_limited` | La limite de débit a été dépassée ; respectez `Retry-After`. |
| 503 | `service_unavailable` | Une dépendance est temporairement indisponible ; réessayez plus tard. |

## Exemple

```bash
curl "https://api.eu.keenauth.com/v1/audit-events?action=user.&from=2026-10-01T00:00:00Z" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
```

```bash
keenauth audit-events list --action user. --from 2026-10-01T00:00:00Z
```

## Données personnelles

Ce point de terminaison traite des données personnelles : des événements d'audit. [Données personnelles dans les API KeenAuth](/docs/policies/personal-data) décrit ce qui est stocké, pendant combien de temps il est conservé et comment il est supprimé. Ne transmettez de catégories particulières de données personnelles (santé, données biométriques, religion, opinions politiques, orientation sexuelle) dans aucun champ.
