diff --git a/docs/erfaringer/README.md b/docs/erfaringer/README.md index b58ed2e..8d3a8d2 100644 --- a/docs/erfaringer/README.md +++ b/docs/erfaringer/README.md @@ -12,6 +12,7 @@ Formålet er å treffe raskere blink med neste komponent. Hver fil dekker én te | `spacetimedb_integrasjon.md` | SDK-konvensjoner, TypeScript-bindings, BigInt, tilkobling | | `adapter_moenster.md` | Adapter/factory for PG↔SpacetimeDB, hybrid-tilnærming | | `authentik_oidc.md` | Authentik sub-claim format, @auth/sveltekit JWT-quirks | +| `authentik_oppsett.md` | OIDC-provider/app-konfigurasjon, endepunkter, redirect URIs, API-admin | ## Retningslinjer diff --git a/docs/erfaringer/authentik_oppsett.md b/docs/erfaringer/authentik_oppsett.md new file mode 100644 index 0000000..8debd0e --- /dev/null +++ b/docs/erfaringer/authentik_oppsett.md @@ -0,0 +1,120 @@ +# Erfaring: Authentik OIDC-oppsett for Synops + +## Oversikt + +Authentik kjører på `auth.sidelinja.org` og fungerer som SSO for alle +Synops-tjenester. To OIDC-providere er konfigurert: + +| Provider | Application | Slug | Bruk | +|---|---|---|---| +| `forgejo` | forgejo | `forgejo` | Git-hosting (git.sidelinja.org) | +| `sidelinja-web` | Sidelinja | `sidelinja` | Hovedapplikasjon (sidelinja.org) | + +## Sidelinja OIDC-provider + +### Endepunkter + +- **Issuer:** `https://auth.sidelinja.org/application/o/sidelinja/` +- **Discovery:** `https://auth.sidelinja.org/application/o/sidelinja/.well-known/openid-configuration` +- **Authorization:** `https://auth.sidelinja.org/application/o/authorize/` +- **Token:** `https://auth.sidelinja.org/application/o/token/` +- **Userinfo:** `https://auth.sidelinja.org/application/o/userinfo/` +- **JWKS:** `https://auth.sidelinja.org/application/o/sidelinja/jwks/` + +### Konfigurasjon + +- **Client type:** Confidential +- **Authorization flow:** Implicit consent (ingen godkjenningsskjerm — det er vår egen app) +- **Signing algorithm:** RS256 +- **Access token validity:** 1 time +- **Refresh token validity:** 30 dager +- **Sub mode:** `hashed_user_id` (SHA256 av Authentik intern UUID) + +### Redirect URIs + +| Modus | URL | Formål | +|---|---|---| +| strict | `https://sidelinja.org/auth/callback/authentik` | Produksjon | +| regex | `http://localhost:\d+/auth/callback/authentik` | Lokal utvikling | + +### Scopes + +Provideren tilbyr: `openid`, `email`, `profile`, `offline_access`. + +### Miljøvariabler (.env på server) + +``` +AUTHENTIK_ISSUER=https://auth.sidelinja.org/application/o/sidelinja/ +AUTHENTIK_CLIENT_ID= +AUTHENTIK_CLIENT_SECRET= +``` + +Disse brukes av SvelteKit (`@auth/sveltekit`) og senere av maskinrommet +for JWT-validering. + +## JWT-validering i maskinrommet + +Maskinrommet (Rust/axum) validerer access tokens utstedt av denne provideren: + +1. Hent JWKS fra `https://auth.sidelinja.org/application/o/sidelinja/jwks/` +2. Valider signatur (RS256), issuer, og utløpstid +3. Slå opp `sub`-claim i `auth_identities`-tabellen → `node_id` + +**Viktig:** `sub` er en SHA256-hash, ikke en UUID. Se `docs/erfaringer/authentik_oidc.md` +for detaljer om dette og andre fallgruver. + +## Administrasjon + +### API-tilgang + +Opprett API-token via `ak shell`: + +```bash +docker exec sidelinja-authentik-server-1 ak shell -c " +from authentik.core.models import Token, User +user = User.objects.get(username='akadmin') +token, _ = Token.objects.get_or_create( + identifier='api-token', + defaults={'user': user, 'intent': 'api', 'expiring': False} +) +print(token.key) +" +``` + +Bruk tokenet med: `Authorization: Bearer ` + +### Verifiser oppsett + +```bash +# OIDC discovery +curl -s https://auth.sidelinja.org/application/o/sidelinja/.well-known/openid-configuration | jq .issuer + +# JWKS (for JWT-validering) +curl -s https://auth.sidelinja.org/application/o/sidelinja/jwks/ | jq '.keys | length' + +# List providere via API +curl -s -H "Authorization: Bearer " \ + https://auth.sidelinja.org/api/v3/providers/oauth2/ | jq '.results[].name' +``` + +## Legge til ny redirect URI + +Hvis en ny tjeneste trenger OIDC (f.eks. maskinrommet med egen callback): + +```bash +# Hent provider pk +curl -s -H "Authorization: Bearer " \ + https://auth.sidelinja.org/api/v3/providers/oauth2/?name=sidelinja-web | jq '.results[0].pk' + +# Oppdater redirect_uris (PATCH) +curl -s -X PATCH -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + https://auth.sidelinja.org/api/v3/providers/oauth2// \ + -d '{"redirect_uris": [ + {"matching_mode": "strict", "url": "https://sidelinja.org/auth/callback/authentik"}, + {"matching_mode": "regex", "url": "http://localhost:\\d+/auth/callback/authentik"}, + {"matching_mode": "strict", "url": "https://ny-tjeneste.sidelinja.org/callback"} + ]}' +``` + +**Merk:** PATCH erstatter hele `redirect_uris`-listen — inkluder alltid eksisterende URIer. diff --git a/tasks.md b/tasks.md index ca3bd84..db1732a 100644 --- a/tasks.md +++ b/tasks.md @@ -47,8 +47,7 @@ Uavhengige faser kan fortsatt plukkes. - [x] 1.2 Seed-data: opprett Vegards brukernode (`node_kind='person'`, `title='Vegard'`) og `auth_identities`-rad. Opprett Sidelinja samlings-node og `owner`-edge fra Vegard. - [x] 1.3 SpacetimeDB modul: opprett Rust-modul med `nodes` og `edges`-tabeller som speiler PG-skjema. Grunnleggende reducers for CRUD. Deploy til server. Ref: `docs/retninger/datalaget.md`, `docs/erfaringer/spacetimedb_integrasjon.md`. - [x] 1.4 Caddy-config: reverse proxy for maskinrommet (api.sidelinja.org), SpacetimeDB, og SvelteKit. Auto-TLS. Ref: `docs/setup/produksjon.md`. -- [~] 1.5 Authentik: opprett OIDC-provider og applikasjon for Synops. Konfigurer redirect URIs. Ref: `docs/erfaringer/authentik_oppsett.md`. - > Påbegynt: 2026-03-17T12:11 +- [x] 1.5 Authentik: opprett OIDC-provider og applikasjon for Synops. Konfigurer redirect URIs. Ref: `docs/erfaringer/authentik_oppsett.md`. ## Fase 2: Maskinrommet — skjelett