Open Banking-plattform – Teknisk översikt över vad vi byggt


Vi har byggt en Open Banking-plattform som ansluter till svenska banker via PSD2 (Payment Services Directive 2). Användare autentiserar med BankID, och plattformen hämtar kontoinformation och transaktioner från flera bankers API:er. All data lagras krypterat i AWS.

Projektet är ett experiment – vi vill se vad som går att bygga nu, med en målbild om en egen ekonomirådgivar-agent som får data från alla ens banker på ett samlat ställe. Detta är ett steg på vägen.

Status idag: Plattformen stödjer tre bankerSEB, Handelsbanken och Swedbank – och går mot deras sandbox-miljöer med simulerad data. För att gå mot riktig produktion krävs köp av kvalificerade certifikat (ett par tusenlappar). Det som skiljer sandbox från produktion är i praktiken bara datakällan; arkitekturen och koden är densamma.

Översikt

  • Användare: Loggar in med Cognito, kopplar sin bank via BankID (decoupled flow – BankID på mobilen), synkroniserar konton och transaktioner.
  • Teknisk stack: React 19, Vite, TypeScript, AWS Lambda, API Gateway v2, DynamoDB, Cognito, Secrets Manager, KMS.
  • Bankintegration: PSD2 AIS (Account Information Service) – SEB, Handelsbanken och Swedbank – kontolista, saldon, transaktionshistorik.
  • Tjänst: openbanking.ainiklas.se

Så ser det ut

Dashboardsvyn samlar total saldo, anslutna banker och en översikt över konton. Data kommer från bankernas sandbox-miljöer (mock), men visar hur aggregeringen fungerar över flera banker.

Open Banking – Dashboard med total saldo, anslutna banker och kontolista

Kontovyn visar alla konton med saldon från samtliga anslutna banker. Synk-knappen triggar hämtning från respektive banks API.

Open Banking – Kontovyn med saldon och synk-knapp

Anslutningsvyn visar vilka banker som är kopplade. Handelsbanken och SEB är anslutna via BankID, Swedbank är redo att anslutas. Här hanteras också återkallelse av consent.

Open Banking – Anslutningsvyn med Handelsbanken och SEB anslutna, Swedbank tillgänglig

Transaktionsvyn visar historik för ett enskilt konto. Här ett Handelsbanken-konto med kategoriserade transaktioner.

Open Banking – Transaktionshistorik för ett Handelsbanken-konto

Arkitektur

Användare (webbläsare)


┌───────────────────┐
│   CloudFront      │  CDN, HTTPS, Geo-restriction (EU)
└─────────┬─────────┘

    ┌─────┴─────┐
    │          │
    ▼          ▼
┌───────┐  ┌──────────────┐
│  S3   │  │ API Gateway  │  HTTP API, JWT (Cognito)
│ React │  │     v2       │
└───────┘  └──────┬───────┘

        ┌────────┼────────┐
        ▼        ▼        ▼
    ┌───────┐ ┌───────┐ ┌───────┐
    │ Bank  │ │ Bank  │ │Health │
    │ Auth  │ │ Sync  │ │ Lambda│
    └───┬───┘ └───┬───┘ └───────┘
        │         │
        │    ┌────┴────┐
        │    ▼         ▼
        │  ┌─────────────────┐  ┌──────────────┐
        │  │ Bank APIs       │  │  DynamoDB    │
        │  │ SEB / HB / SW  │  │  (KMS kryp)  │
        │  └─────────────────┘  └──────────────┘


  ┌─────────────────┐
  │ Secrets Manager │  Bank credentials, OAuth tokens
  └─────────────────┘

Frontend är en React-app hostad på S3 och serverad via CloudFront. All API-trafik går via API Gateway med JWT-authorizer (Cognito). Tre Lambda-funktioner: Bank Auth (anslutning, BankID-flöde, tokenutbyte mot SEB, Handelsbanken och Swedbank), Bank Sync (hämtning av konton och transaktioner från respektive bank), Health (statuskontroll). Varje bank har sin egen adapter bakom ett gemensamt gränssnitt.

Bankanslutningsflödet (Decoupled BankID)

