Skip to content

docs: add ADFS self-hosted identity provider guide#705

Draft
SunsetDrifter wants to merge 7 commits intomainfrom
docs/adfs-oidc-guide
Draft

docs: add ADFS self-hosted identity provider guide#705
SunsetDrifter wants to merge 7 commits intomainfrom
docs/adfs-oidc-guide

Conversation

@SunsetDrifter
Copy link
Copy Markdown
Contributor

Summary

  • Adds src/pages/selfhosted/identity-providers/adfs.mdx — a guide for integrating on-prem Active Directory with ADFS as an OIDC identity provider for self-hosted NetBird.
  • Covers the recommended production topology: ADFS on a dedicated member server, Web Application Proxy (WAP) in a DMZ for external access, and Cisco Duo ADFS MFA Adapter on the ADFS server.
  • Documents the two NetBird settings that are easy to miss with ADFS: NETBIRD_TOKEN_SOURCE=idToken (ADFS puts user claims in the id_token, not the access_token) and NETBIRD_AUTH_USER_ID_CLAIM=upn (the default base64 sub claim breaks URL routing).
  • Adds the page to the sidebar under Self-hosted IdPs in NavigationDocs.jsx.

Page layout

Architecture diagram → Firewall rules → Prerequisites → AD user attribute requirements → 7 configuration steps (ADFS install, OIDC app group, claim transform rules, CORS, WAP install, Duo adapter, NetBird config) → Verification → Troubleshooting → Configuration summary.

Test plan

  • npm run build completes without errors and the new route appears as a static page
  • /selfhosted/identity-providers/adfs renders in the browser with the expected content
  • Sidebar shows ADFS under Self-hosted IdPs alongside Keycloak / Zitadel / Authentik / PocketID
  • Internal anchor links in Troubleshooting resolve to the right step sections
  • <Note> callouts render correctly
  • PowerShell and Bash code blocks have syntax highlighting

New guide for integrating on-prem Active Directory with ADFS as an OIDC
identity provider for self-hosted NetBird. Covers ADFS on a dedicated
member server, Web Application Proxy in a DMZ, Duo ADFS MFA Adapter,
claim transform rules, and the required NetBird configuration
(NETBIRD_TOKEN_SOURCE=idToken, NETBIRD_AUTH_USER_ID_CLAIM=upn).
@SunsetDrifter SunsetDrifter marked this pull request as draft April 17, 2026 09:28
Switch from standalone/setup.env style to the CE-native Dashboard-based
external IdP flow:

- Use a confidential Server Application (Add-AdfsServerApplication with
  generated client secret) instead of a Native Application with PKCE.
- Redirect URI now comes from NetBird's Settings > Identity Providers
  flow, not hard-coded /peers paths.
- Drop the NETBIRD_TOKEN_SOURCE and NETBIRD_AUTH_USER_ID_CLAIM env vars
  (those are standalone/commercial-license settings).
- Fix the base64 sub claim issue upstream in ADFS via a new claim rule
  (Rule 5) that emits sub from UPN, with a fallback note about
  PairwiseIdentifierEnabled for ADFS builds that need it.
- Update Troubleshooting and Configuration Summary to match.
Pull in the richer explanations from the updated source guide:

- Step 1 gets server-provisioning prerequisites, Get-WindowsFeature
  verification after role install, expanded TLS cert rationale with
  Test-Certificate, a three-option service-account discussion with the
  Get-KdsRootKey check and lab-mode EffectiveTime trick, a full
  troubleshooting block for Install-ADServiceAccount, per-parameter
  explanations for Install-AdfsFarm, and a Start-Service + event-log
  fallback plus detailed OIDC-endpoint troubleshooting in 1.5.
- Step 5 gets a full Provision the WAP Server section covering server
  specs, the domain-join decision (with SCADA framing generalized),
  pre-install firewall rules, hosts-file name resolution with Test-
  NetConnection, and exact Export-PfxCertificate/Import-PfxCertificate
  flow for the WAP cert. Step 5.3 is reframed as Establish the Proxy
  Trust with what-it-does and what-you-need callouts; 5.4 expands
  Get-WebApplicationProxyHealth troubleshooting.

CE-specific rewrites (Server Application flow, Dashboard IdP config,
Rule 5 sub override, Duo-optional framing) are preserved.
@sindresorhus/slugify (the project's heading slug generator) splits
CamelCase words (NetBird -> net-bird) and inserts hyphens between
period-separated digits (2.3 -> 2-3). Update every in-page anchor to
match the generated slugs so step links resolve correctly.

Also redirect the UPN row in the AD attributes table to Step 3, since
the 'Required NetBird Configuration Settings' subsection it used to
reference was removed in the CE rewrite.
Rules 3a and 3b in Step 3 produce the 'groups' claim consumed by
JWT Group Sync. Add a Note explaining they can be skipped if group
sync isn't needed, and clarify that 3a and 3b must be kept together
(3a emits into a temp claim, 3b filters and renames it to 'groups').
The prior one-sentence intro ('NetBird requires specific claims in the
OIDC tokens') didn't explain what issuance transform rules are or what
each of the six rules does. Add a paragraph on why ADFS needs them and
a short bullet list describing each rule's purpose and dependencies
(e.g., Rule 5 depends on Rule 4). The optional-rules Note and code
block follow unchanged.
- Replace Get-EventLog with Get-WinEvent in Step 1.5 — Get-EventLog
  only reads classic logs and cannot open 'AD FS/Admin', which lives
  under Applications and Services Logs.
- Remove references to Set-AdfsServerApplication -PairwiseIdentifierEnabled
  $false; that parameter does not exist on the cmdlet. Replace the
  fallback guidance with NETBIRD_AUTH_USER_ID_CLAIM="upn" in setup.env,
  which was the actual POC fix alongside the Rule 5 claim override.
- Restructure the 404 troubleshooting entry as a two-step fix
  (claim rule + NetBird env var) with a decode-token sanity check.
- Drop the 'Domain Users' example from the JWT group sync paragraph
  since Rule 3b's default '^NetBird-' filter would exclude it;
  clarify that visible groups are governed by the filter regex.
- Relabel the LDAP/LDAPS firewall row as 'directory and attribute
  lookups (claim data)' rather than 'authentication'; ADFS
  authenticates users via Kerberos and uses LDAP for attribute lookup.
- Add a clarifying Note to Step 2.5 explaining that the guide reuses
  the client_id as the Web API identifier for simplicity, and larger
  environments may prefer a distinct resource URI.
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.

1 participant