# 🪪 SSO & Identity > [!NOTE] > Every app that needs single sign-on registers against the identity provider once per reverse-proxy zone it's exposed on — and a real platform limitation shapes how superuser accounts authenticate. ## Login flow — same shape, every app ```mermaid sequenceDiagram participant U as User participant App as App (browser-facing zone) participant IdP as Identity Provider (internal zone) U->>App: Opens app App->>U: Redirect to identity provider U->>IdP: OAuth authorize/token exchange Note over IdP: Always happens on the internal zone,
even though the app itself lives
on the browser-facing zone IdP->>U: Success U->>App: Lands back on the app ``` Every app-specific setting beyond this shape (token lifetime, scopes, flow type) is deliberately **not** generalized across apps — each app's own OIDC documentation gets read fresh rather than copying another app's provider config, since the details genuinely differ per vendor. | | | |---|---| | **Registration pattern** | Provider + application pair per zone (up to 2 per app) | | **Native OIDC/SAML apps** | ~12 apps, where the upstream supports it directly | | **Everything else** | Proxy-based forward-auth | ## A real limitation, documented rather than hidden > [!WARNING] > LDAP-based login through the identity provider's own outpost **isn't viable for the primary superuser account** — the outpost hides superuser accounts from LDAP directory search, so any app requiring a search-then-bind flow can never authenticate that account through LDAP. The two workarounds — a second non-admin account, or demoting the primary account from superuser — were both rejected as worse than the problem. Header-based forward-auth is used instead for apps in that situation. ## Git access: least privilege, not the admin account ```mermaid flowchart LR CI["CI / Automation"] -->|scoped write| Bot["Dedicated bot account
non-admin"] Bot --> Repo["Git server"] Other["Other hosts"] -->|read-only| Deploy["Deploy keys
per host"] Deploy --> Repo ``` CI and automation pushes run through a dedicated, non-admin bot account with scoped write access — never through an administrator identity. Hosts that only need to *read* get separate read-only deploy keys instead of any shared credential. A compromised automation credential is never an admin credential. --- Related stacks: [`stacks/identity-and-security/authentik/`](../stacks/identity-and-security/authentik/), [`stacks/platform/gitea/`](../stacks/platform/gitea/)