Bankerna använder decoupled BankID – användaren autentiserar på mobilen via BankID-appen, inte i webbläsaren. Plattformen pollar respektive banks status-endpoint tills autentiseringen är klar. Flödet är i grunden detsamma för SEB, Handelsbanken och Swedbank, med bankspecifika adaptrar som hanterar skillnader i API-format.

  1. Användare väljer bank (SEB, Handelsbanken eller Swedbank) och klickar “Koppla”.
  2. Frontend anropar POST /api/bank/connect med vald bank.
  3. Lambda (Bank Auth) → anropar bankens auth-endpoint. Får tillbaka auth_req_id och autostart_token.
  4. Frontend visar länk/QR som öppnar BankID-appen (via autostart_token).
  5. Användare autentiserar i BankID på mobilen.
  6. Frontend pollar GET /api/bank/connect/{authReqId}/status var 2–3:e sekund.
  7. När status är COMPLETEFrontend anropar POST /api/bank/connect/{authReqId}/complete.
  8. Lambda byter auth_req_id mot access- och refresh-tokens via banken och sparar dem i Secrets Manager (KMS-krypterat).
  9. Lambda skapar consent-post i DynamoDB.
  10. Användaren ser banken som ansluten och kan synka konton och transaktioner.

I sandbox finns /simulate-endpoints som simulerar BankID-klartecken utan att använda riktig BankID – användbart för tester.

Datasynkroniseringsflödet

Efter anslutning kan användaren synka konton och transaktioner:

  1. Användare klickar “Synka”.
  2. Frontend anropar POST /api/sync.
  3. Lambda (Bank Sync) verifierar aktiv consent i DynamoDB.
  4. Hämtar access-token från Secrets Manager.
  5. GET /accounts → lista över konton.
  6. För varje konto: GET /accounts/{id}?withBalance=true → saldo.
  7. GET /transactions per konto → transaktionshistorik.
  8. All data sparas i DynamoDB med KMS-kryptering, TTL 90 dagar (enligt PSD2).

Säkerhet och PSD2

  • Kryptering: DynamoDB och Secrets Manager krypteras med KMS. All trafik över TLS 1.3.
  • Credentials: API-nycklar, client secrets och användartokens för samtliga banker ligger endast i Secrets Manager – aldrig i kod, env eller databas.
  • Data minimering: Lagrar kontonummer (maskerade), saldon, transaktionsbelopp, datum, beskrivningar. Sparar inte personnummer eller fullständiga namn från banken.
  • Consent: 90-dagars consent-cykel, explicit återkallelse, read-only AIS (ingen betalningsinitiering).

Infrastruktur och CI/CD

Allt är infrastruktur som kod (Terraform): CloudFront, S3, API Gateway, Lambda, DynamoDB, Cognito, Secrets Manager, KMS, WAF. GitHub Actions med OIDC kör build, test och deploy – ingen manuell AWS-klickning.

Sandbox vs produktion

AspektSandboxProduktion
Bank-API:erSandbox-miljöer (SEB, HB, Swedbank)Produktions-API:er
DataSimulerad, mockRiktiga konton, saldon, transaktioner
BankIDSimulerad (t.ex. /simulate)Riktig BankID
CertifikatUtvecklarcertifikat (gratis)Kvalificerade certifikat (kostnad)

Att gå live: Kräver köp av kvalificerade certifikat (qualifying certificates) från godkänd leverantör – ordning på ett par tusenlappar. Kod, arkitektur och infrastruktur är i princip oförändrade; det som byts är datakällan – från sandbox till produktion.

Sammanfattning

Plattformen visar hur man kan bygga en PSD2-kompatibel AIS-integration med:

  • Stöd för flera banker (SEB, Handelsbanken, Swedbank) via ett gemensamt adapter-mönster
  • Decoupled BankID (ingen bankuppgifter i webbläsaren)
  • Serverless stack (Lambda, DynamoDB, API Gateway)
  • Kryptering i vila och säker hantering av tokens
  • Tydlig separation mellan sandbox och produktion

Idag mot sandbox – med kvalificerade certifikat kan samma system användas mot riktiga bankdata från alla tre bankerna.