40 lines
2.5 KiB
Markdown
40 lines
2.5 KiB
Markdown
# Authentication Flow
|
|
|
|
Forward auth path for an internal service that doesn't speak OIDC natively. OIDC-native services skip the Caddy hop and go straight to Authentik for the auth handshake — same trust boundary, fewer round trips.
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant U as User
|
|
participant C as Caddy<br/>(reverse proxy)
|
|
participant A as Authentik<br/>(IdP)
|
|
participant S as Internal service
|
|
|
|
U->>C: HTTPS request
|
|
C->>A: Forward auth check
|
|
A-->>C: 401 (no session)
|
|
C-->>U: 302 → auth.lerkolabs.com
|
|
|
|
U->>A: Login (OIDC or password)
|
|
A-->>U: Set session cookie
|
|
|
|
U->>C: HTTPS request + cookie
|
|
C->>A: Forward auth check
|
|
A-->>C: 200 OK + identity headers
|
|
C->>S: Proxy request<br/>(plain HTTP, internal hop)
|
|
S-->>U: Response
|
|
```
|
|
|
|
## How this ended up here
|
|
|
|
Authentik was originally only standing up because Outline needed an IdP to function. I figured I'd run it for that one app and forget about it. Then I started noticing how many other apps had OIDC support sitting right there, and integrating each new one was cheap once the IdP was already in place. After a few months, "every internal service goes through SSO" had become the default without me ever sitting down to decide it.
|
|
|
|
The forward-auth path in this diagram is the catch-all for apps that don't speak OIDC. Caddy intercepts the request, asks Authentik whether the user is logged in, and either proxies through or bounces them to the login page. Less elegant than native OIDC, but it means the "log in with the app's local account" bypass simply doesn't exist anywhere. Every door uses the same key.
|
|
|
|
The Discord music bot is the one case where this same flow is reachable from the public internet. That started because I wanted my friends to be able to use the bot, which meant the dashboard had to be hittable from outside the LAN. Authentik in the DMZ Caddy gates the request; the policy only lets through specific Discord user IDs. Friends get in, randoms don't, and the same auth machinery I was already running handles it.
|
|
|
|
## Notes
|
|
|
|
- **Edge terminates TLS; internal hops are HTTP.** Trust on internal hops is established by segmentation and identity, not by re-encrypting every jump.
|
|
- **Identity headers from Authentik** are passed to the upstream service so it can attribute requests to a user without implementing its own auth.
|
|
- **No anonymous access path.** If Authentik is down, internal services are unreachable. Accepted tradeoff over the alternative — a fallback "skip auth" mode would inevitably get used and would inevitably be the thing that got abused.
|