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

# SCIM 2.0 Provisioning

> Auto provision and deprovision Compliance Command Center accounts from Okta, Azure AD or OneLogin over SCIM 2.0, mapping directory groups onto RBAC roles.

SCIM provisioning lets your identity provider create, update and deactivate Compliance Command Center
accounts automatically, so joiners and leavers are handled by your directory instead of by hand. It is a
licence-gated add-on (`algovoi-command-center-scim`) that ships in the Verifiable Compliance Suite and
pairs with the console's existing SSO (SAML, OIDC, LDAP, Active Directory) and its authenticator-app MFA.

It reuses the console's own identity model rather than adding a parallel one:

* a SCIM **User** is a console account, in the same store your SSO providers read;
* a SCIM **Group** is one of the four fixed RBAC roles (`admin`, `compliance_officer`, `auditor`,
  `viewer`); no new role or group concept is introduced;
* every provisioning change (create, update, deactivate, role assignment) is appended to the console's
  Falcon-signed, offline-verifiable audit chain, so provisioning is itself compliance evidence.

Deprovisioning is a soft deactivate: `DELETE` marks the account inactive, it can no longer sign in, and
the account plus its audit history are retained as evidence. Nothing is hard deleted.

***

## 1. Enable it

The add-on is off by default and licence-gated. It becomes active when three things are true:

1. **Installed.** It ships in the suite bundle; a standalone deployment installs
   `algovoi-command-center-scim` alongside the console.
2. **Licensed.** Your AlgoVoi suite `bundle_license` (the same one that unlocks the rest of the suite)
   satisfies it. With no valid licence the console does not mount the SCIM endpoint at all, so it stays
   unreachable, fail-closed.
3. **Reachable over TLS.** The endpoint lives under your console origin at `/scim/v2`.

When those hold, the console exposes the SCIM base URL:

```
https://your-console-host/scim/v2
```

### The SCIM bearer token

The SCIM endpoint authenticates with a dedicated bearer token, entirely separate from human sign-in. Set
it explicitly, or let the console bootstrap one on first run:

```bash theme={null}
# Option A: set it explicitly (recommended; this is also how you rotate it)
export COMMAND_CENTER_SCIM_TOKEN="$(python -c 'import secrets;print(secrets.token_urlsafe(32))')"

# Option B: no env set: the console writes one once to the data dir, mode 0600
cat "$COMMAND_CENTER_DATA_DIR/command-center-scim-token"
```

Your IdP presents it on every call as `Authorization: Bearer <token>`. To **rotate**, set a new
`COMMAND_CENTER_SCIM_TOKEN` and restart the console, then update the token in your IdP. Treat it like any
production secret.

***

## 2. What it provisions

| SCIM resource | Maps to           | Notes                                                                                                                                                                              |
| ------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `User`        | a console account | `userName` is the login; `active` drives the lifecycle; `emails`, `displayName`, `externalId` are stored. SCIM users sign in through your SSO; this add-on does not set passwords. |
| `Group`       | a fixed RBAC role | The four groups are `admin`, `compliance_officer`, `auditor`, `viewer`. Group membership sets the account's role.                                                                  |

A newly provisioned user starts at the least-privilege `viewer` baseline; assign a role by adding the
user to the matching group. Removing a user from their role group returns them to `viewer`. The console
can never be left without an administrator: any change that would deactivate or demote the last active
admin is refused.

***

## 3. Set up your identity provider

The three providers below all speak standard SCIM 2.0. In every case you supply the same two values.

| Setting                       | Value                                                                       |
| ----------------------------- | --------------------------------------------------------------------------- |
| SCIM base URL / connector URL | `https://your-console-host/scim/v2`                                         |
| Authentication                | HTTP header, `Authorization: Bearer <your SCIM token>` (OAuth bearer token) |
| Unique identifier for users   | `userName`                                                                  |

### Okta

1. In the Okta admin console, open **Applications**, create or open your app, and go to the
   **Provisioning** tab. Choose **Configure API Integration** and enable it.
2. Set **Base URL** to `https://your-console-host/scim/v2` and **API Token** to your SCIM bearer token,
   then **Test API Credentials**.
3. Under **Provisioning to App**, enable **Create Users**, **Update User Attributes** and
   **Deactivate Users**. Deactivation calls `DELETE`/`PATCH active=false`, which soft-deactivates the
   account.
