Skip to content

docs: add Microsoft Entra ID setup guide#983

Open
wdawson wants to merge 7 commits into
mainfrom
wils/gro-96-docs-entra-id-setup-guide-user-sources
Open

docs: add Microsoft Entra ID setup guide#983
wdawson wants to merge 7 commits into
mainfrom
wils/gro-96-docs-entra-id-setup-guide-user-sources

Conversation

@wdawson
Copy link
Copy Markdown
Contributor

@wdawson wdawson commented May 27, 2026

Summary

Adds the Microsoft Entra ID per-provider setup guide as the first concrete provider page under /guides/user-sources/. Walks an admin through registering an Entra app for use as an Arcade User Source: app registration, the Arcade redirect URL, the client secret, the openid permission, then a mapping table from Entra labels to the four fields in Arcade's User Source form.

Closes GRO-96. Part of the GRO-75 umbrella.

What landed in this PR

  • New page at app/en/guides/user-sources/microsoft-entra-id/page.mdx (the Entra walkthrough).
  • New light-mode screenshots at public/images/user-sources/microsoft-entra-id/ (app registrations entry, registration form, client secret created, openid API permission).
  • Renamed the User Sources section index nav entry to Overview in app/en/guides/user-sources/_meta.tsx.
  • Glossary plugin (lib/remark-glossary.ts) extended to skip auto-linking on /guides/user-sources/*/page.mdx so Microsoft terms like "account" and "tenant" don't pop misleading Arcade tooltips. The User Sources overview itself stays opted in.
  • Entra / Entra ID added to the Arcade Vale vocabulary.

Audience and structure

The reader is an admin who's never done OIDC before — they trust Arcade to be the auth expert. The page uses only the four terms that appear identically in both products (issuer URL, client ID, client secret, subject claim); plain English everywhere else, with explicit mappings between Entra labels and Arcade fields.

This shape is intentionally a reusable template for the remaining per-provider guides (Okta, Auth0, Stytch, Clerk):

  1. One-paragraph intro
  2. Before you start (required admin role)
  3. Register an app — <Steps> block, action-oriented
  4. Copy these values to Arcade — provider-to-Arcade mapping table
  5. Create the User Source in Arcade (link to overview)
  6. Notes — provider-specific quirks only

Decisions worth flagging

  • Account-type dropdown matches the actual Entra UI (four options: Single tenant only, Multiple Entra ID tenants, Any Entra ID Tenant + Personal Microsoft accounts, Personal accounts only). The page recommends the two workforce-relevant options and explicitly steers readers away from the two personal-account variants, which sit outside the workforce identity model.
  • Multi-tenant issuer URL uses login.microsoftonline.com/organizations/v2.0, not /common/v2.0. common accepts personal Microsoft accounts in addition to work or school; organizations is workforce-only and matches the Multiple Entra ID tenants choice on the form.
  • Subject claim recommends oid with the real reason: sub is unique per app registration (so it doesn't trace back to a directory identity), and oid is durable even if the person's email changes. The Notes section also links to Entra's optional claims docs with the constraint that Arcade can read any claim that lands in the ID token (not access tokens or other types).
  • PKCE is a one-line note: Arcade always uses PKCE, Entra accepts it automatically. Okta's page later gets a dedicated step for the require-PKCE checkbox; Entra has no equivalent toggle.
  • Certificate credentials are explicitly called out as not supported today (matches engineering's current scope).
  • Glossary auto-link exemption applies to all per-provider User Source pages, not just this one — the same collision (account/tenant/realm meaning the provider's concept, not Arcade's) will hit Okta/Auth0/Stytch/Clerk.

Test plan

  • Vale clean on the new page (added Entra / Entra ID to the Arcade vocab)
  • check-meta-keys — all _meta.tsx keys valid
  • pnpm build/en/guides/user-sources/microsoft-entra-id renders in the route table
  • Screenshots captured (light-mode) and wired into the Steps block
  • Glossary plugin no longer wraps Microsoft terms on this page (verified in the Vercel preview)
  • Reviewer to confirm the steps match the current Entra admin center UI
  • Reviewer to confirm the page reads cleanly for a non-OIDC-expert admin

Follow-ups (not in this PR)

  • Dark-mode screenshot variants — light-only for now.
  • The remaining per-provider guides (Okta GRO-95, Auth0 GRO-94, Stytch GRO-97, Clerk GRO-98) follow the same template.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment May 27, 2026 10:52pm

Request Review

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style Review

Found 7 style suggestion(s).

Powered by Vale + Claude

Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
Comment thread app/en/guides/user-sources/microsoft-entra-id/page.mdx Outdated
wdawson and others added 7 commits May 27, 2026 15:50
New page at /guides/user-sources/microsoft-entra-id/ walks through
registering an Entra ID app for use as a User Source: app registration,
redirect URL, client secret, openid permission, then the value mapping
into Arcade's User Source form.

Audience is an admin who isn't an OIDC expert. The page uses only the
four terms shared with Arcade's User Source form (issuer URL, client
ID, client secret, subject claim); plain-English everywhere else, with
explicit mappings between Entra labels and Arcade fields.

Includes:
- single-directory vs any-directory choice framed in plain terms, with
  the corresponding issuer URL variant for each
- recommendation to use `oid` for the subject claim, with the one-line
  reason
- PKCE note (Entra accepts it automatically; no extra setting)
- note that certificate credentials aren't supported today
- TODO screenshot placeholders at the natural spots in the Steps block

Add Entra and Entra ID to the Arcade Vale vocabulary.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… Overview

- Drop spaces around em-dashes (Google.EmDash) in 4 screenshot TODO
  comments and 2 prose spots (Client Secret note, openid permission
  note); rewrote the User.Read sentence with a semicolon for clarity
- Drop the "We'll add certificate support" sentence (Google.We); the
  surrounding sentence already conveys the limitation
- Rename the User Sources section index to "Overview" in the sidebar
  via the user-sources _meta.tsx so the section reads:
    User Sources
      Overview
      Microsoft Entra ID

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The remark-glossary plugin auto-links the first occurrence of any
Arcade glossary term per paragraph. On per-provider User Source pages
(Microsoft Entra ID today, Okta/Auth0/Stytch/Clerk next), terms like
"account" and "tenant" appear constantly in the provider's sense — not
Arcade's — and the resulting tooltips mislead readers.

Exempt /guides/user-sources/*/page.mdx from glossary auto-linking, but
keep the User Sources overview (/guides/user-sources/page.mdx) opted
in, since that page is where the Arcade-specific concepts get defined.

