Kommunsvar

Teknik och säkerhet

Systemskiss

Invånarens webbläsare
  │  HTTPS (TLS 1.2 eller senare), port 443
  ├── kommunens webbplats ── laddar chattens skript från https://chatt-test.stabilsajt.se
  │
  └── https://chatt-test.stabilsajt.se
        ├── Chatt-API ──────────── Databas (PostgreSQL med pgvector och pg_trgm)
        │      └── AI-modell: Claude (Anthropic) via Anthropics API, modellerna claude-sonnet-5-5 och claude-haiku-5-5
        ├── Administration ─────── inloggning via kommunens IdP (OIDC eller SAML 2.0)
        ├── Inläsning ──────────── hämtar godkända källor över HTTPS
        ├── REST-API /api/v1 ──── kommunens integrationsplattform (OAuth 2.0)
        ├── Schemaläggare ──────── inläsningar, testkörningar, utskick, gallring
        └── Vidareskickning ────── e-post till funktionsbrevlåda eller webhook

Trafik som behövs:

Från Till Port Syfte
Invånarens webbläsare https://chatt-test.stabilsajt.se 443 Chattens skript och API
Administratörens webbläsare https://chatt-test.stabilsajt.se 443 Administration
Tjänsten Kommunens webbplats 443 Inläsning av källor
Tjänsten Kommunens IdP 443 Metadata och tokens vid inloggning (OIDC)
Kommunens integrationsplattform https://chatt-test.stabilsajt.se/api 443 REST-API
Tjänsten Kommunens webhook eller e-post 443 / 587 Vidareskickade frågor, om det används

Ingen trafik initieras från tjänsten in i kommunens interna nät, utöver en webhook som kommunen själv anger. Systemskissen uppdateras med datum när något ändras.

Driftmiljö

Driftmiljö, region, redundans och säkerhetskopiering beskrivs i avtalet för den här installationen. Säkerhetskopior är krypterade, lagras åtskilt från databasen och sparas högst 29 dagar, så att all data kan vara raderad inom 30 dagar efter avtalets slut.

Så tas ett svar fram

  1. Invånarens text maskeras: personnummer, samordningsnummer, telefonnummer, e-postadresser, kortnummer och kontonummer byts mot platshållare. Bara den maskerade texten sparas och skickas vidare.
  2. Frågan sorteras av en mindre AI-modell (claude-haiku-5-5): språk, ämne, spärrat ämne, om invånaren vill prata med en människa, om meddelandet försöker kringgå reglerna, och sökfraser på svenska.
  3. Spärrade ämnen och önskemål om människa besvaras med kommunens texter och kontaktvägar, utan att något svar genereras.
  4. Kunskapsbasen söks med svensk fulltextsökning (med prefix för sammansatta ord), sökning på ord utan böjning, likhet i rubriker och, om det är påslaget, vektorsökning. Resultaten vägs ihop och viktas med källornas prioritet. Högst två avsnitt per sida tas med.
  5. Svaret skrivs av claude-sonnet-5-5. Avsnitten skickas som sökresultat med källhänvisningar påslagna, så att varje del av svaret pekar på de avsnitt det bygger på. Räcker underlaget inte svarar modellen med en fast kod och chatten visar kommunens text för obesvarade frågor.
  6. Kontroller innan svaret visas: svar utan källa visas inte, svar som innehåller den hemliga kontrollkoden eller långa delar av instruktionerna stoppas, och faktakontrollen jämför belopp, datum, tider och kontaktuppgifter med källtexten.
  7. Svaret, utfallet, ämnet, modellversionen och svarstiden sparas. En statistikhändelse utan personuppgifter sparas separat.

Skydd mot manipulation

  • Kommunens regler ligger i systeminstruktionen och har företräde. Invånarens text och källtexterna skickas som innehåll och är märkta som innehåll.
  • Chatten har inga verktyg och kan inte utföra handlingar, bara svara med text.
  • Varje samtal är isolerat. Ett samtal nås bara med en signerad nyckel som webbläsaren får när samtalet startar, och chatten har inget minne mellan samtal.
  • Instruktionerna innehåller en hemlig kontrollkod. Visas den, eller långa delar av instruktionerna, i ett svar stoppas svaret och händelsen loggas.
  • En säkerhetsfrågebank (försök att få chatten att strunta i reglerna, rollspel, inbäddade instruktioner, försök att få fram instruktionerna) finns i varje webbplats testbank och körs vid ändringar och modellbyten.

Inläsning

Inläsningen följer robots.txt och Crawl-delay, skickar villkorade förfrågningar (ETag och Last-Modified), hoppar över sidor märkta noindex och läser högst 20 MB per fil. Adresser som pekar på interna eller privata nät hämtas aldrig, och varje omdirigering kontrolleras på nytt. Inläsningen körs i korta steg och sparar sin status, så att den klarar omstarter och kan följas i realtid. Schemalagda inläsningar startar utan att hindra varandra.

Inloggning och behörighet

Administratörer loggar in via kommunens IdP med OpenID Connect (med PKCE) eller SAML 2.0 (signerade svar krävs). Kommunens katalog styr åtkomsten: den som saknar en kopplad grupp nekas, och ett konto som stängs i katalogen kan inte logga in igen. Tjänsten kan dessutom kräva att IdP:n intygar tvåfaktorsautentisering.

Tillfälliga lokala konton har lösenord (scrypt) och engångskod (TOTP). Fem felaktiga försök låser kontot i 15 minuter. Sessioner gäller i högst tio timmar och upphör efter 60 minuter utan aktivitet. Sessionskakan är HttpOnly, Secure och SameSite=Lax.

Inloggningar, misslyckade inloggningar, ändrade behörigheter och alla ändringar loggas i ändringsloggen.

REST-API

API:t följer Diggs REST API-profil: version i adressen (/api/v1), OpenAPI 3.1-specifikation på https://chatt-test.stabilsajt.se/api/v1/openapi.json, resursen api-info, fält i camelCase, datum enligt RFC 3339 med svensk tidszon, fel enligt RFC 7807, sidindelning med page och limit med _meta och _links, och X-RateLimit-rubriker. Autentisering sker med OAuth 2.0 client credentials. Åtkomsttoken gäller i fem minuter, uppdateringstoken i 24 timmar och kan användas en gång. Basic- och Digest-autentisering stöds inte. Se API-dokumentationen.

Kryptering

All trafik går över HTTPS med TLS 1.2 eller senare och HSTS. Hemligheter i databasen (engångskodernas nycklar, IdP:ns klienthemlighet, webhook-hemligheter) är dessutom krypterade med AES-256-GCM. API-klienternas hemligheter och sessionsnycklar sparas bara som hashvärden.

Schemalagda händelser och loggning

Inläsningar, testkörningar, utskick, nya försök med vidareskickade frågor och gallring körs av en schemaläggare som startar varje minut. Varje händelse loggas med tid och resultat och syns under Ändringslogg, fliken Drifthändelser. Fel loggas med en referens som visas för användaren, utan tekniska detaljer.

Versionsbyten

Databasändringar görs med numrerade migreringar som körs i en transaktion och testas mot en kopia av databasen innan de körs i produktion. Ingen information går förlorad vid versionsbyte. Webbplatsernas inställningar är versionerade och kan återställas.

Byte av AI-modell

Vilken modell och version som svarar loggas för varje svar och visas under Översikt och i API:t (/model-versions). Inför ett modellbyte körs varje kommuns frågebank mot den nya modellen och jämförs med den nuvarande. Kommunen informeras minst 30 dagar i förväg och kan testa den nya modellen i testläget.