4. Map attributes so Okta `userName` maps to console `userName` and `email` maps to `emails.value`.
5. Under **Push Groups**, push the groups that correspond to the four roles. Name them to match a role
   (`admin`, `compliance_officer`, `auditor`, `viewer`) or the role label (for example `Administrator`);
   the console accepts a pushed group only when it maps to an existing role.

### Azure AD (Microsoft Entra ID)

1. In **Enterprise applications**, open your app and select **Provisioning**. Set **Provisioning Mode**
   to **Automatic**.
2. Set **Tenant URL** to `https://your-console-host/scim/v2` and **Secret Token** to your SCIM bearer
   token, then **Test Connection**.
3. In **Mappings**, keep **Provision Azure Active Directory Users** and **Groups** enabled. Ensure
   `userPrincipalName` maps to `userName` and `mail` maps to `emails[type eq "work"].value`.
4. Assign users and groups to the app. Azure sends `PATCH` with `active=false` on unassignment, which
   deactivates the account.
5. Name the assigned groups to match the four roles so membership sets the console role.

### OneLogin

1. In OneLogin, open the app's **Configuration** and enter the **SCIM Base URL**
   `https://your-console-host/scim/v2` and the **SCIM Bearer Token**.
2. Set the **API Connection** to **Enable** and confirm the connection succeeds.
3. On the **Provisioning** tab, enable **Create user**, **Delete user** and **Update user**. Delete
   performs a soft deactivate.
4. Map **SCIM Username** to `userName` and the email attribute to `emails.value`.
5. Use **Rules** or group mappings so that role entitlements map to the four role groups.

***

## 4. Deprovisioning

When your IdP disables or unassigns a user, it calls the SCIM endpoint to deactivate the account. The
effect:

* the account is marked `active=false` (a soft deactivate, never a hard delete);
* the user can no longer sign in through any provider (local, LDAP, AD, OIDC, SAML);
* the account record and its full audit history are retained as evidence;
* a `scim_user_deactivate` entry is written to the signed audit chain.

Existing signed sessions are stateless and expire on their own TTL, so deprovisioning stops new sign-ins
immediately and closes out access as sessions lapse.

***

## 5. Audit evidence

Every SCIM operation is appended to the same Falcon-1024 signed, hash-linked audit chain the rest of the
console uses, and re-verifies offline from the **Audit** page or the validation pack. The actions you
will see:

| Action                                               | When                                |
| ---------------------------------------------------- | ----------------------------------- |
| `scim_user_create`                                   | a user is provisioned               |
| `scim_user_update`                                   | user attributes change              |
| `scim_user_deactivate` / `scim_user_reactivate`      | a user is deprovisioned or restored |
| `scim_group_add_member` / `scim_group_remove_member` | a role is assigned or removed       |

Each entry records the target account and is hash-linked to the previous one, so the provisioning history
is tamper-evident and exports as part of your compliance evidence.

***

## 6. Endpoint reference

Base path `https://your-console-host/scim/v2`. All calls require the bearer token.

| Method and path                                    | Purpose                                                                                                                 |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `GET /Users`                                       | List users. Supports `eq` filters on `userName`, `emails.value`, `active`, `externalId`, plus `startIndex` and `count`. |
| `POST /Users`                                      | Provision a user.                                                                                                       |
| `GET /Users/{id}`                                  | Fetch one user.                                                                                                         |
| `PUT /Users/{id}`                                  | Replace user attributes.                                                                                                |
| `PATCH /Users/{id}`                                | Update attributes or `active` (deactivate/reactivate).                                                                  |
| `DELETE /Users/{id}`                               | Soft-deactivate (deprovision).                                                                                          |
| `GET /Groups`, `GET /Groups/{id}`                  | List the four role groups and their members.                                                                            |
| `POST /Groups`                                     | Idempotent for a group naming an existing role; a new role cannot be created.                                           |
| `PATCH /Groups/{id}`                               | Add, remove or replace members, which sets or clears that role.                                                         |
| `GET /ServiceProviderConfig`, `GET /ResourceTypes` | SCIM discovery, so your IdP can probe capabilities.                                                                     |

Pair SCIM with [authenticator-app MFA](/compliance-command-center) for the full "MFA plus auto-provision"
enterprise identity story, all self-hosted and evidenced on the same signed chain.
