# User lifecycle and passwords

A user moves through Okta's statuses (staged, active, suspended, deprovisioned) by the lifecycle routes, and password routes expire, reset and change its password; nothing is emailed.

The user lifecycle is how an onboarding and offboarding flow moves a user between statuses, and how it changes the user's password. Every transition happens in the request that asks for it. Create a staged user, activate it, suspend it, then deactivate and purge it:

```bash
curl -s -X POST "$RYSTIC_URL/_rystic/scenario" -d '{"name":"design_studio"}' -o /dev/null
u="$RYSTIC_URL/api/v1/users"
curl -s "$u?activate=false" -H 'Authorization: SSWS placeholder' -H 'Content-Type: application/json' -d '{"profile":{"firstName":"New","lastName":"Hire","email":"new.hire@wdcontractors.example","login":"new.hire@wdcontractors.example"}}' | jq -c '{id, status}'
# -> {"id":"00u00000000000000001","status":"STAGED"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/activate?sendEmail=false" -H 'Authorization: SSWS placeholder' | jq -c '{activationToken}'
# -> {"activationToken":"actvTok0000000000001"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/suspend" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 200
curl -s "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' | jq -c '{status}'
# -> {"status":"SUSPENDED"}
curl -s -X POST "$u/00u00000000000000001/lifecycle/deactivate" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 200
curl -s "$u?filter=status%20eq%20%22DEPROVISIONED%22" -H 'Authorization: SSWS placeholder' | jq -c 'length'
# -> 4
curl -s -X DELETE "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 204
curl -s "$u/00u00000000000000001" -H 'Authorization: SSWS placeholder' -o /dev/null -w '%{http_code}\n'
# -> 404
```

### Statuses and routes

A user is `STAGED` when created with `activate=false`, and `ACTIVE` once created with the default `activate=true` or activated.

**Differs from Okta:** a user activated without a password lands `ACTIVE` at once, where Okta can leave it `PROVISIONED` until the user completes activation. Passwordless activation is not modeled.

These routes sit under `/api/v1/users/{id}/lifecycle/`:

- `activate`, `deactivate`, `suspend`, `unsuspend` and `reactivate`
- `expire_password` and `expire_password_with_temp_password`
- `reset_password` and `reset_factors`

`expire_password` leaves the user `PASSWORD_EXPIRED`. What `activate` and `reset_password` return depends on `sendEmail`:

| Route | Without `sendEmail` | With `sendEmail=false` | With `sendEmail=true` |
|---|---|---|---|
| `activate` | as `true` | an `activationUrl` | `{}` |
| `reset_password` | as `false` | a `resetPasswordUrl` | `{}` |

**Differs from Okta:** Okta documents `sendEmail` as required on `reset_password`, while the simulator takes a missing one as `false`.

**Differs from Okta:** each URL is on the simulator's own origin and serves nothing.

**Differs from Okta:** no email is sent, whatever `sendEmail` says.

**Differs from Okta:** nobody signs in, so `lastLogin` never moves and `LOCKED_OUT` is reachable only from a seed.

### Deactivating and purging

A first `DELETE` on a user deactivates it (`DEPROVISIONED`) and a second purges it, so the read in the example returns 404. A plain user list leaves `DEPROVISIONED` users out, while `search` and `filter` include them.

Deactivating or purging a user removes its application assignments, direct and group-derived. Activating the user again restores the group-derived ones only ([Bookmark applications](https://www.rystic.ai/docs/simulators/okta/features/applications.md)).

Adding a deactivated user to a group returns 403 `E0000038`. So does a `POST` or `PUT` that edits a deactivated user's profile. That is the policy of the Okta org the simulator was measured against.

### Passwords

`POST /api/v1/users/{userId}/credentials/change_password` takes `oldPassword` and `newPassword` and returns the user's credentials.

**Differs from Okta:** the simulator has no password policy, so it accepts any password.

---

Source: https://www.rystic.ai/docs/simulators/okta/features/user-lifecycle · Markdown: https://www.rystic.ai/docs/simulators/okta/features/user-lifecycle.md
