
# Simula il provisioning SCIM

`POST /v1/directories/{directory_id}:simulate` · autorizzazione `directories:write` · solo sviluppo e staging

Esegue uno scenario del simulatore SCIM sull'endpoint SCIM reale della directory. Solo per questa esecuzione, KeenAuth genera un vero token SCIM, lo usa e poi lo revoca. I controlli sul token, i rate limit, il circuit breaker per la deprovisioning di massa e il log del provisioning funzionano esattamente come con il tuo provider di identità. Gli utenti sono un insieme fisso e fittizio: 25 persone con dominio `example.test` in 5 gruppi. Non contengono dati personali reali.

Il simulatore è uno strumento di sviluppo e modifica la directory. Gli utenti e i gruppi che scrive restano nella directory come qualsiasi altro record provisionato. Usa una directory che hai creato per i test.

| Scenario | Cosa fa |
|---|---|
| `seed` | Crea i 25 utenti e i 5 gruppi con le relative appartenenze. In una directory che li contiene già, il primo utente riceve un `409` SCIM e l'esecuzione risulta `failed`. |
| `bulk_deactivate` | Invia `active=false` per il 60% degli utenti (15 su 25). Il circuit breaker scatta solo se `mass_deprovision_guard.absolute_min` della directory è 15 o meno. Con il valore predefinito di 25 non scatta. |
| `group_churn` | Sposta un utente da un gruppo a un altro. |
| `attribute_update` | Modifica il nome visualizzato e il cognome di ogni utente. |
| `conflict_email` | Crea un utente con uno `userName` già esistente e si aspetta un `409 uniqueness` SCIM. |

Se la directory è vuota, ogni scenario diverso da `seed` esegue prima `seed`.

Il token di simulazione non viene elencato e non conta nei 2 token validi. Usarlo non avvia la rotazione del token del tuo provider di identità. Per ogni directory può essere in corso una sola esecuzione alla volta. L'esecuzione viene registrata nell'audit come `directory.simulation_started` e `directory.simulation_finished`.

## Richiesta

| Campo | Tipo | Obbligatorio | Descrizione |
|---|---|---|---|
| `directory_id` | path | sì | ID della directory SCIM (`dir_…`). |
| `scenario` | body, stringa | sì | `seed`, `bulk_deactivate`, `group_churn`, `attribute_update` o `conflict_email`. |
| `Idempotency-Key` | header | no | Ripropone la prima risposta per una richiesta ritentata; lo scenario non viene eseguito di nuovo. |

```json
{"scenario": "bulk_deactivate"}
```

## Risposta

`200 OK` con il risultato dell'esecuzione. Una risposta di errore SCIM non fa fallire la richiesta. Rende l'esecuzione `failed`, compila `failure` e lascia i conteggi a quanto riuscito prima dell'errore. Il risultato contiene solo conteggi e stati: nessun utente, nessun ID SCIM e nessun token.

```json
{
  "directory_id": "dir_01j9xm2n4p6q8r0s2t4v6w8y0z",
  "scenario": "bulk_deactivate",
  "status": "completed",
  "users_created": 0,
  "groups_created": 0,
  "users_updated": 0,
  "groups_updated": 0,
  "users_deactivated": 15,
  "conflicts": 0,
  "circuit_breaker_tripped": true,
  "deprovision_hold": {"id": "0191e9b2-6f3a-7c4d-8e5f-0a1b2c3d4e5f", "pending_count": 6},
  "failure": null,
  "started_at": "2026-10-28T09:31:00.123456Z",
  "completed_at": "2026-10-28T09:31:01.654321Z"
}
```

| Campo | Descrizione |
|---|---|
| `status` | `completed`, oppure `failed` quando l'endpoint ha risposto con un errore SCIM, l'esecuzione ha impiegato troppo tempo o una risposta non era quella attesa dallo scenario. |
| `users_updated` | PATCH sugli utenti diversi dalle disattivazioni. |
| `users_deactivated` | PATCH con `active=false` accettati dall'endpoint, comprese quelle trattenute. |
| `conflicts` | Risposte `409 uniqueness` attese (`conflict_email`). |
| `circuit_breaker_tripped` | Durante l'esecuzione è stato aperto un trattenimento per deprovisioning di massa. |
| `deprovision_hold` | Il trattenimento aperto della directory dopo l'esecuzione, oppure `null`. Puoi approvarlo o rifiutarlo con gli endpoint `deprovision-holds`. |
| `failure` | `null` quando `completed`. Altrimenti `reason` (`scim_error`, `timeout` o `unexpected_response`), e per `scim_error` anche `scim_status` (stato HTTP) e `scim_type` (`scimType` SCIM, oppure `null`). |

## Errori

| HTTP | code | Quando |
|---|---|---|
| 400 | `unknown_field` | Il body contiene un campo diverso da `scenario`. |
| 403 | `test_feature_not_in_production` | L'ambiente è un ambiente di produzione. |
| 404 | `not_found` | La directory non esiste in questo ambiente. |
| 409 | `conflict` | È in corso un'altra esecuzione di questa directory, oppure la directory è disattivata o in fase di eliminazione. |
| 422 | `validation_failed` | `scenario` manca o è sconosciuto (`/scenario`). |
| 422 | `idempotency_key_reuse` | La `Idempotency-Key` è stata usata per una richiesta diversa. |
| 401 | `unauthenticated` | La credenziale manca, non è valida o è stata revocata. |
| 403 | `insufficient_permissions` | La credenziale non ha l'autorizzazione richiesta. |
| 429 | `rate_limited` | È stato superato il rate limit; riprova dopo il periodo indicato in `Retry-After`. |
| 503 | `service_unavailable` | La sincronizzazione della directory o il simulatore non sono disponibili temporaneamente oppure non sono configurati in questo deployment; riprova dopo il periodo indicato in `Retry-After`. |

## Esempio

```bash
curl -X POST "https://api.eu.keenauth.com/v1/directories/dir_01j9xm2n4p6q8r0s2t4v6w8y0z:simulate" \
  -H "Authorization: Bearer $KEENAUTH_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"scenario": "seed"}'
```

```bash
keenauth directories simulate dir_01j9xm2n4p6q8r0s2t4v6w8y0z --scenario bulk_deactivate
```
