Use Case AI-Powered SDLC in a Bank: How We Run FlowSquad with Zero Data Leaving Our Data Centre

AI-Powered SDLC in a Bank: How We Run FlowSquad with Zero Data Leaving Our Data Centre

Ollama on-premise, local ChromaDB, SAML 2.0 with Keycloak, PostgreSQL on bare metal. A reference architecture for the most regulated environments — where data sovereignty is non-negotiable.
TL;DR

What Are the Data Sovereignty Requirements in a Banking Environment?

Banking institutions face a layered web of data sovereignty obligations that make cloud-based AI tools off-limits for anything touching source code, architecture documents, or customer-adjacent requirements. In the EU, DORA (Digital Operational Resilience Act) classifies source code repositories as critical information assets subject to ICT risk management controls. PCI DSS 4.0 Requirement 3.5 requires strong cryptography for cardholder data environments — which includes the systems that build and maintain payment software.

September 1, 2026 · 10 min read · BankingInsuranceGovernment

Beyond regulatory mandates, most banking IT security policies include an outright prohibition on sending proprietary source code or internal design documents to external APIs. This means the standard FlowSquad deployment — which calls OpenAI or Anthropic APIs — is off the table before the conversation starts.

FlowSquad's air-gapped/on-premise deployment mode was built specifically for this scenario. It replaces every cloud dependency with an on-premise equivalent: Ollama replaces cloud LLM APIs, ChromaDB replaces Pinecone, and the entire stack runs inside the bank's data centre with no egress traffic to the internet required at runtime.

Important: The air-gapped deployment requires pulling Docker images and Helm charts during initial setup. Plan for a one-time internet-connected bootstrap to a staging environment, followed by a transfer to the air-gapped data centre via approved media (USB, internal registry). After that, zero internet access is required for ongoing operation.

What Does the FlowSquad Air-Gapped Reference Architecture Look Like?

The architecture organises into four network zones, all within the data centre perimeter. Traffic flows inward from client devices through the application layer to the data and LLM layers — no traffic flows outward to the internet.

Zone 1 — Client Layer (Developer Workstations / VDI)
Chrome / Edge Browser Internal DNS resolution TLS 1.3 to FlowSquad
↓ HTTPS (TLS 1.3, internal CA cert) ↓
Zone 2 — DMZ / Load Balancer
HAProxy / NGINX (internal) WAF (ModSecurity) Internal TLS termination
↓ Internal network ↓
Zone 3 — Application Layer (Kubernetes Cluster)
FlowSquad App Pod ×3 Keycloak (SAML 2.0) Redis (session cache) Internal container registry
↓ Internal API calls only ↓
Zone 4a — LLM Layer (GPU Servers)
Ollama (Llama 2 70B) Ollama (Mistral 7B) Nomic Embed Text (embeddings) 2× NVIDIA A100 80GB
↓ Internal data calls ↓
Zone 4b — Data Layer (Bare Metal Servers)
PostgreSQL 16 (Primary) PostgreSQL 16 (Replica) ChromaDB (NVMe SSD) Vault (secrets)
◀ DATA CENTRE PERIMETER — NO EGRESS TO INTERNET ▶

How Is the LLM (Ollama) Deployed On-Premise?

Ollama is the on-premise LLM runtime that FlowSquad uses in air-gapped mode. It serves both completions (Llama 2 70B for complex tasks, Mistral 7B for fast tasks) and embeddings (Nomic Embed Text at 768 dimensions). The GPU server requires NVIDIA drivers 535+ and CUDA 12.1+.

FlowSquad communicates with Ollama over a private HTTP endpoint on port 11434, which is firewalled from all external access. In benchmarks on an A100 GPU, Ollama Llama 2 70B produces first tokens in under 1.8 seconds for story decomposition prompts — comparable to GPT-4 API latency for most tasks.

# FlowSquad Helm values for Ollama configuration (air-gapped)
llm:
  defaultProvider: ollama
  ollama:
    endpoint: "http://ollama-svc.ai-layer.svc.cluster.local:11434"
    defaultModel: "llama2:70b"
    fastModel: "mistral:7b"
    embedModel: "nomic-embed-text"
    timeoutSeconds: 120
    maxRetries: 2

# Verify Ollama is reachable from the FlowSquad pod
kubectl exec -n flowsquad deploy/flowsquad -- \
  curl -s http://ollama-svc.ai-layer.svc.cluster.local:11434/api/tags | \
  python3 -c "import sys,json; [print(m['name']) for m in json.load(sys.stdin)['models']]"
# Expected output:
#   llama2:70b
#   mistral:7b
#   nomic-embed-text:latest