Same path-based skip pattern as the existing /resources/integrations/
exemption.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add an MDX comment to bust Next.js/Vercel's cached MDX compilation for
this page. The Vercel build keeps .next/cache across deploys and didn't
pick up the lib/remark-glossary.ts skip we added in bdf0f46 because the
page source itself hadn't changed.

The comment also documents the exemption inline for future readers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… issuer

The Entra portal's "Supported account types" dropdown lists four
options, with labels different from what this page had:

- Single tenant only — <tenant name>
- Multiple Entra ID tenants
- Any Entra ID Tenant + Personal Microsoft accounts
- Personal accounts only

Update the step to name the two workforce-relevant options exactly as
they appear in the dropdown, and explicitly steer readers away from
the two personal-account variants since they sit outside the workforce
identity model User Sources are designed for.

Also fix the issuer URL recipe: the previous text used
`login.microsoftonline.com/common/v2.0` for the multi-tenant case, but
`common` accepts personal Microsoft accounts in addition to work or
school accounts. For workforce-only multi-tenant, the correct endpoint
is `login.microsoftonline.com/organizations/v2.0`.

Update the trailing "Single-directory recommendation" note to reuse
the new "Single tenant only" terminology.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Add four light-mode screenshots from the Entra admin center to
  public/images/user-sources/microsoft-entra-id/ (app registrations
  list, registration form, client secret value, openid API permission)
  and replace the TODO MDX comments with <Image> elements
- Remove the temporary glossary-cache-bust comment; the glossary plugin
  exemption is documented in lib/remark-glossary.ts
- Drop the fenced code block for the redirect URL; inline code on its
  own line is enough visual emphasis and removes the PLAINTEXT header
