Files
public/docs/sso-and-identity.md
T
thesabear e9af5dde32 Fix SSO section: correct README/doc split, remove unverified LDAP claim
README is short/sharp facts, docs/*.md is full depth/process/reasoning
- that split had collapsed into either near-duplicate text in both
files or the fact missing from the README entirely. README now states
the OIDC zone-crossing fact in one crisp sentence; the full doc has
the complete step-by-step breakdown. The LDAP superuser workaround
claim is removed from both - the source material frames it as
contingency guidance for a scenario that may never have come up, not
documented deployed behavior, so it doesn't belong in either file.
2026-08-22 19:30:52 +03:00

35 lines
3.1 KiB
Markdown

# 🪪 SSO & Identity
> [!NOTE]
> Authentik is the identity provider for this fleet — self-hosted rather than an external IdP, for the same reason Vault is self-hosted in [`docs/secrets-and-pki.md`](secrets-and-pki.md): internal-only apps shouldn't need to trust a third party just to authenticate a login, and the two-zone reverse-proxy model in [`docs/dns-naming.md`](dns-naming.md) only works if the identity provider itself lives inside that same trust boundary.
## Dual-zone registration
Every new app gets a Proxy Provider + Application pair registered per reverse-proxy zone it's actually exposed on — up to two registrations for the same app, one per zone from [`docs/dns-naming.md`](dns-naming.md), driven by actual need rather than registering every app on both zones by default.
## OIDC login: the redirect crosses zones, every time
For an app using native OIDC, the login always follows the same path:
1. User opens the app on the **browser-facing zone**.
2. The app redirects the browser to Authentik to do the actual OAuth authorize/token exchange.
3. That exchange happens against Authentik's own address on the **service-to-service zone** — reachable from a browser for this one hop specifically, even though that zone doesn't get the mutual-TLS treatment the browser-facing zone does.
4. On success, the browser lands back on the app, still on the browser-facing zone.
So an app's OIDC discovery/authority setting always points at the service-to-service zone, even though the app itself is normally reached on the browser-facing zone — the two zones are defined in [`docs/dns-naming.md`](dns-naming.md). This is confirmed against one real app's actual login flow, not assumed to hold for every app without checking. Every other app-specific setting (token lifetime, scopes, flow type) doesn't generalize the same way — each app's own OIDC documentation gets read fresh rather than copying another app's provider config, since those details genuinely differ per vendor.
## Git access: least privilege, not the admin account
```mermaid
flowchart LR
CI["CI / Orchestration engine<br/>see docs/orchestration.md"] -->|scoped write| Bot["Dedicated bot account<br/>non-admin"]
Bot --> Repo["Gitea"]
Other["Other hosts"] -->|read-only| Deploy["Deploy keys<br/>per host"]
Deploy --> Repo
```
Automation should never run with more privilege than it needs. CI and orchestration pushes (the flows described in [`docs/orchestration.md`](orchestration.md)) 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. The practical payoff: if an automation credential ever leaks, the blast radius is "can push to specific repos," not "has full admin control of the Git server."
---
Related: [`docs/dns-naming.md`](dns-naming.md), [`docs/orchestration.md`](orchestration.md), [`docs/secrets-and-pki.md`](secrets-and-pki.md) · Stacks: [`stacks/identity-and-security/authentik/`](../stacks/identity-and-security/authentik/), [`stacks/platform/gitea/`](../stacks/platform/gitea/)