Directory Integration
Connect your identity provider (Okta or Microsoft Entra ID / Azure AD) to automatically enrich your Shadow AI client records with org-directory attributes — department, job title, and manager. This lets you slice AI-tool usage by team, attribute activity to the right people, and apply policy by org unit.
Enrichment only. The directory sync never creates or deletes Shadow AI clients. It only updates attributes on clients you've already enrolled, matched by identity (email by default). Your directory is never modified.
How it works
- You connect your IdP once with read-only credentials.
- On a schedule (and on demand), the platform pulls your directory users in the background.
- Each directory user is matched to an enrolled Shadow AI client by a join key (email by default).
- Matching client rows are updated with the user's department, job title, and manager.
The sync runs entirely in the background and is built for large tenants — users are streamed page-by-page and the platform paces itself against your IdP's rate limits, so syncing tens or hundreds of thousands of users won't time out or get throttled.
Prerequisites
- You're an Organization Owner or AI Steward (required to manage directory integrations).
- Shadow AI is deployed and you have enrolled clients (browser extension / desktop agent) reporting in.
- Admin access to your Okta or Entra ID tenant to create read-only credentials.
Connect Okta
Create a read-only API token in Okta
In the Okta Admin Console, go to Security → API → Tokens → Create Token. Create the token while signed in as a read-only administrator (the token inherits that admin's permissions — read-only is sufficient and recommended). Copy the token value — Okta shows it only once.
Open the Directory Integration settings
In AgenticAnts, go to Shadow AI → Directory Integration → Connect Okta.
Enter your credentials
| Field | Value |
|---|---|
| Tenant URL | https://your-org.okta.com (no trailing slash, no /api/v1) |
| API token | The token you just created |
Test the connection
Click Test connection. A green confirmation means the credentials and URL are valid.
Save & sync
Click Save & sync. Credentials are encrypted at rest and the first sync starts in the background.
Connect Microsoft Entra ID (Azure AD)
Register an application
In the Azure portal: Microsoft Entra ID → App registrations → New registration. Give it a name and register. Note the Directory (tenant) ID and Application (client) ID from the Overview page.
Add application permissions
Go to API permissions → Add a permission → Microsoft Graph → Application permissions and add:
User.Read.AllDirectory.Read.All
These must be Application permissions (not Delegated) — the integration uses app-only (client-credentials) auth. After adding them, click "Grant admin consent for <your tenant>". Each permission's Status must turn green ("Granted"); until consent is granted they have no effect.
Create a client secret
Go to Certificates & secrets → Client secrets → New client secret. Copy the secret Value immediately (not the Secret ID — the Value is what's used for authentication, and it's shown only once).
Connect in AgenticAnts
Go to Shadow AI → Directory Integration → Connect Azure AD / Entra ID and enter:
| Field | Value |
|---|---|
| Directory (tenant) ID | e.g. 00000000-0000-0000-0000-000000000000 |
| Application (client) ID | from the app registration |
| Client secret | the secret Value |
Test, then Save & sync
Click Test connection, then Save & sync.
Identity mapping (how users are matched)
By default, a directory user is matched to a Shadow AI client on email (case-insensitive). For most setups this is all you need — leave Identity mapping (advanced) turned off.
Turn on Identity mapping (advanced) only if your enrolled clients don't carry an email. You can then pick the join key on each side:
- From your enrolled clients: email, login/username, UPN, employee ID, or full name.
- From your IdP: the corresponding directory attribute.
Avoid name-based join keys. Full name / display name are not unique — two people can share a name, and a name match can enrich the wrong client. Always prefer email, UPN, login, or employee ID when available.
Test mapping before you sync
Click Test mapping to preview, against a sample of your directory, how many enrolled clients would match your chosen key — e.g. "920 of 1,000 enrolled clients would match (92%)" — plus a few examples that didn't match on each side. Use this to validate your join key before running a full sync.
Entra ID users without a mailbox: if a directory user has no mail value, the email match falls back to the user's userPrincipalName (UPN). Make sure your enrolled clients' email matches the UPN in that case, and keep advanced mapping off.
Sync schedule
Set Sync every to control how often the directory re-syncs in the background:
| Option | When to use |
|---|---|
| 1 hour | You want directory changes reflected quickly |
| 24 hours (default) | Recommended for large tenants — gentlest on your IdP |
A background scheduler checks every few minutes and runs any integration whose interval has elapsed since its last sync. You can also run a sync at any time with Sync now — it runs in the background and the page updates with the result shortly after.
What gets synced
For each matched client, the sync updates (only when the IdP provides a value — it never blanks an existing value):
- Department
- Job title
- Manager
- Full name
It also records the directory source and the directory user ID on the client for traceability. Sync results (users fetched, updated, skipped) and a history of runs are visible on the integration card.
Managing the integration
- Sync now — run an on-demand background sync.
- Sync history — view recent runs and their status.
- Pause / Resume — pause scheduled syncs (manual Sync now still works while paused).
- Disconnect — remove the integration. Existing department/title data already written to clients is kept; future syncs stop.
Troubleshooting
"0 of N enrolled clients would match"
The join key isn't lining up. Check:
- Are you on the right key? Turn Identity mapping (advanced) off to use the default email match. Avoid name-based keys.
- Do the values actually match? Compare an IdP user's email/UPN with your enrolled client's email. For Entra users without a mailbox, the client's email must equal the UPN.
- Stale preview. If you just enrolled clients or changed mapping, re-run Test mapping — it's a point-in-time snapshot.
Entra ID: Authorization_RequestDenied (403)
The app registration is missing permissions or consent. Confirm User.Read.All and Directory.Read.All are added as Application permissions and show "Granted" (green) after clicking Grant admin consent.
Scheduled sync doesn't seem to run
The integration only syncs when its interval has elapsed. If it synced recently and you're on a 24-hour cadence, the next run is up to 24 hours away — that's expected. Use Sync now to run immediately, or set Sync every to 1 hour.
Some users didn't get enriched
- The user has no matching enrolled client (you can only enrich clients that exist).
- The IdP user is missing the join attribute (e.g. an external/guest account with no email).
Security
- Credentials are encrypted at rest and never shown again after saving.
- The integration uses read-only access to your directory and never modifies it.
- Use a read-only admin token (Okta) or only the read application permissions above (Entra ID) — least privilege.
- Rotate the API token / client secret periodically per your security policy.