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 banker – SEB, 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.
Kontovyn visar alla konton med saldon från samtliga anslutna banker. Synk-knappen triggar hämtning från respektive banks API.
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.
Transaktionsvyn visar historik för ett enskilt konto. Här ett Handelsbanken-konto med kategoriserade transaktioner.
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.
- Användare väljer bank (SEB, Handelsbanken eller Swedbank) och klickar “Koppla”.
- Frontend anropar
POST /api/bank/connectmed vald bank. - Lambda (Bank Auth) → anropar bankens auth-endpoint. Får tillbaka
auth_req_idochautostart_token. - Frontend visar länk/QR som öppnar BankID-appen (via
autostart_token). - Användare autentiserar i BankID på mobilen.
- Frontend pollar
GET /api/bank/connect/{authReqId}/statusvar 2–3:e sekund. - När status är
COMPLETE→ Frontend anroparPOST /api/bank/connect/{authReqId}/complete. - Lambda byter
auth_req_idmot access- och refresh-tokens via banken och sparar dem i Secrets Manager (KMS-krypterat). - Lambda skapar consent-post i DynamoDB.
- 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:
- Användare klickar “Synka”.
- Frontend anropar
POST /api/sync. - Lambda (Bank Sync) verifierar aktiv consent i DynamoDB.
- Hämtar access-token från Secrets Manager.
GET /accounts→ lista över konton.- För varje konto:
GET /accounts/{id}?withBalance=true→ saldo. GET /transactionsper konto → transaktionshistorik.- 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
| Aspekt | Sandbox | Produktion |
|---|---|---|
| Bank-API:er | Sandbox-miljöer (SEB, HB, Swedbank) | Produktions-API:er |
| Data | Simulerad, mock | Riktiga konton, saldon, transaktioner |
| BankID | Simulerad (t.ex. /simulate) | Riktig BankID |
| Certifikat | Utvecklarcertifikat (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.