Pull models from the internet to the staging environment first, then transfer via the bank's approved data transfer process. Models are large: Llama 2 70B is 39 GB, Mistral 7B is 4.1 GB, and Nomic Embed Text is 274 MB. Store them in an internal OCI-compliant registry (Harbor, Nexus) for reproducible deployments.

How Is ChromaDB Deployed Without Cloud Connectivity?

ChromaDB is FlowSquad's default vector database for air-gapped deployments. It runs as a stateful Kubernetes pod with a PersistentVolumeClaim backed by NVMe SSD storage for query performance. Unlike Pinecone, ChromaDB has zero external dependencies — all indexing and query operations are local.

Configure the VectorDB in the Helm values to point at the in-cluster ChromaDB service:

# ChromaDB configuration for air-gapped deployment
vectordb:
  provider: chromadb
  chromadb:
    host: "chromadb-svc.flowsquad.svc.cluster.local"
    port: 8000
    collectionName: "flowsquad-codebase"
  persistence:
    enabled: true
    storageClass: "local-nvme"
    size: "100Gi"

# Deploy ChromaDB as a StatefulSet
kubectl apply -f - <<'EOF'
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: chromadb
  namespace: flowsquad
spec:
  selector:
    matchLabels: { app: chromadb }
  template:
    spec:
      containers:
        - name: chromadb
          image: internal-registry.bank.local/chromadb:0.5.3
          ports: [{ containerPort: 8000 }]
          volumeMounts:
            - name: chroma-data
              mountPath: /chroma/chroma
  volumeClaimTemplates:
    - metadata: { name: chroma-data }
      spec:
        storageClassName: local-nvme
        resources:
          requests: { storage: 100Gi }
EOF

A fully indexed mid-size banking codebase (800,000 lines across 11 languages) occupies approximately 28 GB on disk in ChromaDB at the default embedding dimension of 768 (Nomic Embed Text). Query latency for AskProduct is under 180ms p95 on NVMe-backed storage.

How Does SAML 2.0 with Keycloak Handle Authentication?

In a banking environment, FlowSquad must integrate with the existing Identity Provider rather than maintaining its own user database. SAML 2.0 with Keycloak is the standard approach: Keycloak acts as the IdP, connected to the bank's LDAP/Active Directory, and FlowSquad acts as the Service Provider. All authentication flows stay inside the data centre.

# FlowSquad SAML 2.0 configuration in Helm values
auth:
  mfaRequired: true
  saml:
    enabled: true
    idpMetadataUrl: "https://keycloak.bank.internal/realms/banking/protocol/saml/descriptor"
    spEntityId: "https://flowsquad.bank.internal"
    acsUrl: "https://flowsquad.bank.internal/auth/saml/callback"
    nameIdFormat: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
    attributeMapping:
      email: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
      role: "flowsquad_role"     # Keycloak attribute → FlowSquad RBAC role
      firstName: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
    signRequests: true
    encryptAssertions: true   # Required for banking security policy

In Keycloak, create a Client with the following settings: Client Protocol: saml, Sign Documents: ON, Encrypt Assertions: ON. Add a mapper of type "Role List" to populate the flowsquad_role attribute. Map Keycloak roles (flowsquad-analyst, flowsquad-reviewer) to the corresponding FlowSquad RBAC roles. Authentication round-trips complete in under 350ms on the internal network.

What Does PostgreSQL on Bare Metal Look Like in This Architecture?

For the highest-regulation environments, FlowSquad recommends PostgreSQL on bare metal rather than a Kubernetes-managed operator, to satisfy requirements around dedicated hardware for financial data. The primary/replica setup provides high availability without cloud managed services.

# PostgreSQL bare-metal configuration for FlowSquad
# /etc/postgresql/16/main/postgresql.conf (relevant settings)
listen_addresses = '10.50.1.10'    # bind to internal network only
max_connections = 150
shared_buffers = 8GB               # 25% of 32GB RAM
effective_cache_size = 24GB
ssl = on
ssl_cert_file = '/etc/ssl/certs/pg-server.crt'  # internal CA
ssl_key_file = '/etc/ssl/private/pg-server.key'
log_statement = 'ddl'              # DDL audit logging for compliance
log_min_duration_statement = 1000  # slow query log ≥ 1s

# pg_hba.conf — allow only Kubernetes pod CIDR and Keycloak
hostssl flowsquad_prod flowsquad 10.100.0.0/16 scram-sha-256
hostssl flowsquad_prod flowsquad 10.50.2.0/24  scram-sha-256

Run the replica with hot_standby = on and synchronous replication (synchronous_commit = remote_apply) for zero data loss on failover. Automated failover uses Patroni — a PostgreSQL HA framework that integrates with Kubernetes via etcd. Recovery Point Objective (RPO) is effectively 0 seconds with synchronous replication.

