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

# SCIM Pilot Runbook

> Preflight, validation, conformance, and rollback steps for an inbound SCIM rollout.

Run this runbook before enabling SCIM for a customer-facing pilot, before
flipping `GENESIS_SCIM_REQUIRE_PROVISIONED_USERS=true`, and any time you
materially change the IdP-side SCIM configuration.

## Preflight

Confirm each of the following before running validation:

* The Genesis deployment has a stable HTTPS hostname and persistent
  configuration values.
* Authentication is configured and a test user can sign in through the
  customer IdP **before** SCIM-only admission is enforced.
* The SCIM admin endpoints are reachable as a Genesis admin:
  * `GET /api/config/scim/config`
  * `POST /api/config/scim/tokens/rotate`
  * `PUT /api/config/scim/group-role-mapping`
* A dedicated SCIM bearer token has been generated for the tenant and stored
  in the IdP's secret field.
* The group-to-role mapping has been configured **before** enabling group
  push from the IdP.
* `GENESIS_SCIM_REQUIRE_PROVISIONED_USERS` is set to `false` for now.

For deployment-specific environment variables, see
[SCIM Inbound Provisioning](/docs/Setup/SCIM-Inbound-Provisioning#environment-variables).

## Validation steps

Run these in order against a single pilot user. Reset state between iterations
if needed.

<Steps>
  <Step title="Provision a pilot user">
    Have the IdP provision one user. Or push directly:

    ```bash theme={null}
    POST /scim/v2/Users
    Authorization: Bearer <SCIM token>
    Content-Type: application/scim+json

    {
      "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
      "externalId": "idp-user-123",
      "userName": "alice@example.com",
      "active": true,
      "displayName": "Alice Example",
      "emails": [{ "value": "alice@example.com", "primary": true }]
    }
    ```
  </Step>

  <Step title="Verify the user exists">
    ```bash theme={null}
    GET /scim/v2/Users?filter=userName eq "alice@example.com"
    ```

    The response must contain exactly one resource with `active: true` and the
    expected `externalId`.
  </Step>

  <Step title="Push a mapped group with the user as a member">
    From the IdP (or directly), push one group present in the Genesis
    group-to-role mapping with the pilot user as a member. Confirm a `200` /
    `201` SCIM response.
  </Step>

  <Step title="Verify the role assignment">
    Have the pilot user sign in. Then call:

    ```bash theme={null}
    GET /api/rbac/me/permissions
    ```

    Confirm the role corresponding to the pushed group is present.
  </Step>

  <Step title="Remove the user from the group">
    From the IdP, remove the user from the group. Confirm only that role is
    revoked in Genesis. The user remains active.
  </Step>

  <Step title="Deactivate the pilot user">
    From the IdP, deactivate the user (or PATCH `active=false`). Confirm:

    * `GET /scim/v2/Users/<id>` returns `active: false`.
    * The user can no longer sign in once SCIM-only admission is enabled.
  </Step>

  <Step title="Verify audit rows">
    Confirm each operation above wrote a row to `SCIM_AUDIT_LOG`. See the
    [audit query examples](/docs/Setup/SCIM-Monitoring#audit-queries).
  </Step>

  <Step title="Confirm no unrelated changes">
    Inspect a non-SCIM admin user. Their roles, login state, and metadata
    should be unchanged.
  </Step>
</Steps>

## Conformance harness

Genesis ships a repeatable conformance harness, `scripts/validate_scim_conformance.py`,
that exercises the live SCIM endpoint. The script is included in the
Genesis source distribution; if you do not have it locally, request it from
your Genesis contact.

Run it from a machine that can reach the Genesis host before customer pilot
traffic begins, and again whenever you change SCIM-related configuration.

```bash theme={null}
python scripts/validate_scim_conformance.py \
  --base-url https://<genesis-host>/scim/v2 \
  --group-name <mapped-scim-group> \
  --output scim-conformance-report.json
```

Set `GENESIS_SCIM_TOKEN` in the environment before running the command. Pass
`--token` only for tightly controlled automation where shell history and
process listings are not retained.

For self-signed certificate troubleshooting in non-production environments,
add `--insecure`. Do not use `--insecure` against production hosts.

The harness checks include:

* Invalid bearer token is rejected with a SCIM-shaped error.
* `ServiceProviderConfig`, `ResourceTypes`, and `Schemas` are reachable.
* PATCH support is advertised; ETag is correctly **not** advertised.
* User and Group resources can be created, fetched, listed, filtered,
  PATCH-updated, replaced, and soft-deactivated.
* Group membership PATCH `add` and `remove` operations are reflected in
  Genesis role assignments.
* Group delete removes role membership without deactivating users.

The harness writes a JSON report listing every check and its status. Retain
the latest report alongside your release evidence.

## Rollback

If a rollout needs to be reversed:

<Steps>
  <Step title="Cut off the IdP">
    Disable the IdP SCIM app **or** revoke the Genesis SCIM token with
    `POST /api/config/scim/tokens/revoke`.
  </Step>

  <Step title="Reopen sign-in if it was restricted">
    Set `GENESIS_SCIM_REQUIRE_PROVISIONED_USERS=false` so non-SCIM users can
    still sign in.
  </Step>

  <Step title="Restore the previous mapping">
    PUT the previous `group_role_mapping` payload through
    `PUT /api/config/scim/group-role-mapping`.
  </Step>

  <Step title="Reconcile roles">
    Re-run the last known-good IdP group snapshot, or push the mapped groups
    from the IdP again, to bring Genesis role state back in line.
  </Step>

  <Step title="Roll back the deployment if needed">
    If the regression is suspected to be in Genesis itself, roll the
    deployment back to the previous container image and restart the
    application. Helm-based deployments can use `helm rollback`.
  </Step>
</Steps>

## Pilot-to-production checklist

Before announcing SCIM as generally available for the deployment:

* All [validation steps](#validation-steps) pass for the pilot user.
* The [conformance harness](#conformance-harness) report is green and
  retained.
* [Monitoring](/docs/Setup/SCIM-Monitoring) signals and alerts are wired up
  and acknowledged by an on-call owner.
* The [security review](/docs/Setup/SCIM-Security) has been completed for the
  deployment.
* A separate SCIM bearer token exists per integration and the rotation
  procedure is documented for the customer.
* For multi-replica deployments, strict global SCIM rate limiting is enforced
  at ingress / WAF / API gateway / a shared limiter.
* A rollback path is documented and rehearsed.

## Accepted limitations for this release

* Genesis does not advertise ETag support; optimistic concurrency is not
  required for a pilot unless the target IdP requires it.
* SCIM Bulk operations are not supported.
* Custom SCIM schema extensions beyond the SCIM Enterprise User extension fields
  documented in the [API Reference](/docs/Setup/SCIM-API-Reference#user-payload-example)
  are not supported.
* The in-process per-token rate limiter is suitable for single-pod
  deployments; for multi-replica deployments, enforce strict global limits at
  ingress / WAF / API gateway / a shared limiter.
