Sheet POR-08 — Identity Manual
Identity Migration
Migration planning, cutover readiness, inventory discipline, and the identity translation work needed to leave an incumbent cleanly.
Scope
Moving identity providers is usually where hidden complexity becomes visible. This public guide keeps the planning, risk, and cutover guidance from the deeper manual without exposing private migration interfaces or implementation mechanics.
Access
Requirements:
- active tenant context
portal.migrations.viewto inspect workspaces and sourcesportal.migrations.manageto create workspaces, sources, cutover plans, previews, applies, OCM acknowledgements, and post-cutover evidence updates
Scope rules:
- operator-tenant sessions may manage migration workspaces across customer tenants
- customer tenant sessions may only access their own tenant path
guest_accessandsupport_accesscontexts are denied because migration state requires membership-backed tenant context
Current Shipped Scope
- one durable migration workspace per tenant
- two workspace modes:
first_run_adoptionmerge_into_existing- durable source-connection records for Okta, Entra, generic SCIM 2.0, and CSV upload
- encrypted-at-rest source secret storage
- audit records for workspace and source creation
- read-only inventory collection for one configured source at a time
- durable inventory snapshots, normalized inventory items, and page-level raw evidence metadata
- snapshot list, latest, and detail read routes
- durable assessment runs bound to one completed inventory snapshot
- durable per-item compatibility classifications for the shipped
M2inventory item set - durable bounded OCM and unavoidable-change impact rows where the classifier can support them honestly
- durable merge-decision rows for truthfully detected live-tenant overlaps in
merge_into_existing - assessment list, latest, and detail read routes
- merge-decision list and resolve routes
- OCM acknowledgement routes
- preview-handoff readiness state derived from merge and OCM review completion
- durable cutover-plan rollback guidance and post-cutover completion evidence
- cutover-plan create, list, detail, preview, and apply routes
- cutover-evidence read and update routes
- preview-token-protected apply for the bounded
first_run_adoptionandmerge_into_existingcontracts - truthful execution readback for created, blocked, skipped, manual-follow-up, and failed steps
- operator-facing post-cutover handoff criteria, rollback notes, and communications evidence in the Portal workspace
- one dedicated Portal route and nav entry for migration tooling under
Configuration -> Migration Tooling
Current shipped cutover automation remains intentionally bounded:
- only workspaces whose latest assessment handoff is already
ready_for_future_previewmay create, preview, or apply cutover plans - merge mode consumes explicit persisted merge decisions and never silently overwrites the matched Portal runtime row
- apply only creates the supportable targets described below
Use The Portal UI
Operators can now use the first tenant-scoped Portal workspace for migration tooling:
- open
Configuration -> Migration Tooling - the page loads the first workspace for the active tenant plus its sources, latest snapshot, latest assessment, and any existing cutover plan bound to that assessment
- the workspace exposes the latest inventory snapshot counts, collected domains, source-record counts, collection warnings, paginated inventory and assessment item tables (default 25 rows per page, with 10/25/50/100 options, persisted to the operator’s local profile), the current preview-handoff gate, OCM acknowledgement action, plan summary counts, step-level dispositions, preview state, apply-only outputs, and post-cutover evidence or handoff notes
- after inventory collection completes, run the snapshot assessment before expecting cutover-plan data to appear; inventory collection runs in the background (the Run Inventory button enqueues it and the UI polls the latest snapshot until it completes or fails), while the assessment is a separate read-only step bound to the completed snapshot
The UI also supports the setup path:
- the empty state can create a workspace with
first_run_adoptionormerge_into_existing - the workspace panel can add Okta, Entra, generic SCIM 2.0, or CSV sources
- CSV onboarding reads the selected file header, requires an email-column mapping, creates the source with
connection_config.column_mapping, and uploads the file immediately after source creation
Migration Capability Status
Before creating or collecting from sources, check the capability status band on the relevant workflow or call:
The response shows the safe deployment posture for each source inventory, enrichment, and secret-import lane. It includes the gate key, enabled state, environment variable name, default state, scope, operator label, and disabled detail. It does not expose configured values, API tokens, password hashes, TOTP seeds, or source secrets.
Important launch gates:
PORTAL_GENERIC_SCIM_INVENTORY_ENABLED=trueis required before a generic SCIM source can collect inventory.PORTAL_CSV_INVENTORY_ENABLED=trueis required before a CSV source can collect inventory.PORTAL_OKTA_USER_INVENTORY_ENABLED=trueenables Okta user enrichment;PORTAL_OKTA_FACTOR_INVENTORY_ENABLED=trueenables Okta factor enrichment.PORTAL_ENTRA_USER_INVENTORY_ENABLED=trueenables Entra user enrichment;PORTAL_ENTRA_AUTH_METHOD_INVENTORY_ENABLED=trueenables Entra authentication-method enrichment.PORTAL_PASSWORD_HASH_IMPORT_ENABLED=trueis required before an Okta source withconnection_config.import_passwords=truecan authenticate migrated password hashes.
Source creation is still allowed while a gate is disabled so operators can stage a cutover. Inventory fails closed for disabled primary lanes and persists a failed snapshot with migration_inventory_collector_disabled until the deployment gate is enabled.
Disabled enrichment lanes (users, memberships, factors/auth methods) do not fail the snapshot — collection continues and the snapshot carries a warning naming the disabled gate. Only disabled primary lanes fail closed.
Browser Verification Gate
The live dev-browser migration smoke is now a read-only authenticated proof for the real the relevant workflow product state. It does not swap migration endpoints onto route-fulfilled fixtures after login, and it does not claim preview/apply/cancel side-effect coverage.
Supported commands:
The direct Playwright invocation self-skips unless is present.
The wrapper sources docs/ux/.creds and requires
plus . Run it only against the sanctioned dev-VPS
environment for migration-tooling evidence capture.
Mutating launch evidence is a separate explicit lane:
Artifacts land under
${PORTAL_AUDIT_RUN_DIR}/artifacts/${PORTAL_AUDIT_JOB_ID}/${PORTAL_AUDIT_JOURNEY_SLUG}/.
tenant id, workspace/source/assessment/plan identifiers, and a note that the
proof is real authenticated product state only. The wrapper also writes
for the relevant workflow when the live proof succeeds. See
for the schema.
Create A Workspace
Create the tenant workspace:
Request body:
Rules:
- each tenant can have only one active workspace in this slice
- new workspaces start in
draft
List or read the workspace:
Add A Source Connection
Create a source under the workspace:
Current supported contracts:
Okta
Entra
Generic SCIM 2.0
scim_filter is optional.
CSV
CSV sources require connection_config.column_mapping at creation time because there is no later source-update route in this surface. The email mapping is required. After creation, upload the CSV bytes:
Rules:
- Okta currently supports only
connection_mode=api_token - SCIM currently supports only
connection_mode=bearer_token - CSV currently supports only
connection_mode=csv_upload - source names must be unique within one workspace
- archived workspaces cannot accept new sources
List or read sources:
Secret Handling
Portal stores source credentials encrypted at rest and never returns raw secret material in list or detail responses.
Responses expose only:
- connection metadata
- source status
Portal now uses these secrets only for read-only inventory collection against the configured source. The inventory slice does not mutate Portal runtime or the incumbent platform.
Operational note:
- the configured Okta token must be able to read applications, groups, identity providers, routing rules, policies, domains, and assignment targets
- Okta user inventory requires
PORTAL_OKTA_USER_INVENTORY_ENABLED=true; Okta factor inventory requiresPORTAL_OKTA_FACTOR_INVENTORY_ENABLED=true - Okta password-hash import requires both
connection_config.import_passwords=trueon the source andPORTAL_PASSWORD_HASH_IMPORT_ENABLED=truein deployment - the configured Entra application must be able to read applications, service principals, domains, groups, conditional-access policies, and app-role assignments
- Entra user inventory requires
PORTAL_ENTRA_USER_INVENTORY_ENABLED=true; Entra auth-method inventory requiresPORTAL_ENTRA_AUTH_METHOD_INVENTORY_ENABLED=true - generic SCIM inventory requires
PORTAL_GENERIC_SCIM_INVENTORY_ENABLED=true - CSV inventory requires
PORTAL_CSV_INVENTORY_ENABLED=true - if a configured source type’s primary collector lane is disabled, the inventory snapshot is marked
failed; Portal does not report a disabled source as a successful empty run - optional Okta user and factor enrichment lanes are skipped with warnings when their feature flags are disabled, so a completed application, group, policy, domain, and assignment snapshot can still feed assessment and cutover review
Collect An Inventory Snapshot
Trigger a source snapshot:
Current read-only source domains:
Okta
Entra
- application registrations from Microsoft Graph the relevant workflow
- service principals from Microsoft Graph the relevant workflow
- verified domains from Microsoft Graph the relevant workflow
- groups from Microsoft Graph the relevant workflow
- conditional-access policies from Microsoft Graph the relevant workflow
- service-principal app-role assignments from Microsoft Graph the relevant workflow
- users from Microsoft Graph the relevant workflow
- user authentication methods from Microsoft Graph the relevant workflow
Generic SCIM 2.0
- users from the relevant workflow
- groups from the relevant workflow
CSV
csv_userrows from the uploaded CSV blob using the source’s persistedcolumn_mapping
Current response shape includes:
- snapshot status and timestamps
- source-type summary counts (
item_count,evidence_count, domain breakdown, drift summary) - collected source-record counts for each domain processed
- collection warnings
Read back snapshots:
Inspect normalized inventory items page by page:
- response is
{items, total, limit, offset}ordered by(item_domain, display_name, id) - the Portal UI consumes this endpoint for the inventory item table; operators choosing a different page size persist that choice locally so the next page they open uses the same size
Important contract notes:
- the Portal UI shows the completed snapshot summary and warnings immediately after collection; assessment and cutover panels stay empty until the operator runs a compatibility assessment for that snapshot
- only one collection run may be active per source at a time
- archived workspaces and non-
configuredsources cannot collect inventory - snapshot detail exposes summary counts and gate metadata only; normalized item rows and raw API evidence pages are accessed through the paginated item-list route above (a dedicated raw-evidence download route is not yet shipped)
Run A Compatibility Assessment
Trigger a snapshot-scoped assessment:
R-0130: assessment runs in the background. The POST returns 202 Accepted with the
queued run (assessment_status='queued'); the Run Assessment button in the UI does the
same enqueue and then polls the assessment GET endpoints until the run reaches
Gate panel and re-run without acknowledging anything. A queued or in-progress
Read back assessment history:
Assessment runs are durable and rerunnable for the same completed inventory snapshot. Portal keeps historical runs instead of overwriting the prior result.
Current compatibility classes:
native_importimport_with_approximationvisibility_onlymanual_rebuild_requiredblocked
Current assessment response detail includes:
- assessment status and timestamps
- classifier version
- summary counts (
item_assessment_count,ocm_impact_count, gate state) - bounded OCM impact rows with audience, severity, summary, and related item references
- merge-decision rows for assessment items that truthfully collide with live tenant state in merge mode
Inspect per-item compatibility classifications page by page:
- response is
{items, total, limit, offset}ordered by(created_at, id)to match classifier insertion order - the Portal UI consumes this endpoint for the assessment item table; page-size selection persists per operator browser
Additional review routes now exist for completed assessment runs:
Important contract notes:
- assessment is read-only in this slice and does not mutate live Portal runtime
- only completed inventory snapshots may be assessed
- archived workspaces and non-
configuredsources cannot run assessment - only one
assessingrun may be active per snapshot at a time - direct-user assignment rows stay blocked until later identity-link and merge-decision work exists
- merge-decision review only applies to
merge_into_existingworkspaces map_to_existingresolution must point at one of the persistedmatched_resourcesfor that assessment run- OCM acknowledgement updates the existing persisted impact rows; it does not create a second acknowledgement object
Work With A First-Run Cutover Plan
Current cutover-plan routes:
Create request body:
Current rules:
- cutover plans are bound to one workspace, one source, one inventory snapshot, and one completed assessment run
- both
first_run_adoptionandmerge_into_existingworkspaces are eligible in this tranche - the referenced assessment must already be
completed - the assessment handoff must already be
ready_for_future_preview - unacknowledged OCM impacts or other live handoff blockers still reject create, preview, and apply
- apply requires the current matching
preview_tokenfrom the latest preview response - cancellation does not roll back already-applied runtime changes; review evidence after the run settles
- generated OIDC client secrets are revealed exactly once through a manage-permission action on the post-apply screen. Copy and store them immediately - Portal cannot retrieve them again, and unrevealed secrets are auto-purged after 24 hours by default
Check group memberships and sign-in before you cut over
Two things decide whether day one after cutover works. Read both off the plan preview before you apply.
1. Are memberships being migrated? Look for create_group_membership steps. If you see
manual_group_membership_dependency instead, the group or the member user is not staged by this
plan — usually because the group already exists in the tenant under a different source
identity, or the user is out of the snapshot. Those users will land in no group, and any access
you were relying on group->application assignments to grant will not exist. Fix the plan, do not
apply and hope.
If a membership is already live in the tenant, the step shows as
skip_existing_group_membership — that is correct and expected on a re-plan.
2. How will each user sign in? Every create_portal_user step carries a
credential_bootstrap value:
-
imported_password_hash— the user keeps their existing password. This only happens on Okta sources withimport_passwordsenabled and a hash actually present in the export. -
invite_email_required— the user cannot bring their password over. Okta does not expose password hashes on user reads, and Entra cloud-only accounts cannot export them at all, so this is the normal case for almost every migration. On apply, Portal emails that user a claim link so they can set a Portal password themselves.
log_only instead of sent, which means the invites exist but nothing left the box and your
users have no link. Check the credential-bootstrap counts in the apply result and re-send from
the user-invite screen for anything that did not report sent.
Plan your cutover comms around this: users are getting a “set your password” email on cutover day, not signing in with what they had. That is a platform limitation of the source directory, not something Portal can work around.
Recover From Cancelled Or Partially-Successful Apply
Recovery rules:
- cancellation stops future steps only; it does not roll back steps that already executed
- Portal may already have created users, groups, group-targeted assignments, upstream providers, routing rules, or tenant OIDC clients before the run stopped
- review the Evidence panel first, then download the failed-step CSV if any rows failed
- treat generated OIDC client secrets as one-time material; if you did not capture them before the reveal window closed, rotate or recreate the client instead of expecting Portal to recover them
Recommended operator workflow:
- inspect the Evidence panel and note applied, failed, skipped, and outstanding follow-up counts
- download the failed-step CSV when failures exist and attach it to the change or incident record
- review rollback notes and record tenant-specific cleanup instructions before making more runtime changes
- verify whether imported Portal users, transferred MFA material, created upstream providers, routing rules, groups, or assignments should stay in place or be manually reverted
- if OIDC clients were created, reveal and store the one-time secret immediately; if the reveal window already expired, rotate or recreate the client
- once tenant state is understood and any manual cleanup is complete, generate a new preview token and re-run the plan instead of reusing stale preview state
Retention And Manual Cleanup
Portal now enforces bounded retention for durable migration records and exposes one operator-controlled purge surface for obsolete inventory snapshots.
Retention defaults:
- completed or failed inventory snapshots: 90 days
- completed or failed assessment runs: 90 days
- terminal apply-run rows: 365 days
- unrevealed one-time apply outputs such as generated OIDC client secrets: 24 hours by default
Cleanup behavior:
CleanupWorkerevaluates migration retention on the same cadence as the rest ofcore.cleanup.run_all_cleanup- retention never deletes in-progress assessment runs or snapshots referenced by active
draftorpreviewedcutover plans - terminal apply-run rows are retained longer than snapshots and assessments because they are part of the execution audit trail
- one-time apply outputs are purged separately from the apply-run row because the secret material should disappear much sooner than the audit record
Manual purge route:
Manual purge rules:
- requires
portal.migrations.manage - rejects collecting snapshots
- rejects snapshots with an in-progress assessment
- rejects snapshots referenced by an active
draftorpreviewedcutover plan - emits
migration.inventory.snapshot_purgedin the audit trail
Current supportable auto-create contracts:
- upstream SAML providers when evidence includes the entity ID, SSO URL, and signing certificate Portal needs for truthful creation
- simple domain-based federation routing rules that depend on a provider created in the same execution run or explicitly mapped to an existing provider through merge review
- tenant-scoped groups
- tenant-owned application OIDC applications recreated from compatible Okta OIDC application evidence or compatible Entra application-registration evidence
- group-targeted tenant app assignments when the referenced tenant app and group both resolve through same-plan create or explicit merge mapping
Current supportable merge-mode bindings:
map_to_existingfor overlapped upstream providers, routing rules, tenant-owned applications, and tenant-scoped groups- net-new safe creates for supportable contracts when no live overlap exists
- group-targeted tenant app assignment creation when the app and group dependencies resolve through same-plan create or
map_to_existing
Current non-auto-created outcomes:
- direct-user app assignments remain blocked
- Entra OIDC-style service principals remain
manual_follow_upbecause the collected evidence does not yet distinguish whether Portal should create a confidential or public client - auth-policy approximation rows remain
manual_follow_upbecause the current cutover lane does not collapse per-rule approximation into one tenant-wide auth-policy mutation automatically - overlap-driven
create_newdecisions stay explicit follow-up when the persisted merge-review state does not carry enough rename or alternate target-shape data to avoid the captured collision safely
Work With Post-Cutover Evidence
Current evidence routes:
Current evidence response includes:
- the current cutover plan detail
- the latest execution run when apply has been attempted
- latest apply-run identifiers, cancellation metadata, rollback availability, latest rollback run, and rollback summary
- durable rollback guidance stored on the cutover plan
- durable post-cutover completion evidence stored on the cutover plan
- computed handoff criteria derived from the current plan and execution record
Current operator-entered rollback fields:
- rollback summary
- rollback owner
- rollback steps
Current operator-entered completion evidence fields:
- communications-complete flag
- communications summary
- artifact or ticket reference
- manual validation summary
- follow-up-reviewed flag
- follow-up summary
Current handoff criteria are truthful to the bounded cutover contract:
- Portal checks whether an execution record exists
- Portal checks whether rollback guidance is recorded
- Portal checks whether communications completion evidence is recorded
- Portal checks whether outstanding follow-up has been reviewed
- Portal does not pretend blocked or manual-follow-up rows disappeared; it only makes them explicit
Current important limits:
- automated rollback is bounded to safe Portal-created targets from one terminal apply run; manual, skipped, failed, or ambiguous items still require operator recovery
- Portal does not run automated post-cutover provider sign-in probes or downstream app launch probes in this slice
- manual validation notes are operator-entered evidence, not machine-collected health checks
Keep Inventory Fresh During Coexistence
Use scheduled inventory resync when the incumbent IdP and Portal will coexist for more than a short change window.
- Open the migration source.
- Enable inventory resync and choose an interval between 15 minutes and 7 days.
- Use Run immediately when you need a fresh scheduled snapshot before the next normal interval.
- Watch the source resync status:
-
next_run_atis the next worker due time. -last_enqueued_atis the last scheduled snapshot enqueue. -is_stalemeans the latest completed inventory is older than the configured interval. -last_errorshows scheduler failures such as deferral because another collection is already queued or collecting. - After a scheduled snapshot completes, inspect
drift_summary. If added or removed item counts are non-zero, rerun assessment and rebuild or preview the cutover plan before applying.
Roll Back A Terminal Apply Run
Automated rollback is available only for one terminal apply run with a linked execution run. It is designed as a safety-controlled fallback, not a force-delete tool.
- Review the preview counts and item dispositions. Items classified as
manual_required,skip, or unsafe are not auto-deleted. - Treat
succeededas fully reverted; the cutover plan moves torolled_back. - Treat
partial_successorfailedas an operator recovery state. Use the progress response, failed item reasons, lifecycle events, and cutover evidence to complete manual cleanup.
Rollback safety boundaries:
- mapped existing resources are skipped
- groups with members require manual cleanup
- users with post-apply login activity require manual cleanup
- cross-tenant or missing targets are never deleted
- ambiguous runtime state is failed or marked manual-required instead of guessed
Rollback actions are audited as previewed, enqueued, item reverted, item skipped, item manual-required, item failed, completed, or failed.
Staged Rollout, Coexistence, And Fallback
Use first_run_adoption when Portal is becoming the tenant authority after evidence review. Use merge_into_existing when Portal already has runtime resources and incumbent objects must be bound explicitly through merge decisions.
Recommended decision points:
- Enable scheduled resync during coexistence so source evidence does not silently age.
- Rerun assessment after meaningful drift appears.
- Resolve merge collisions before preview.
- Preview immediately before apply; stale preview tokens are intentionally rejected.
- During apply, use cancellation only when you need to stop future steps at safe worker boundaries.
- After apply, inspect progress, errors CSV, rollback availability, lifecycle events, and handoff evidence.
- Use automated rollback for safe Portal-created resources; use manual recovery for unsupported or ambiguous items.
Fallback limits:
- Portal does not deep-overwrite existing resources in merge mode.
- Portal does not import direct-user app assignments automatically.
- Portal does not run automated post-cutover sign-in or downstream-app launch probes yet.
- Portal does not provide a hidden force-link, force-delete, or cross-tenant cleanup bypass.
Status Behavior
Workspace lifecycle in the shipped slice:
draftwhen created with no active sourcesready_for_inventoryonce at least one non-archived source existsarchivedreserved for later lifecycle work
Source lifecycle in the shipped slice:
configuredarchived
Inventory snapshot lifecycle in M2:
queuedafter manual enqueue or scheduled resync enqueuecollectingwhile the source read is in flightcompletedafter the snapshot, items, evidence rows, and any scheduled drift summary are persistedfailedwhen the external source rejects the request or returns unusable data
Assessment lifecycle in shipped M3:
queuedafter Portal accepts the assessment request and before the worker claims itassessingwhile the worker-owned classifier is evaluating one completed snapshotcompletedafter item assessments, OCM impacts, merge decisions, and readiness summary state are persistedfailedwhen the classifier cannot finish or the persistence step cannot complete cleanly
Cutover-plan lifecycle in shipped M4 + W5-T08 background apply:
draftafter plan creation or rebuildpreviewedafter a successful preview response mints the current preview token; plan stayspreviewedwhile the background apply run is in progressappliedwhen every planned step mutates successfullyapplied_with_follow_upwhen the execution succeeds for supportable targets but still includes blocked, skipped, or manual-follow-up stepsfailedwhen a planned mutation step fails during executionrolled_backwhen a rollback run reverts every safe rollback item for the terminal apply run
Background apply run lifecycle (migration_apply_run.status):
queued— run accepted, worker has not yet claimed itin_progress— worker is processing steps; lease refreshed automatically every ~20 secondscancelling— a cancellation request was accepted and the worker has not yet reached a safe stop boundarysucceeded— all steps applied with no failures and no skipspartial_success— at least one step succeeded; one or more steps failed (checkerrors_by_cause)failed— zero steps succeededcancelled— the worker observed the cancellation request and stopped future steps
Rollback run lifecycle (migration_rollback_run.status):
queued— rollback accepted, worker has not claimed itin_progress— worker is processing rollback itemssucceeded— every rollback item was reverted or safely skipped and the plan moved torolled_backpartial_success— at least one item reverted, but one or more items require manual recovery or failedfailed— no items reverted or the worker could not complete the rollback run
Cutover-step lifecycle in shipped M4:
plannedmanual_follow_upblockedskippedappliedfailed
Execution-run lifecycle in shipped M4:
startedcompletedcompleted_with_follow_upfailedcancelled
On successful collection, Portal updates migration_sources.last_inventory_at.
Workspace summary currently tracks:
source_countconfigured_source_countocm_statusocm_review_statusunavoidable_change_countassessment_statuslatest_assessment_started_atlatest_assessment_completed_atmerge_review_statuspending_merge_decision_countresolved_merge_decision_countpreview_handoff_statuspreview_handoff_blockers
Audit
Portal emits audit records for state-changing actions:
migration.workspace.createdmigration.source.createdmigration.source.inventory_resync_updatedmigration.inventory.collection_enqueuedmigration.inventory.scheduled_collection_enqueuedmigration.inventory.scheduled_collection_deferredmigration.inventory.collectedmigration.inventory.collection_failedmigration.assessment.completedmigration.assessment.failedmigration.merge_decision.resolvedmigration.ocm_impacts.acknowledgedmigration.cutover_plan.createdmigration.cutover_plan.previewedmigration.cutover_plan.appliedmigration.cutover_evidence.updatedmigration.cutover_step.appliedmigration.cutover_step.blockedmigration.cutover_step.failedmigration.cutover_step.manual_follow_upmigration.cutover_step.skippedmigration.cutover.apply_cancel_requestedmigration.cutover.apply_cancelledmigration.cutover.apply_failedmigration.cutover.ephemeral_outputs_revealed— manage-permission caller reveals one-time apply outputsmigration.cutover.ephemeral_outputs_purged— expired one-time apply outputs are purged without exposing raw secretsmigration.cutover.rollback_previewedmigration.cutover.rollback_enqueuedmigration.cutover.rollback_item.revertedmigration.cutover.rollback_item.skippedmigration.cutover.rollback_item.manual_requiredmigration.cutover.rollback_item.failedmigration.cutover.rollback_completedmigration.cutover.rollback_failedmigration.user.created— background worker creates a newPortalUserrow from imported inventorymigration.user.merged— background worker matches an existingPortalUserby email during applymigration.mfa.totp_transferred— TOTP secret installed into theusersrow TOTP storage for the imported usermigration.mfa.totp_skipped— TOTP transfer skipped because the secret seed was unavailable or missing from the factor payloadmigration.mfa.re_enrollment_required— durable migration lifecycle event recorded for a push, WebAuthn, or SMS factor that cannot be transferredmigration.lifecycle_event.resolved— operator marks a pending lifecycle event resolved after confirming the user completed MFA re-enrollmentmigration.lifecycle_event.superseded— operator marks a pending lifecycle event superseded when a newer migration decision makes it obsolete
Closing lifecycle events. After confirming that the user has re-enrolled MFA, or determining that the event is obsolete, use the lifecycle events panel (Manage permission required) to close the event. For each pending row, click “Mark resolved” (confirmed re-enrollment) or “Mark superseded” (obsolete). Enter a required resolution note describing the outcome. The action is audited and cannot be undone through the UI. The user-row mfa_provenance field remains the login enforcement signal regardless of the event closure state.
Audit details include the tenant, actor, target resource id, and the non-secret configuration facts relevant to the write.
Launch Boundaries
Portal’s current launch claim for migration tooling is limited to the bounded tenant-scoped workflow documented in this guide: create a workspace, connect a supported source, collect inventory, run assessment, review merge and OCM signals, preview or apply the supportable cutover steps, and capture post-cutover evidence or handoff notes.
Portal does not currently claim full-estate incumbent-platform replacement or one-click migration parity. The following capabilities remain outside the shipped launch boundary and must not be promised as current behavior:
- Full first-run automation for every assessed item type
- Field-by-field overwrite or deep reconcile of existing upstream providers, routing rules, groups, or tenant-owned applications during merge mode
- Direct-user assignment import
- Automated post-cutover provider or downstream application validation probes
- One-click migration across the full incumbent estate