Self-Hosted OIDC Federation — Candidate Comparison and Recommendation
Research report for owner decision: one self-hosted, open-source OpenID Connect identity provider to federate Google / Apple / GitHub / Microsoft sign-in for the fleet (Hermes portal, Docusaurus, Codebase Memory, Research Hub, Hermes WebUI), Docker-only installs, tailnet-only exposure via Tailscale Serve.
Evidence basis: a dedicated research pipeline (collection → compilation →
two fresh-context reviews). Primary-source captures and 20 falsifiable claims
are preserved at /root/Working/Research/self-hosted-oidc-federation-20260930/
(evidence packet, Level 1 receipt, Level 2 review reports). Nothing was
deployed or tested; all claims are documentary, and the labels below are the
packet's own epistemic vocabulary, not shorthand.
Headline result
Recommendation: authentik — with Keycloak as a genuine runner-up, not an afterthought. The ranking below is the remediated one: the first review pass found a critical coherence defect (Keycloak was being rejected solely for lacking Apple support, while the same report scoped Apple out of this deployment). The defect was corrected inside the artifact: Keycloak's verdict changed from NO to RUNNER-UP; ZITADEL moved from second to third.
| Rank | Candidate | GitHub | Microsoft | Apple | Forward-auth proxy (for the static/web-UI apps) | Verdict | |
|---|---|---|---|---|---|---|---|
| 1 | authentik | GA-DOC | GA-DOC | GA-DOC | GA-DOC | First-party proxy provider (evidenced) | Recommended |
| 2 | Keycloak | GA | GA | GA | EXT only (third-party JAR; not in the 26.7.4 official guide) | Needs a separate forward-auth component (oauth2-proxy / Traefik / Caddy) | Runner-up — Apache-2.0, most mature, largest community; costs one extra container; reverts to "no" if Apple becomes required |
| 3 | ZITADEL | GA | GA | GA | GA | No first-party forward-auth → also needs a second component | Excellent IdP, but AGPL-3.0-only core and smaller community; no Apple-independent reason to prefer it over Keycloak |
| 4 | Casdoor | GA | GA | GA | GA (docs ~20 months after first user reports of Apple friction) | No first-party forward-auth | No — Apple docs arrived after user-reported failures; project is repositioning toward "agent-first IAM / MCP gateway" |
| 5 | Ory (Kratos + Hydra) | GA | GA | GA | GA | Highest — you build the login and consent UIs yourself | No — a toolkit, not a turnkey IdP; slowest release cadence of the group |
| — | Authelia | — | — | — | — | — | VENDOR-DENIED for this job: its docs state it supports the OIDC provider role (open beta) and does not intend the relying-party role — i.e. it cannot itself "log in with Google/GitHub/Apple/Microsoft" |
| — | Pomerium / oauth2-proxy | — | — | — | — | — | No account store of their own; they front an IdP rather than replace one |
Two labels carry the whole Apple question, and they are different states: NOT-DOCUMENTED (Apple absent from the full Keycloak 26.7.4 admin guide — zero matches in 1,127,768 characters of retrieved text, with a control check that other socials do appear) is not VENDOR-DENIED (Keycloak never says Apple is unsupported), and it is not a collection gap. A third-party Apple JAR exists (EXT-COMMUNITY) but binds to internal SPIs and breaks across major versions.
Why authentik wins this fleet, not the other way around
- Consolidation, not four-provider coverage. Once Apple is out of scope (see below), Keycloak, ZITADEL, Casdoor and Ory are all documented for Google, GitHub and Microsoft — so the deciding axis is the other job: protecting apps that cannot implement an OIDC client themselves.
- The static site and the plain web UI can only be secured at a proxy. Docusaurus is static; Codebase Memory's UI does not ship an OIDC client. authentik documents a first-party forward-auth proxy provider; every other candidate needs a second component (oauth2-proxy, Traefik forwardAuth, or Caddy forward_auth). That generic-middleware substitute works in general but is REASONED, not vendor-confirmed, for these specific IdPs — nothing was deployed to test it.
- Login-page social login is OSS in authentik (the "sign in with" buttons); flow-embedding (social buttons inside the app's own login flow) is what's Enterprise-marked. For this fleet the OSS login-page path is the one that matters.
- Docker Compose fits the Docker-only constraint, with vendor-stated caveats (Postgres + Redis sidecars).
Apple: out of scope for this deployment, and the report says why
Sign in with Apple is blocked by Apple's own prerequisites, not by any
candidate: it requires a verified HTTPS domain (and in practice public-facing
reachability for its token exchange), which a *.ts.net tailnet-only host
does not satisfy. That inference is labeled REASONED, not vendor-stated.
Two consequences:
- No candidate is penalized for "missing Apple" — Apple is absent from the premises of this deployment.
- If Apple sign-in ever becomes a hard requirement, the ranking reverts: Keycloak drops out (extension-only), and ZITADEL (first-party Apple, handles the form-post) rises.
What must be settled empirically before committing
One load-bearing question stays UNVERIFIED / untested: whether Google
(others presumably) accepts a *.ts.net HTTPS redirect URI in practice. A
published rule check found no violation (the URI is https, domain-scoped,
path-allowed), but acceptance in practice was not tested. The report's
actionable step: run a 20-minute test — register a Google OAuth client with
the tailnet redirect URI and complete one sign-in through a throwaway client
of the candidate IdP — before any production cutover.
Caveats the owner should keep in view
- Forward-auth proxy claims for Keycloak/ZITADEL/Casdoor/Ory are
NOT-DOCUMENTED in this run's retrieval (no first-party proxy doc fetched),
with the nginx
auth_requesthalf of that check still an open collection gap. - Operational-burden comparisons rest partly on uncited inference (collection gap 5 in the packet).
- Community-health figures are a point-in-time GitHub API capture, not a trend statement.
- authentik's own license split (MIT core, some features GPL/Enterprise) was noted by the packet; the recommended path uses OSS-tier features only, but a production cutover should re-confirm which authentik tiers the forward-auth proxy needs.
Sources (load-bearing)
- authentik docs: social sign-in sources + proxy/forward-auth provider (primary, current)
- Keycloak 26.7.4 full admin guide retrieval (absence finding, with method note)
- Keycloak Apple JAR (community extension, GitHub)
- ZITADEL federation docs (incl. Apple form-post handling); ZITADEL license files (AGPL-3.0 core)
- Casdoor Apple docs commit history (2025-05-05) vs first user report (2023-09-04, #2298)
- Ory Hydra/Kratos docs; Pomerium docs; oauth2-proxy docs
- Apple Sign in with Apple developer requirements (prerequisite set)
- Google / Microsoft Entra / GitHub OAuth redirect-URI published rules
Full verbatim captures, claim-to-evidence bindings, and the review trail:
/root/Working/Research/self-hosted-oidc-federation-20260930/.
Decision requested
Approve the authentik direction (with the 20-minute tailnet-redirect empirical test as a precondition), or name a constraint that changes the ranking (e.g. Apple required → ZITADEL; no extra containers acceptable → re-weigh Keycloak-plus-proxy).
Published by hermesjkdev001 · 2026-09-30.