Hoppa till innehållet

Devportalen /portal/dev

Startsideportalens ekosystem för människa och agent

Dokumentationen / Yta

Åtkomstspärren

dok · atkomst
id: atkomst
namn: Åtkomstspärren
sammanfattning: Låser startsideportalens demo bakom en delad kod så att den kan ligga på en publik adress utan att vara öppen. Ingången /portal och devportalen /portal/dev ligger utanför spärren; projektportalen på roten har ingen spärr alls (ADR-040).
uppdaterad: 2026-10-19

ansvar:
- Spärra allt i startsideportalen utom en kort, stängd lista öppna vägar, före routningen, så att en ny yta inte kan glömma spärren.
- Hålla ingången /portal och devportalen /portal/dev öppna, så att beskrivningen av systemet går att läsa och hämta – också av verktyg som inte kan mata in en kod.
- Vara avstängd när ACCESS_CODE är osatt, så att lokal utveckling inte kräver en kod.
- Hålla koden borta ur kakan – den bär ett SHA-256-avtryck, inte klartext.
- Validera ?vidare= mot öppen vidarebefordran innan den följs.
- Aldrig utge sig för att vara autentisering, och aldrig vara behörighet i projektportalen. Spärren säger ingenting om vem användaren är.

filer:
- apps/portal/src/middleware.ts — Spärren för startsideportalen. Kör i edge-runtime, före all routning. Vägarna är appens egna – Next tar bort basvägen /portal före middleware och lägger på den i omdirigeringen.
- apps/portal/src/atkomst/kod.ts — arOppenVag, atkomstkod, fingeravtryck, likaSakert. Fri från Node-API:er så middleware kan använda den. sakerVidare kommer ur @startsidan/gemensamt.
- apps/portal/src/atkomst/actions.ts — lasUpp: jämför koden, sätter kakan, skickar vidare.
- apps/portal/src/atkomst/kod.test.ts — Tester på avtryck, jämförelse, vidarebefordran och de öppna vägarna.
- apps/portal/src/app/las-upp/page.tsx — Upplåsningssidan, /portal/las-upp. Satt till noindex.
- packages/gemensamt/src/felforsok.ts — Spärren mot gissningar: tio fel per adress och tio minuter, med den adress Traefik lägger sist i X-Forwarded-For. Delas med projektportalens konton och skrivnyckel, men räknas per app.

api:
- arOppenVag: (pathname: string) => boolean
  Ligger vägen utanför spärren? Vägen är appens egen, utan /portal. Listan är stängd: / (ingången), /dev, /api/health och /las-upp – var och en med allt under sig, utom roten.
- atkomstkod: () => string | undefined
  Koden ur miljön. Osatt eller tom betyder att spärren är avstängd.
- fingeravtryck: (kod: string) => Promise<string>
  SHA-256 i hex med prefix, så avtrycket bara betyder något här.
- likaSakert: (a: string, b: string) => boolean
  Jämförelse som tar lika lång tid oavsett var strängarna skiljer sig.
- sakerVidare: (vidare: unknown) => string
  Ur @startsidan/gemensamt/vidare. Släpper bara igenom interna vägar. Faller tillbaka på /.
- lasUpp: (formData: FormData) => Promise<void>
  Server action bakom upplåsningsformuläret.

kontrakt:
Detta är inte autentisering. Alla som kommer in delar samma kod, och rollen väljs fortfarande fritt på /portal. En modul som behöver veta vem användaren är ska vänta på SAML-sessionen i fas 4 – läs aldrig åtkomstkakan som en identitet. Projektportalens konton (ADR-039) är aldrig identiteten här.

Väg | Läge | Varför
/portal | Öppen | Prototypens ingång berättar vad prototypen är. Den visar inte demon, bara vägen in i den.
/portal/dev och allt under | Öppen | Portalen, designsystemet, dokumentationen, llms.txt och spec.json ska gå att läsa av både människor och verktyg.
/portal/api/health | Öppen | Dokploys healthcheck för start-portal markerar annars containern som sjuk.
/portal/las-upp | Öppen | Det är sidan man låser upp på.
/portal/start och allt under | Låst | Själva demon.
/portal/verktyg/*, /portal/sidor/* | Låst | Modulvyerna och sidorna i skalet.
/portal/flode/<namn> | Låst | Fokuslägena är demon i helskärm.
/portal/api/flows/*, /portal/api/min-ai | Låst | AI-anropen kostar pengar.
/portal/api/mock/*, /portal/api/kompetens/* | Låst | Demons data om påhittade personer.
Allt utanför /portal | Ingen spärr | Projektportalen (ADR-040). Öppen med flit; ändringsloggen, ritningen, organisationen och pitchen kräver ett konto (ADR-039).
/start, /dev, /verktyg … (gamla) | Omledning | Projektportalens next.config leder varje gammal adress permanent (308) till sin nya under /portal; utskickade länkar ska alltid fungera.

- ACCESS_CODE måste sättas i Dokploy innan domänen delas. Osatt = öppet, utan varning. Variabeln listas bara under start-portal i docker-compose.yml.
- /portal och /portal/dev är publika. Skriv dem därefter: namn på kommunens medarbetare och projektets deltagare får stå där, känsliga personuppgifter aldrig.
- Allt får hämtas men inget indexeras: robots.txt är öppen, så att AI-tjänster kan läsa en länk, och varje sida sätter noindex. noindex verkar bara på en sida som får hämtas (ADR-012, ändrat 20 oktober 2026).
- Byts koden loggas alla ut – avtrycket i kakan matchar inte längre. Det är den enda vägen att återkalla åtkomst.
- Middleware kör i edge-runtime: atkomst/kod.ts får bara använda Web Crypto, aldrig node:crypto.

beroenden: skal, bygge
beslut: ADR-012, ADR-029, ADR-040

kvarstår:
- Ingen utloggning ur spärren – bara kakans 30 dagar eller ett kodbyte.
- Kakan har sökvägen / och syns därför också för projektportalen, som inte läser den.
- Formulärets POST är verifierad i webbläsare, inte i test. Middleware och den delade logiken är verifierade i container respektive vitest.