← Back to guides

Okta Username Discrepancy Audit

Daily-scheduled Okta Workflow that detects email/username mismatches on Okta profiles and username/UPN drift in downstream app assignments, logs each to a table, and emails a summary.

Okta Workflows Audit

Flopack file

Import this directly into Okta Workflows. Creates 3 flows, 1 table, and 2 connection placeholders.

↓ Download .flopack

Why this exists

Okta user profiles pass a username variable into each assigned application. When that app-user userName is set equal to the account username (the usual default), it stays in sync. But if you change the username on an Okta profile, Okta does not cascade the change into each existing application assignment. Those have to be re-synced manually, and any downstream app that uses username as the UPN will drift.

This workflow catches two kinds of drift:

Architecture

Three flows, one table, two connections.

Flow 1 — Main (Scheduled, daily 7am ET)

Scheduled Trigger List Users with Search For Each (calls Helper 1)
Search Rows (today's mismatches) Length Continue If (> 0) Compose Send Email

Flow 2 — Helper: Check User Discrepancies

Callable (User ID) Read User Compare (email vs login) If/Else Create Row
List Apps Assigned to User For Each (calls Helper 2)

Flow 3 — Helper: Check App UPN

Callable (User ID, Email, Okta Username, App Name, App User Name) Compare If/Else Create Row

Table — Username Discrepancies

ColumnTypePurpose
Okta User IDTextOkta user.id
EmailTextprofile.email
Okta UsernameTextprofile.login
App NameTextApp label (empty for email mismatches)
App UsernameTextApp assignment userName (empty for email mismatches)
Mismatch TypeTextemail_vs_username or username_vs_upn
Detected AtDateRun timestamp

Setup — one-time

1 Import the flopack

In Okta Workflows console: File → Import, select username-discrepancy-audit.flopack. This creates a folder named Username Discrepancy Audit with the 3 flows and the table.

2 Map the connections

Two connection placeholders were created:

  • Okta Connection — map to your existing Okta connection (or create one with an Okta API token from Security → API → Tokens). Token must belong to a super admin or a read-only admin with user/app-user read access.
  • Gmail Notifications — map to a Gmail connection with the inbox that should send the summary.

If you want Outlook/Office 365 instead of Gmail, delete the Send Email card and drop in Office 365 Mail → Send Email.

3 Wire the card inputs & outputs

The flopack intentionally ships connector cards with empty input pins — Okta populates the correct pin schemas automatically when you open the flow in the editor. Drag outputs into inputs as follows.

Main flow

  • List Users with Search: Search status eq "ACTIVE" (or broader if you want to catch suspended accounts). Leave Limit at 200 per page.
  • For Each: Set List to the List Users output. Set Flow to Helper - Check User Discrepancies. Map the user's id into the helper's User ID input.
  • Search Rows: Point at the Username Discrepancies table. Filter: Detected At >= today_start (use the Now card subtracted by 24h, or a date-truncated value).
  • Length: Input = Search Rows output list.
  • Continue If: Length > 0.
  • Compose: Build the body. Example template:
    Username discrepancy audit - {{count}} issue(s) detected today.
    
    Full details in the Username Discrepancies table:
    https://your-org.workflows.oktapreview.com/ ...
  • Send Email: To = your alert address. Subject = Okta username drift: {{count}} issue(s). Body = Compose output.

Helper 1 — Check User Discrepancies

  • Read User: User ID = callable input.
  • Compare: Read User → profile.email vs Read User → profile.login. Operator: Does Not Equal.
  • If/Else: Condition = Compare output.
    • True branchCreate Row into Username Discrepancies with Okta User ID, Email, Okta Username populated. Leave App Name / App Username empty. Mismatch Type = email_vs_username. Detected At = Now.
  • List Applications Assigned to User: User ID = callable input.
  • For Each (app): List = List Apps output. Flow = Helper - Check App UPN. Map:
    • User ID ← callable User ID
    • Email ← Read User profile.email
    • Okta Username ← Read User profile.login
    • App Name ← loop item label
    • App User Name ← loop item credentials.userName

Helper 2 — Check App UPN

  • Compare: Okta Username vs App User Name. Operator: Does Not Equal.
  • If/Else → True branch → Create Row: All five callable inputs into the corresponding columns. Mismatch Type = username_vs_upn. Detected At = Now.
4 Confirm the schedule

Main flow ships scheduled for 07:00 America/New_York daily. Open the flow → Schedule tab to change time, cadence, or timezone.

Tip: First run can be heavy on large tenants. Consider a weekend 2am run for the initial backfill so the table shows existing drift, then move to a daily cadence.
5 Turn on the flows

Toggle each flow to ON (top-right of the flow editor). Helpers must be on or For Each calls will fail.

6 Test it
  1. In the Main flow, click Save & run.
  2. Watch the execution history. Expect one helper invocation per active user.
  3. Open the Username Discrepancies table — rows should appear for every current mismatch.
  4. Confirm the summary email lands in your alert inbox.

Tuning & known edges

Fixing drift (follow-up)

This workflow detects; it doesn't auto-fix, by design — UPN changes can break sessions and downstream SSO. To remediate a username_vs_upn row:

  1. In Okta admin: Applications → [app] → Assignments → [user] → edit, update the User Name field to match the Okta login.
  2. If the app is SCIM-provisioned, a re-sync will push the new UPN to the downstream app.
  3. If the app uses SWA or federated SSO without SCIM, coordinate with the app owner before changing the UPN — the downstream account may need renaming too.