# Validate Identifier-First SSO And SCIM

Use this guide to manually validate the full identifier-first authentication flow and SCIM lifecycle behavior in staging.

## Scope

This checklist validates:

* Email-first sign-in routing (`password`, `google_workspace`, `okta_saml`)
* SSO session bootstrap and first-login user materialization
* Okta SCIM user lifecycle (create/update/deactivate/reactivate)
* MFA policy lockout for IdP-managed orgs
* Blocking of password/invite flows for SSO orgs
* Master-admin auth strategy and SCIM token operations

## Preflight

Before testing, confirm:

* Staging has `AUTH_IDP_ALLOWED_ORIGINS` populated for your Okta/custom IdP origins.
* Firebase SAML provider IDs are created and valid for each Okta org under test.
* You have one org for each strategy:
  * `email_password`
  * `google_workspace`
  * `okta_saml` + `scimEnabled=true`
* You have test users for each org domain.
* For Okta, SCIM integration is configured with the current SCIM token from Master Admin.

## Master-Admin Setup Checks

1. Open `/admin/organizations`.
2. Create a new org with each auth strategy using the "Create organization" card.
3. For Okta orgs, set:
   * `strategy=okta_saml`
   * valid `providerId` (format `saml.*`)
   * domain list
   * SCIM enabled
4. Save auth settings for an existing org and verify persistence after refresh.
5. Rotate SCIM token and confirm a new token is shown once.

Expected:

* Org auth config is visible in admin UI and persists.
* Rotated token replaces token id on org auth config.

## Identifier-First Sign-In Checks

1. Open `/auth/sign-in`.
2. Confirm only email + Continue is shown initially.
3. Test each domain type:
   * Password org email -> password field appears.
   * Google org email -> redirect to Google.
   * Okta org email -> redirect to Okta.
4. Test unknown domain email -> fallback to password step.

Expected:

* No "Continue with Google" or "Continue with Okta" buttons.
* Routing strictly follows org/domain auth config.

## Password Org Checks

1. Sign in with password-org account.
2. Confirm app lands at `/app`.
3. Trigger forgot-password flow.
4. Send invite from org users page.
5. Accept invite and set password.

Expected:

* Password, invite, and reset flows remain functional.
* MFA behavior follows org policy (`soft`/`enforced`).

## Google Workspace Org Checks

1. Sign in with Google-org account via email-first flow.
2. Confirm session lands at `/app`.
3. Try password reset for Google-org email.
4. Try invite creation in org users.
5. Open org security settings.

Expected:

* SSO redirect/login succeeds.
* Password reset returns IdP-managed error.
* Invite creation is blocked with explicit SSO policy error.
* Security settings show MFA as managed by identity provider.
* MFA gate does not prompt/block local MFA setup.

## Okta + SCIM Org Checks

### A) Provisioned active user

1. Push user from Okta to SCIM `/Users` (active=true).
2. Sign in through identifier-first email flow.

Expected:

* SSO succeeds.
* If first login, canonical `users/{uid}` is created automatically.

### B) Deprovision

1. Deactivate user in Okta (SCIM active=false or delete flow).
2. Retry sign-in.

Expected:

* Sign-in blocked with inactive-directory message.
* Existing Axon account is disabled and refresh tokens revoked.

### C) Reactivate

1. Reactivate user in Okta (SCIM active=true).
2. Retry sign-in.

Expected:

* Sign-in succeeds again.
* Axon account is re-enabled when previously SCIM-disabled.

### D) Token rotation safety

1. Rotate SCIM token in Master Admin.
2. Retry SCIM call with old token.
3. Retry SCIM call with new token.

Expected:

* Old token receives `401 Unauthorized`.
* New token works.

## Security Settings And MFA Policy Checks

1. For SSO orgs, call `GET /api/org/security-settings`.
2. Verify `mfaManagedByIdp=true`.
3. Attempt `PATCH /api/org/security-settings` to change MFA policy.

Expected:

* PATCH is rejected with managed-by-IdP error.
* UI controls for MFA policy are read-only/disabled.

## API Spot Checks

* `POST /api/auth/identifier`
  * Returns method + org/provider routing decision.
* `POST /api/auth/sso-session`
  * Rejects provider mismatch.
  * Rejects inactive Okta SCIM users.
  * Provisions first-time SSO users.
* `POST /api/org/users`
  * Rejects invites for non-`email_password` orgs.
* `POST /api/auth/password-reset`
  * Rejects SSO-managed org emails.
* `POST /api/auth/accept-invite`
  * Rejects SSO-managed org invites.

## Audit Log Verification

Confirm these actions appear in audit logs during test execution:

* `admin.org.create`
* `admin.org.auth.update`
* `admin.org.scim.token.rotate`
* `scim.user.upsert`
* `scim.user.deactivate`
* `user.sso.provision`

## Evidence To Capture

Capture per test org:

* Sign-in flow recording (email-first -> final destination)
* Response/error screenshots for blocked flows
* SCIM deprovision/reactivation results
* Audit log entries for the action list above


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xdbx.gitbook.io/axon/task-guides/validate-identifier-first-sso-and-scim.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
