A microservices-based online banking application demonstrating agentic AI capabilities with .NET 9, Python, Go, React, and cloud-native Azure services deployed on AKS with Istio service mesh.
This is a demonstration application. It is not production ready, and is not a reference implementation. It is built to show architecture and agent behaviour to an audience, not to run a bank. Several deliberate shortcuts are documented in Production readiness below — read that section before using any part of this repository as a starting point for real work.
- Docker & Docker Compose
- go-task (Taskfile runner)
- Git, Node.js 18+ (for UI development)
- 8GB RAM, 10GB disk space
git clone https://github.com/briandenicola/online-banking-demo.git
cd online-banking-demo
cp .env.example .env
# Start all services
task local:up
# Seed demo data (optional)
./scripts/seed-data.sh- React UI: http://localhost:3000/
- API Gateway: http://localhost/
- Health Check: http://localhost/health
- Documentation Hub — Start here for all guides
- Local Development — Docker Compose setup, environment variables, hot reload workflows
- Azure Cloud Deployment — Terraform provisioning, AKS + Istio, Taskfile-driven deployment
- Chatbot Memory MVP — Agent Memory Toolkit rollout, validation, and rollback
- System Architecture — Service map, communication patterns, authentication, event pipeline
- Testing Guide — Playwright E2E test suite (4 phases, 195+ specs)
This project was built using AI-assisted development practices:
- ADRs — Architecture Decision Records capturing key technical choices
- Squad Guide — How the AI team framework (Squad) was used with specialized agent roles
- Copilot Integration — GitHub Copilot CLI usage, speckit workflow, and lessons learned
┌──────────────────────────────────────────────────────────────────┐
│ External Users / Clients │
└───────────────────────┬──────────────────────────────────────────┘
│
┌───────────▼────────────────┐
│ Istio Ingress Gateway │
│ (HTTP/HTTPS, envsubst) │
└───────────┬────────────────┘
│
┌────────────────┼────────────────┐
│ │ │
┌────▼────┐ ┌─────▼─────┐ ┌────▼─────┐
│ React │ │ .NET 9 │ │ Python │
│ UI App │ │ Services │ │ Agents │
└─────────┘ └─────┬─────┘ └────┬─────┘
│ │
└───────┬───────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
┌────▼────┐ ┌────▼─────┐ ┌────▼─────┐
│ Redis │ │ Cosmos DB│ │ Azure │
│ Streams │ │ (Entra) │ │ AI Foundry│
└─────────┘ └──────────┘ └──────────┘
Core .NET 9 Microservices (REST/HTTP, JWT-authenticated):
- User Service — Authentication, JWT token generation, user profiles
- Account Service — Account lifecycle, balance tracking
- Transaction Service — Transaction history, event publishing to Redis Streams
- Transfer Service — Money transfer orchestration, inter-service calls with JWT forwarding
Python Agent Services (FastAPI, AI-powered via Azure AI Foundry):
- Chatbot Service — AI financial advisor with Agent Framework, Cosmos chat persistence, account/transaction tools
- AI Service — Risk scoring, transaction categorization via Foundry agents
- Budget Service — Spending analysis and financial health insights
- Account Opening Service — AI-powered multi-agent pipeline for new account applications (document extraction, identity verification, KYC compliance, account provisioning via Azure AI Foundry and Content Understanding Service)
Infrastructure & Admin Services:
- Event Processor (Go) — Redis Streams consumer, async event routing
- Prompt Eval Service (.NET) — Prompt template management and admin evaluation UI; delegates eval execution to ai-service's LLM-as-judge pipeline (see ADR-006)
- UI Application (React 18 + MUI v9) — Web frontend with admin panel
- Event-Driven: Redis Streams (
banking-events) for inter-service communication - JWT Authentication: Tokens issued by User Service, validated across all services
- Agentic AI: Chatbot with real data tools, anomaly detection, budget analysis, AI-powered account opening, and LLM-as-judge prompt evaluation — all via Azure AI Foundry
- Chat Persistence: Cosmos DB-backed chat history with 30-day TTL
- Cloud-Native: AKS with Istio service mesh, Workload Identity, KeyVault CSI driver
- Private Networking: All PaaS services accessed via private endpoints with private DNS zones
- Infrastructure as Code: Terraform with AzureRM + AzAPI providers
- Observability: OpenTelemetry SDK + Application Insights
All operations are managed via go-task:
| Command | Description |
|---|---|
| Local Development | |
task local:up |
Start all services with Docker Compose |
task local:down |
Stop all services |
| Cloud Deployment | |
task cloud:up |
Full Azure environment (Terraform + AKS config) |
task cloud:infra:config |
One-time AKS setup (creds, namespaces, secrets, CSI) |
task cloud:build |
Build all container images via ACR |
task cloud:deploy |
Deploy manifests to AKS (repeatable) |
task cloud:tls:enable |
Install cert-manager + configure TLS (idempotent) |
task cloud:tls:status |
Check certificate status |
task cloud:down |
Destroy all Azure resources |
| Testing | |
task e2e:run |
Run all Playwright E2E tests |
task e2e:ui |
Interactive Playwright UI mode |
online-banking-demo/
├── docs/ # Documentation
│ ├── deployment-local.md # Local Docker Compose guide
│ ├── deployment-azure.md # Azure AKS deployment guide
│ ├── architecture.md # System architecture
│ └── testing.md # E2E testing guide
├── cluster-config/ # Kubernetes cluster configuration
│ ├── cert-manager/ # TLS certificates (ClusterIssuer, Certificate)
│ └── istio/gateway/ # Istio ingress gateway configuration
├── deploy/kustomize/ # Kubernetes manifests
│ ├── base/ # Service deployments, ConfigMap, SecretProviderClass
│ └── observability/ # OTEL collector, monitoring
├── infra/cloud/ # Terraform (AKS, Cosmos DB, Redis, AI Foundry, KeyVault)
│ ├── private-endpoints.tf # Private endpoints + DNS zones for all PaaS services
│ └── ai-connections.tf # AI Foundry project connections + App Insights link
├── src/
│ ├── user-service/ # .NET 9 — Authentication
│ ├── account-service/ # .NET 9 — Account management
│ ├── transaction-service/ # .NET 9 — Transaction history
│ ├── transfer-service/ # .NET 9 — Money transfers
│ ├── chatbot-service/ # Python — AI financial advisor (Agent Framework)
│ ├── ai-service/ # Python — Risk scoring, categorization
│ ├── budget-service/ # Python — Budget analysis
│ ├── account-opening-service/ # Python — AI-powered account opening pipeline
│ ├── event-processor/ # Go — Redis Streams consumer
│ ├── prompt-eval-service/ # .NET 9 — AI prompt evaluation
│ └── ui-app/ # React 18 + MUI v9 — Web frontend
├── tests/e2e/ # Playwright E2E test suite
├── Taskfile.yml # Root Taskfile (includes cloud, local, e2e)
├── Taskfile.cloud.yml # Azure deployment tasks
├── Taskfile.local.yml # Local development tasks
├── Taskfile.e2e.yml # E2E testing tasks
├── docker-compose.yml # Local services orchestration
└── .env.example # Environment variables template
Deployed to Azure using Terraform and Taskfile:
| Resource | Purpose |
|---|---|
| AKS | Kubernetes with Istio service mesh |
| Cosmos DB | Primary database (Entra RBAC auth) |
| Azure Managed Redis | Cache + event streaming (Balanced B0, port 10000/TLS) |
| Azure AI Foundry | AI agents + OpenAI models |
| Application Insights | Observability (OTEL SDK) |
| Key Vault | Secrets (synced to K8s via CSI driver) |
| Container Registry | Image storage (ACR, Premium SKU) |
| Private Endpoints | Private networking for all PaaS services (9 endpoints, 10 DNS zones) |
# Full deployment workflow
task cloud:up # Terraform + AKS configuration
task cloud:build # Build all images to ACR
task cloud:deploy # Deploy manifests to AKS
# Optional TLS
task cloud:tls:enable # cert-manager + Let's Encrypt (idempotent)See docs/deployment-azure.md for the complete guide.
- .NET 9 SDK: .NET services
- Python 3.11+: AI agent services
- Go 1.22+: Event processor
- Node.js 18+: React UI
# Keep infrastructure running
docker-compose up -d
# .NET service
cd src/user-service && dotnet watch run
# Python service
cd src/chatbot-service && uvicorn app.main:app --reload --port 8001
# React UI
cd src/ui-app && npm start- Services won't start: Increase Docker memory to 8GB+, check ports with
sudo lsof -i :80 - Redis errors:
docker-compose down -v && docker-compose up -d redis - JWT 401 errors: Clear browser localStorage, re-login for fresh token
- Azure 401s: Verify Workload Identity annotation on service account, check Entra RBAC roles
See docs/deployment-local.md for more troubleshooting.
This repository optimises for demonstrability, not operability. The shortcuts below are deliberate and known. They are listed so that nobody has to discover them the hard way, and so that anyone adapting this code knows what a real deployment would still have to build.
| Area | What this demo does | What production would need |
|---|---|---|
| Workload identity | All 11 services share one Kubernetes ServiceAccount federated to one managed identity holding Cosmos Data Contributor at account scope, plus Redis, Key Vault, Storage and AI roles. Any pod can read and write every container. | A managed identity per service, with role assignments scoped to the specific containers and secrets that service owns. |
| Service-to-service auth | The authority-service action broker forwards the caller's token downstream. A mediator client credential is provisioned end to end but never used. | A service credential with an authorization policy scoped to the specific actions it may perform — never blanket admin. |
| Action execution | The approval chain is complete and verified through co-signature. Execution is not wired — the target routes in config/authority-policy.yaml do not resolve and no UI control calls execute. |
Real routes, a contract test binding config targets to actual controllers, and idempotent downstream handlers. |
| Secrets | Bootstrapped into Key Vault by a script on a jump box, mounted via the CSI driver. | Managed rotation, no human-run bootstrap, no long-lived client secrets. |
| Data | Synthetic. Containers are recreated freely. | Migration testing against production-shaped data, backup/restore drills, retention and residency controls. |
| Tenancy | Single tenant, single environment, no rate limiting or quota enforcement on AI calls. | Per-tenant isolation and cost controls on model invocation. |
These are the failure patterns this codebase actually produced. Every one passed its test suite, and every one surfaced only when something genuinely ran. They generalise well beyond this repo.
- Fail-open on an absent field. This family appeared roughly six times here:
x === trueversusx !== falsediffering only onundefined;[].every()returning true for an empty list; a null publisher logging nothing; a query returning zero rows rather than an error. When you introduce a field, decide explicitly what an absent one means — and prefer a default that makes absence raise rather than pass. - A silent fallback turns a metric into theatre. An AI planner that quietly degrades to a deterministic script still emits confident-looking numbers. A demo that fails is embarrassing for five minutes; a demo that lies costs credibility. Make the mode an explicit declaration and fail closed when it cannot be honoured.
- Configuration that names things is never type-checked. Routes, queue names and topic names written in YAML drift from the code they point at, and mocks at that boundary hide it forever. Add a test that resolves every configured target against the real thing.
- Duplication is the bug. Nearly every serious defect here lived in a seam between two independently-stated facts, each internally coherent — two statements of an envelope shape, a fixture asserting one contract while the service implemented another. The fix is rarely to reconcile the copies; it is to delete one side.
- Environment parity hides port and hostname bugs. Values correct in
docker-composewere wrong in Kubernetes, and authentication was broken cluster-wide while every local test passed. - Test the guard by breaking it. If deliberately disabling a control does not turn a test red, that control is unverified regardless of how much coverage surrounds it.
MIT License — see LICENSE file for details.
Last Updated: May 2026 Repository: https://github.com/briandenicola/online-banking-demo
0 comments
log in to comment.