How Do You Validate That Zero Data Leaves the Network?

After installation, perform a network egress validation to confirm that no FlowSquad component initiates outbound connections to the internet. This validation is typically required as part of the Change Management evidence package for banking IT governance.

# Step 1: Capture all egress traffic from the FlowSquad namespace for 30 minutes
kubectl exec -n flowsquad deploy/flowsquad -- \
  tcpdump -i eth0 -n 'dst net not 10.0.0.0/8 and dst net not 172.16.0.0/12 and dst net not 192.168.0.0/16' \
  -w /tmp/egress-capture.pcap &

# Step 2: Run a full generation workflow (Epic decomposition + AskProduct)
# ... (use the UI or CLI to trigger generation) ...

# Step 3: Check capture — expected result: 0 packets
tcpdump -r /tmp/egress-capture.pcap | wc -l
# Expected output: 0
# Any non-zero output indicates unexpected egress — investigate immediately.
Validation passed: At a Tier 1 bank deployment (45 engineers, 12 active projects), the egress validation captured 0 packets to external IPs during a 4-hour functional test. All LLM inference, embedding, and vector query traffic stayed within the 10.0.0.0/8 RFC-1918 range.
ComponentOn-Premise EquivalentNetwork ZoneExternal Dependency?
LLM (completions)Ollama + Llama 2 70BZone 4a (GPU servers)None at runtime
LLM (embeddings)Ollama + Nomic Embed TextZone 4a (GPU servers)None at runtime
Vector databaseChromaDB (StatefulSet)Zone 4b (data layer)None
Relational databasePostgreSQL 16 (bare metal)Zone 4b (data layer)None
Identity & SSOKeycloak + SAML 2.0Zone 3 (app layer)None (LDAP internal)
Secrets managementHashiCorp Vault (on-prem)Zone 4b (data layer)None
Container imagesHarbor internal registryZone 3 (app layer)None at runtime

Frequently Asked Questions

How does Ollama's model quality compare to GPT-4 for SDLC artifact generation?

Llama 2 70B and Mistral 7B produce high-quality stories, HLD/LLD documents, and test cases for most standard SDLC use cases — teams at regulated institutions report 85–90% of artifact quality compared to GPT-4 outputs, with the gap most visible on highly complex architectural decisions. For banking teams where data sovereignty is non-negotiable, this trade-off is universally accepted. FlowSquad's prompt templates are tuned specifically for Llama 2 and Mistral to maximise output quality within their context window constraints.

What GPU hardware is the minimum viable for running Ollama Llama 2 70B?

Llama 2 70B in 4-bit quantization (GGUF Q4_K_M) requires approximately 40 GB of VRAM. The minimum practical hardware is 2× NVIDIA A40 (48 GB VRAM each) or 1× A100 80 GB. For a team of 20+ engineers with concurrent generation requests, 2× A100 80 GB is recommended to avoid GPU queuing. Alternatively, Mistral 7B at 4-bit runs on a single RTX 4090 (24 GB VRAM) and is suitable for teams under 10 engineers with non-concurrent usage patterns.

How do we handle FlowSquad software updates in an air-gapped environment?

FlowSquad releases a monthly update bundle containing: new Docker images (pushed to your internal Harbor registry via approved transfer), updated Helm chart values, and Alembic migration scripts. The update process is: transfer images to internal registry → update Helm chart version in your GitOps repo → ArgoCD/Flux applies the rolling update. Average update window is under 20 minutes with zero downtime due to the rolling update strategy. A detailed update runbook is included in the air-gapped deployment package.

Can Keycloak connect to Active Directory instead of LDAP?

Yes. Keycloak supports Active Directory natively via its User Storage SPI with an LDAP provider configured for AD-specific attributes. Configure Connection URL: ldaps://ad.bank.internal:636, Users DN: OU=Engineers,DC=bank,DC=internal, and map the memberOf attribute to Keycloak groups, which then map to FlowSquad RBAC roles. The entire AD-to-FlowSquad group mapping configuration takes approximately 45 minutes for an experienced Keycloak administrator and does not require any changes to Active Directory itself.

Is the air-gapped deployment covered by FlowSquad's standard support SLA?

Yes, with one difference: P1 incidents in air-gapped environments require a secure channel for log sharing (the bank's secure file transfer system) rather than standard email. FlowSquad's enterprise support plan includes a dedicated support engineer familiar with air-gapped deployments, a maximum 4-hour response SLA for P1 issues, and a quarterly architecture review call. The air-gapped deployment package also includes an offline diagnostics tool that generates a sanitised support bundle (no source code included) for sharing with the FlowSquad support team.

dev.to Hashnode Medium LinkedIn