# The Guest List 💋 Every app in The Super Boujee Business Box ✨ authenticates through the same door. One login, every room. You don't re-authenticate because you walked from Docs to Drive — that's not a feature, that's just manners. The identity layer is built on **Ory Kratos** (who you are) and **Ory Hydra** (what you're allowed to do). Lightweight Go binaries, no JVM, no XML — they fit k3s like they were born for it. We chose them over Keycloak because we wanted something that didn't need 2GB of RAM to tell you who's logged in. --- ## The Auth Flow ``` You → any app (docs.sunbeam.pt, drive.sunbeam.pt, etc.) → 302 redirect to auth.sunbeam.pt → Hydra says "who are you?" → Kratos login UI (password, TOTP, WebAuthn — your pick) → authenticate → Hydra issues OIDC token → 302 back to the app → app validates via mozilla-django-oidc → session established ✨ ``` That's it. Every La Suite app uses the same `mozilla-django-oidc` library. Swapping from Keycloak (the French government default) to Hydra was transparent at the app level — same OIDC, different provider. --- ## The Players ### Ory Kratos — Identity Management Handles the "who are you" part: - **Registration** — create accounts (or provision them via `sunbeam auth identity create`) - **Login** — password, TOTP, WebAuthn, lookup secrets - **Profile** — name, email, metadata - **Recovery** — password reset via email (through Postfix) - **Session** — 720 hours (30 days), cookie-scoped to parent domain The cookie-scoping is key: setting the session cookie on the parent domain means all `*.sunbeam.pt` subdomains share the session. Log in once, you're everywhere. ### Identity Schemas Three schemas for different types of users: | Schema | Purpose | |--------|---------| | `employee` | Core team (Sienna, Amber, Lonni) — full access, all apps | | `default` | Standard users — for when the team grows | | `external` | External collaborators — limited scope | ### Ory Hydra — OAuth2 / OIDC Provider Handles the "what can you do" part: - Issues OAuth2 access tokens and OIDC ID tokens - Manages the OIDC client registry - Token lifetimes: access/ID tokens 1h, refresh tokens 720h, auth session 720h - OpenID Connect discovery at `auth.sunbeam.pt/.well-known/openid-configuration` ### Hydra Maester The secret sauce for client management. Watches `HydraOAuth2Client` CRDs in Kubernetes and automatically: 1. Registers the client with Hydra 2. Creates a K8s Secret with `CLIENT_ID` and `CLIENT_SECRET` 3. Keeps them in sync if the CRD changes No manual client registration. Declare a CRD, get a working OIDC client. --- ## The OIDC Client Registry Every app is a registered OIDC client. Hydra Maester manages all of them: | App | Secret Name | Redirect URI | Notes | |-----|-------------|-------------|-------| | Docs | oidc-docs | `docs.DOMAIN/api/v1.0/callback/` | | | Drive | oidc-drive | `drive.DOMAIN/api/v1.0/callback/` | | | Meet | oidc-meet | `meet.DOMAIN/api/v1.0/callback/` | | | Messages | oidc-messages | `mail.DOMAIN/api/v1.0/callback/` | `offline_access` scope | | People | oidc-people | `people.DOMAIN/api/v1.0/callback/` | | | Find | oidc-find | `find.DOMAIN/oidc/callback/` | | | Gitea | oidc-gitea | `src.DOMAIN/user/oauth2/Sunbeam/callback` | | | Calendars | oidc-calendars | `cal.DOMAIN/api/v1.0/callback/` | | | Projects | oidc-projects | `projects.DOMAIN/oidc-callback` | | | Hive | oidc-hive | *(none)* | `client_credentials` grant | | Tuwunel | oidc-tuwunel | *(matrix namespace)* | Matrix SSO | | Grafana | grafana-oidc | *(monitoring namespace)* | auto-assign Admin role | Messages gets `offline_access` to maintain sessions across browser restarts. Hive uses `client_credentials` because it's a service, not a human. Grafana auto-assigns Admin because if you're authenticated, you're on the team. --- ## Self-Service Flows Users can manage their own security: | Method | What it is | |--------|-----------| | **Password** | Classic email + password | | **TOTP** | Time-based one-time passwords (Google Authenticator, etc.) | | **WebAuthn** | Hardware security keys (YubiKey, etc.) | | **Lookup Secrets** | Backup/recovery codes | Recovery emails go through Postfix (same SMTP used by Messages) at `postfix.lasuite.svc:25`. --- ## Vault Integration Secrets don't live in Git. They live in OpenBao (Vault) and sync to Kubernetes via Vault Secrets Operator. ### OIDC Client Secrets Hydra Maester creates K8s Secrets from HydraOAuth2Client CRDs. These contain `CLIENT_ID` and `CLIENT_SECRET` that apps consume. ### Dynamic Database Credentials Every app's database password rotates every 5 minutes via `VaultDynamicSecret`. The Vault Secrets Operator: 1. Requests new credentials from OpenBao's database engine 2. Creates/updates the K8s Secret 3. Triggers a rollout restart of the affected Deployment ### Static Secrets Django secret keys, DKIM keys, API tokens — synced from OpenBao KV v2 with 30-second refresh via `VaultStaticSecret`. --- ## Admin Access For when you need to manage identities directly: ```bash # Via sunbeam CLI sunbeam auth identity list sunbeam auth identity create amber@sunbeam.pt --name "Amber" sunbeam auth identity get # Via Kratos Admin API (auth-gated through proxy) # Accessible at id.sunbeam.pt (requires Hydra /userinfo auth) # Via Hydra Admin API (auth-gated through proxy) # Accessible at hydra.sunbeam.pt (requires Hydra /userinfo auth) ``` Sol☀️ also has Kratos admin access for identity operations within Matrix chat. --- ## The Login UI Sunbeam-branded login, consent, and recovery pages served by `kratos-admin-ui`. This is what you see at `auth.sunbeam.pt` — the velvet rope. Custom logo, custom colors, same energy as everything else in the box. ✨