- Rewrite the Subject Claim cell to explain the real reason `oid` is
  preferable to `sub` (sub is unique per app registration, so it
  doesn't trace back to a directory identity) and to `email` (`oid` is
  durable even if the address changes)
- Drop the "Single-tenant recommendation" Note; it was disconnected
  from where the choice is actually made
- Add a "Custom subject claims" Note pointing to Entra's optional
  claims docs, with the constraint that Arcade can only read claims
  that land in the ID token

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wdawson wdawson force-pushed the wils/gro-96-docs-entra-id-setup-guide-user-sources branch from cb99398 to c34d209 Compare May 27, 2026 22:51
@wdawson wdawson marked this pull request as ready for review May 27, 2026 22:54
@wdawson wdawson requested review from torresmateo and vfanelle May 28, 2026 18:52
@samkujovich
Copy link
Copy Markdown

Not an expert here so take with a grain of salt -

Reviewed this against the coordinator's User Source / OIDC validation code on
main (not just the docs). One real issue, narrower than it first looked, plus
a minor nit.

🔴 The multi-tenant Issuer URL value won't validate

The "Copy these values to Arcade" table tells admins who pick Multiple Entra
ID tenants
to use:

https://login.microsoftonline.com/organizations/v2.0

That specific value can't be saved or used. Two reasons, both verified:

  1. Create-time (HTTP 422). validate_oidc_issuer fetches
    <issuer>/.well-known/openid-configuration and requires the doc's own
    issuer to match the submitted string byte-for-byte. Entra's
    organizations/v2.0 (and common/v2.0) discovery docs both report their
    issuer as the placeholder https://login.microsoftonline.com/{tenantid}/v2.0
    — so the submitted organizations/v2.0 never matches. The User Source
    won't save.
  2. Runtime. ID-token validation does an exact iss match against the stored
    issuer (JWTClaimsRegistry(iss={"value": user_source.issuer})). Real Entra
    tokens carry https://login.microsoftonline.com/<actual-tenant-guid>/v2.0,
    which wouldn't match organizations/v2.0 either.

Both checks are intentional (exact-match is the secure default, called out in the
code), so this isn't a bug to fix in the engine — it's the issuer value in the
guide that needs to change.

The fix

The account-type choice and the Issuer URL are independent. Whichever account
type the admin picks, the Issuer URL should always be the tenant-specific
form:

https://login.microsoftonline.com/{tenant-id}/v2.0

({tenant-id} = the Directory (tenant) ID on the Overview page.) This is the
shape the coordinator's own Microsoft test fixture uses, and it validates
correctly because the concrete-tenant discovery doc reports a concrete issuer.

Suggest dropping the conditional/organizations row and just instructing the
tenant-specific issuer for both account-type options.

One limitation worth a sentence in Notes

Because Arcade matches iss exactly, a single User Source maps to exactly one
tenant. If an admin picks "Multiple Entra ID tenants" expecting users from many
different orgs to sign in through one User Source, that won't work today — each
tenant issues a distinct iss. Worth stating so multi-tenant-app admins aren't
surprised. (Picking the multi-tenant account type is fine; onboarding arbitrary
tenants through one source is the unsupported part.)

⚪ Minor: "Copy these values" table points to the Overview page

The framing implies all four values live on the app's Overview page, but the
client secret is only visible at creation time. Half a sentence would save a
reader from hunting for it.

✅ Checked and clean

Glossary plugin exemption (overview stays opted-in, provider pages skipped, no
over-broad match on user-sources-* siblings), _meta.tsx keys, internal
anchors (#create-a-user-source, #rotate-the-client-secret), redirect URL
host, openid as the sole required Graph delegated permission, the oid
subject-claim guidance (correct for the tenant-specific issuer), Vale vocab,
and llms.txt.

Copy link
Copy Markdown
Contributor

@vfanelle vfanelle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried creating an Entra account, and failed :/ It requires a credit card in the free trial. I used my personal one, but even after triple checking my info it was rejected. I suspect it wanted one with a billing address that matches our business address.

Otherwise, I read the doc and it makes sense. I approve.

@samkujovich can you try the Entra integration with the company card to double check the instructions in the doc that'll go live for customers?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants