ABK Alfouz
Security Architecture · Alfouz Gamification App

How the bank stays safe while customers play.

كيف يبقى البنك آمناً بينما يستمتع العملاء بالتطبيق.

The Alfouz Gamification App is built so that an exposed mobile-app endpoint can never do anything destructive to the customer's bank account. The app is allowed to create an app login, read the customer's Alfouz balance and tier, and add money to the Alfouz account. Every other bank operation — withdrawals, transfers, payee management, card actions, change of personal data — is not exposed by this app and cannot be reached through it.

This document explains the security model in plain terms, for review by the Central Bank of Kuwait and ABK's own security team.

01

Overview

نظرة عامة

The Alfouz Gamification App is a customer-engagement layer that runs alongside the Al Ahli Bank of Kuwait core banking system. It rewards existing Alfouz account holders for keeping a balance in the bank, through in-app spins, tier levels, and savings missions.

The app is a read-mostly client of the bank. It reads the customer's identity (via PACI), their Alfouz balance, and their Alfouz draw chances. The only write operation against the bank's records is a top-up deposit initiated through KNET, which goes directly to the customer's existing Alfouz account.

Read

Bank-held identity, balance, tier, draw chances

The app reads these values through bounded ESB endpoints and renders them in the UI.

Write

App login, top-up, in-app spin economy

The app creates an app-login record, processes KNET top-up to the Alfouz account, and maintains its own internal spin wallet. None of these are bank-core writes other than the top-up payment.

Never

Withdrawal, transfer, card or personal-data change

The app's API surface does not include any of these operations. They are not reachable through any code path or admin override.

02

API surface boundary

حدود واجهة البرنامج

The app's backend exposes a fixed, audited list of HTTP endpoints. Anything not on this list is not implemented; there is no admin override, hidden flag, or feature toggle that can expose additional bank operations.

Allowed operations PERMITTED

GroupEndpointsWhat it does
Identity POST /api/paci/initiate
POST /api/paci/poll
POST /api/wf2/finalize
Verifies civilId through PACI; binds the verified identity to the new app login.
App login POST /api/auth/login
POST /api/auth/refresh
POST /api/auth/forgot-password
Authenticates an existing app login; refreshes JWT; password reset through the same OTP gates.
Read — profile GET /api/profile
GET /api/dashboard
GET /api/tiers/me
Returns the customer's bank-held name, masked phone, current balance, current tier.
Read — Alfouz draw GET /api/draws
GET /api/draws/next
GET /api/chances
Returns the read-only Alfouz draw schedule, winners, and the customer's chance counts.
Write — top-up POST /api/topups
POST /api/topups/{id}/confirm
Initiates a KNET payment that credits the customer's existing Alfouz account. Money never enters the app's own accounts.
App-internal — spins GET /api/spins
POST /api/spins/{id}/reveal
GET /api/missions
Manages the in-app spin wallet and savings missions. No bank-core writes.

Explicitly not exposed DENIED

The following bank operations exist in the core banking system, but the Alfouz Gamification App does not implement any endpoint or code path that can trigger them:

If an attacker fully compromised the mobile API server, the worst they could do is read the data listed in the Allowed table above, push KNET top-ups to customers' Alfouz accounts (which would add money to those accounts, not take any), and write to the app-internal spin wallet (which is not real money). They cannot withdraw, transfer, or change any bank record.

03

Identity & authentication

الهوية والمصادقة

The app's identity model has two layers: an upstream PACI verification (one-time at registration and at password recovery) and an app-login secret (password) used for every session afterwards. Both are validated server-side; the device never asserts identity by itself.

PACI · root of trust

The Civil ID is verified through Kuwait Mobile ID (Hawiyti)

At registration and at password recovery, the server initiates a PACI session and binds the resulting requestId to the submitted civilId server-side. The user authorises the disclosure inside the official Hawiyti app. The server never trusts a client-asserted “PACI passed” flag.

App login

civilId + password, validated server-side

The app password is hashed with a per-user salt; the server never transmits or logs the plaintext beyond the single login request. JWT tokens are issued on successful login with a short lifetime; refresh requires a valid refresh token.

Anti-impersonation

A client cannot submit civilId = A, complete PACI for A, then submit civilId = B at finalize and inherit the verification. The civilId is recovered from the server-side requestId binding on every step, not from the client's request body. If the bodies disagree, the request fails closed.

04

Authorization

التفويض

Every authenticated endpoint requires a valid JWT bound to a single customer. The server derives the target customerId from the JWT, never from a request parameter. A customer cannot read or write another customer's data by changing a URL parameter or request-body field.

05

Data protection

حماية البيانات
In transit

TLS 1.2+ end-to-end

All API traffic is HTTPS. The .app TLD is HSTS-preloaded by Google, so browsers and the Flutter HTTP client refuse plaintext connections to any alfouz.app hostname.

At rest

Encrypted database storage

Customer data lives in SQL Server with transparent data encryption. Password hashes use a strong per-user salt; OTPs are stored hashed; PACI requestIds live in a 10-minute TTL cache.

On device

Masked PII only

The bank-held phone number is never returned to the device in full. The server returns a masked display string (e.g. +9655•••0002) as an opaque token. The same masking applies to email and any other identifier.

Logs

No PII in application logs

Application logs record event types and customer ids, never raw civilIds, phone numbers, emails, OTP values, or passwords. SQL parameter values are redacted before logging.

06

Audit & logging

التدقيق والسجلات

Every gate in the registration and login flows emits a discrete server-side event tied to a session identifier. The full registration of any customer is reconstructable from the audit log alone, without consulting the production database.

EventCaptured
PACI initiatecivilId hash, requestId, server timestamp, source IP
PACI verifiedrequestId, PACI response code, server timestamp
Phone OTP sent / validatedcustomerId, channel = Phone, attempt counter, timestamp
Email OTP sent / validatedcustomerId, channel = Email, attempt counter, timestamp
Password setcustomerId, hash version, timestamp (plaintext never logged)
RegisteredcustomerId, civilId hash, timestamp (closes the WF2 session)
Login success / failurecivilId hash, source IP, timestamp, failure reason if any
Top-up initiated / completedcustomerId, KNET reference, amount, timestamp
Spin revealcustomerId, spinPoolId, prizeId (if any), shuffle audit id, timestamp

Audit events are written synchronously with the operation they record. A spin reveal that fails to write its audit row also fails to commit the reveal — there is no path that produces an outcome without an audit trail.

07

Rate limiting

تحديد المعدّل
08

Threat model

نموذج التهديدات
ThreatMitigation
civilId substitution — client submits civilId A, completes PACI for A, then sends civilId B at finalize hoping to inherit A's verification. Server recovers the verified civilId from the PACI requestId binding, not the client's request body. Mismatch fails closed.
OTP brute-force — attacker tries all six-digit codes. Server-side validation only, attempt-capped, channel-scoped, single-use, plus issuance rate limit prevents code-pool refill.
OTP replay — reuse of a previously seen valid OTP. OTPs are marked consumed on first valid use; reuse fails. OTPs also expire on a short TTL.
Channel cross-consumption — using a phone OTP to validate the email gate or vice versa. OTPs are issued with a Channel attribute; validation requires the code and matching channel.
JWT replay — stolen token used after the user logs out. Short access-token lifetime; logout invalidates the refresh token server-side.
API host compromise — the mobile API server is breached. API surface allowlist prevents the attacker from invoking any withdrawal, transfer, payee, card, or personal-data operation. Worst case: read profile data and push KNET top-ups that add money to customers' accounts.
Database compromise — SQL Server access by an attacker. Passwords are hashed with a per-user salt; OTPs are short-TTL and stored hashed; civilIds are stored as full values for bank operations but never returned to the device in full; encryption at rest applies.
Man-in-the-middle — intercepting API traffic. TLS 1.2+ end-to-end; HSTS preload via the .app TLD; certificate pinning in the Flutter HTTP client for the production hostname.
Social engineering — fake prize message asking the customer for card details. The Diraya in-app financial-literacy module presents a daily anti-fraud scenario and rewards the customer for choosing the safe response.
09

Bank-core isolation

عزل النواة البنكية

The mobile API does not talk to the bank's core banking system directly. It communicates through a bounded ESB adapter that exposes only the operations the app needs:

The ESB adapter rejects any call that does not match this allowlist. A vulnerability in the mobile API server cannot reach SendMoney, WithdrawCash, UpdateCustomerData, OpenAccount, or CloseAccount — those operations exist in the core but are not on the ESB allowlist this app uses.

The credit operation is also bounded: it accepts only a positive amount, only the customer's own Alfouz account as destination (derived from the JWT, not the request body), and only after KNET has confirmed the payment at its end.

10

Operational posture

الوضع التشغيلي
Hosting

Runs inside the bank's production environment

The backend is hosted on the bank's own production infrastructure, behind the bank's existing network controls, firewalls, and monitoring. It is not operated on any third-party public cloud. The app server reaches the core only through the bounded ESB adapter described above.

Cutover

Integration-ready, simulation for testing

During testing the app runs against deterministic in-process simulators for PACI and the bank Alfouz lookup. Connecting to the bank's live ESB endpoints flips a single configuration flag; no schema or code change is required.

Change control

Audited, out-of-band releases

Releases follow the bank's production change-management process. The application server exposes no interactive remote shell; each change is applied through an audited pipeline and attributed to an authenticated operator.

Monitoring

Health endpoints + web-server access logs

Health endpoints confirm service state on every release. Web-server request logs capture every API call with timestamp, source IP, status, and a customer hash — never raw PII.

11

Compliance summary

ملخّص الامتثال
Identity

PACI as root of trust

Verification is server-resolved against a Kuwaiti government source on every registration and password recovery. The client never asserts identity.

Boundary

No destructive bank operations

The app's API surface is an audited allowlist. Withdrawal, transfer, card, payee, and personal-data operations are not implemented and not reachable through any admin override.

Audit

Every gate is an event

Each step emits a server-side event with a session identifier. Audit and operation commit together — one without the other is not possible.

PII

Masked to the device

Bank-held phone, email, and other identifiers are returned to the device only as masked opaque display strings. Application logs never record raw PII.

Consumer protection

Daily anti-fraud education

The Diraya module surfaces a short anti-fraud scenario each day inside the app, in Arabic and English, with a small in-app reward for engagement.

Reach-back

Available for follow-up review

The Al Ahli Bank of Kuwait Alfouz team is available to walk the Central Bank of Kuwait's reviewers through any gate, endpoint, audit event, or threat-model entry in person.

Three points to remember. The bank account is read-mostly. There is no withdrawal, transfer, or destructive operation exposed by the app. Every operation is audited end-to-end.