From 2bae1148bb5a6cf979b6dd04cc1d6fd86bfd90f4 Mon Sep 17 00:00:00 2001 From: Snider Date: Fri, 20 Feb 2026 16:23:02 +0000 Subject: [PATCH] docs(go-api): add Authentik integration and auth layers to design Adds forward auth (Traefik) and direct OIDC validation modes, auth layers diagram, deployment notes, and coreos/go-oidc dependency. Authentik added to Wave 1 plugin roadmap. Co-Authored-By: Virgil --- docs/plans/2026-02-20-go-api-design.md | 105 +++++++++++++++++++++++-- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/docs/plans/2026-02-20-go-api-design.md b/docs/plans/2026-02-20-go-api-design.md index bb21d22..3d46a93 100644 --- a/docs/plans/2026-02-20-go-api-design.md +++ b/docs/plans/2026-02-20-go-api-design.md @@ -215,7 +215,7 @@ api.New( ) ``` -Auth evolution path: bearer token → API keys → JWT → OAuth2/OIDC. Middleware slot stays the same. +Auth evolution path: bearer token → API keys → Authentik (OIDC/forward auth). Middleware slot stays the same. ## WebSocket Integration @@ -322,9 +322,10 @@ All plugins drop in as `With*()` options on the Engine. No architecture changes | Plugin | Option | Purpose | Priority | |--------|--------|---------|----------| +| **Authentik** | `WithAuthentik()` | OIDC + forward auth integration. See Authentik section below. | **High** | | [gin-contrib/secure](https://github.com/gin-contrib/secure) | `WithSecure()` | Security headers: HSTS, X-Frame-Options, X-Content-Type-Options, CSP. Essential for web pages and API alike. | High | -| [gin-contrib/sessions](https://github.com/gin-contrib/sessions) | `WithSessions()` | Server-side sessions (cookie, Redis, memcached). Needed when auth evolves beyond bearer tokens to web sessions. | High | -| [gin-contrib/authz](https://github.com/gin-contrib/authz) | `WithAuthz()` | Casbin-based authorisation. Policy-driven access control — define who can call which endpoints. | Medium | +| [gin-contrib/sessions](https://github.com/gin-contrib/sessions) | `WithSessions()` | Server-side sessions (cookie, Redis, memcached). For web session management alongside Authentik tokens. | High | +| [gin-contrib/authz](https://github.com/gin-contrib/authz) | `WithAuthz()` | Casbin-based authorisation. Policy-driven access control — define who can call which endpoints. Complements Authentik's identity with fine-grained permissions. | Medium | | [gin-contrib/httpsign](https://github.com/gin-contrib/httpsign) | `WithHTTPSign()` | HTTP signature verification. Maps to UEPS Ed25519 consent tokens for Lethean network peer authentication. | Medium | ### Performance & Reliability @@ -386,18 +387,112 @@ Four protocols, one set of handlers. ### Implementation Order -**Wave 1 (gateway hardening):** secure, slog, timeout, gzip, static +**Wave 1 (gateway hardening):** Authentik, secure, slog, timeout, gzip, static **Wave 2 (performance + auth):** cache, sessions, authz, brotli **Wave 3 (network + streaming):** httpsign, sse, location, i18n, gqlgen **Wave 4 (observability):** pprof, expvar, opengintracing Each wave adds `With*()` options + tests. No breaking changes — existing code continues to work without any new options enabled. +## Authentik Integration + +[Authentik](https://goauthentik.io/) is the identity provider and edge auth proxy. It handles user registration, login, MFA, social auth, SAML, and OIDC — so go-api doesn't have to. + +### Two Integration Modes + +**1. Forward Auth (web traffic)** + +Traefik sits in front of go-api. For web routes, Traefik's `forwardAuth` middleware checks with Authentik before passing the request through. Authentik handles login flows, session cookies, and consent. go-api receives pre-authenticated requests with identity headers. + +``` +Browser → Traefik → Authentik (forward auth) → go-api + ↓ + Login page (if unauthenticated) +``` + +go-api reads trusted headers set by Authentik: +``` +X-Authentik-Username: alice +X-Authentik-Groups: admins,developers +X-Authentik-Email: alice@example.com +X-Authentik-Uid: +X-Authentik-Jwt: +``` + +**2. OIDC Token Validation (API traffic)** + +API clients (SDKs, CLI tools, network peers) authenticate directly with Authentik's OAuth2 token endpoint, then send the JWT to go-api. go-api validates the JWT using Authentik's OIDC discovery endpoint (`.well-known/openid-configuration`). + +``` +SDK client → Authentik (token endpoint) → receives JWT +SDK client → go-api (Authorization: Bearer ) → validates via OIDC +``` + +### Implementation in go-api + +```go +engine := api.New( + api.WithAuthentik(api.AuthentikConfig{ + Issuer: "https://auth.lthn.ai/application/o/core-api/", + ClientID: "core-api", + TrustedProxy: true, // Trust X-Authentik-* headers from Traefik + }), +) +``` + +`WithAuthentik()` adds middleware that: +1. Checks for `X-Authentik-Jwt` header (forward auth mode) — validates signature, extracts claims +2. Falls back to `Authorization: Bearer ` header (direct OIDC mode) — validates via JWKS +3. Populates `c.Set("user", AuthentikUser{...})` in the Gin context for handlers to use +4. Skips /health, /swagger, and any public paths + +```go +// In any handler: +func (r *Routes) ListItems(c *gin.Context) { + user := api.GetUser(c) // Returns *AuthentikUser or nil + if user == nil { + c.JSON(401, api.Fail("unauthorised", "Authentication required")) + return + } + // user.Username, user.Groups, user.Email, user.UID available +} +``` + +### Auth Layers + +``` +Authentik (identity) → WHO is this? (user, groups, email) + ↓ +go-api middleware → IS their token valid? (JWT verification) + ↓ +Casbin authz (optional) → CAN they do this? (role → endpoint policies) + ↓ +Handler → DOES this (business logic) +``` + +Phase 1 bearer auth continues to work alongside Authentik — useful for service-to-service tokens, CI/CD, and development. `WithBearerAuth` and `WithAuthentik` can coexist. + +### Authentik Deployment + +Authentik runs as a Docker service alongside go-api, fronted by Traefik: +- **auth.lthn.ai** — Authentik UI + OIDC endpoints (production) +- **auth.leth.in** — Authentik for devnet/testnet +- Traefik routes `/outpost.goauthentik.io/` to Authentik's embedded outpost for forward auth + +### Dependencies + +| Package | Purpose | +|---------|---------| +| `github.com/coreos/go-oidc/v3` | OIDC discovery + JWT validation | +| `golang.org/x/oauth2` | OAuth2 token exchange (for server-side flows) | + +Both are standard Go libraries with no heavy dependencies. + ## Non-Goals - gRPC gateway - Automatic MCP-to-REST adapter (can be added later) -- OAuth2 server (use external provider) +- Built-in user registration/login (Authentik handles this) - API versioning beyond /v1/ prefix ## Success Criteria