Skip to main content

Sovereign AI Security Gateway & Zero-Trust Perimeter

An enterprise-grade, zero-license-tax Sovereign AI Security Gateway & Zero-Trust Perimeter deployed on the OpenCloud (Okustera) platform.

This reference architecture demonstrates a hardened production integration of Fortinet FortiGate-VM Next-Generation Firewalls (NGFW), OpenStack Octavia Amphora Load Balancers (LBaaS), Microsoft Presidio in-line PII Sanitization, and the Model Context Protocol (MCP) tool execution plane, interfacing with private sovereign language models (qwen2.5:1.5b and deepseek-r1:1.5b) running entirely on the tenant Kubernetes compute plane.

A live, publicly accessible instance of this workload is published at:

๐ŸŒ Live Application Dashboard: https://shield.okustera.com

The complete runnable source repository for this workload is available on GitLab at Haroyan/okustera-secure-ai-gateway (or locally in your workspace at okustera-secure-ai-gateway/).


1. System Architecture & Packet Flowโ€‹

The system employs a defense-in-depth, hub-and-spoke network perimeter where untrusted external traffic is scrubbed at the network edge, inspected by next-gen virtual firewalls, stripped of sensitive personal identifiers (PII) before reaching AI models, and guarded against server-side request forgery (SSRF) during agentic tool execution:


2. Interactive Web UI Dashboard & Security NOCโ€‹

The project includes an interactive web dashboard and Network Operations Center (NOC) served securely over HTTPS (Port 443) at https://shield.okustera.com/:

  • Live Security KPI Telemetry: Real-time metric counters for total prompts inspected, PII tokens sanitized, FortiGate threat attacks dropped, MCP agent tools executed, and end-to-end processing latency.
  • Pre-Configured Enterprise Scenarios:
    • Banking & Financial Ledger: Ingests customer prompts with real-world names, SSN, and IBAN numbers; sanitizes them with Presidio; executes an MCP tool call to query private account balances; and deanonymizes the response in a secure enclave.
    • Healthcare / HIPAA PHI: Ingests patient clinical inquiries containing Patient Names, Medical Record Numbers (MRN), and symptoms; strips PHI before model inference.
    • Threat Drill 1 (MCP SSRF Exploit Probe): Simulates an agentic prompt injection attempting to coerce an LLM into probing link-local cloud metadata (http://169.254.169.254/); demonstrates immediate FortiGate East-West drop via policy FGT-POL-001-ANTI-SSRF-METADATA.
    • Threat Drill 2 (Ingress SQL Injection Attack): Injects an OWASP SQLi payload (' OR 1=1--) in the prompt body; demonstrates immediate HTTP 403 Forbidden rejection at the edge firewall before compute or AI models are touched.
  • 5-Phase Pipeline Execution Stepper: Real-time visual status progression through each phase:
    1. Octavia & FortiGate Perimeter Inspection (WAF, rate limiting, and DDoS scrubbing)
    2. Microsoft Presidio Entity Recognition & Anonymization (in-line zero-retention masking)
    3. Model Context Protocol (MCP) Tool Execution (transit network authorization)
    4. Sovereign Local Model Generation (in-cluster qwen2.5:1.5b or deepseek-r1:1.5b)
    5. Reversible Deanonymization Enclave (ephemeral session-scoped entity restoration)

3. Core Capabilities Demonstratedโ€‹

A. Advanced Perimeter & Load Balancing (Octavia + FortiGate-VM)โ€‹

  • OpenStack Octavia Amphora Ingress: Layer 4/7 TCP load balancing distributes incoming traffic across redundant firewall appliances with automated health monitoring and active-standby failover.
  • FortiGate Next-Gen Virtual Firewall (vfw.small): Enforces Layer 7 WAF inspection, blocking SQLi, XSS, and remote code execution (RCE) attacks with immediate HTTP 403 responses.
  • FGCP Active-Passive Clustering: Heartbeat synchronization across an isolated HA subnet enables sub-second stateful failover with zero session drop.

B. Hub-and-Spoke Microsegmentation & Advanced SDN Routingโ€‹

  • Neutron allowed_address_pairs: Standard OpenStack Neutron port security enforces anti-spoofing by dropping any packet whose source IP does not match the port allocation. To enable FortiGate-VM to operate as a transit router for spoke VPCs, allowed_address_pairs { ip_address = "0.0.0.0/0" } is enabled on the LAN interface.
  • Subnet Route Interception (openstack_networking_subnet_route_v2): All outbound egress from spoke subnets is forced through the FortiGate LAN interface by declaring a 0.0.0.0/0 next-hop route table entry, eliminating bypass vectors.

C. In-Line Reversible PII Masking (Microsoft Presidio 2.2)โ€‹

  • Zero Model Data Retention: Scans raw prompt text before it reaches any LLM or persistent audit log, replacing sensitive entities with deterministic, type-aware tokens:
    • Person names: <PERSON_1>, <PERSON_2>
    • Financial identifiers: <IBAN_CODE_1>, <CREDIT_CARD_1>
    • Social Security Numbers: <US_SSN_1>
    • Healthcare identifiers: <MEDICAL_RECORD_NUMBER_1>
  • Ephemeral Session Vault: Entity mappings are held strictly in an in-memory, session-scoped cryptographic vault with automatic TTL expiry. When the model returns a response referencing <PERSON_1>, the gateway restores the original entity name before transmitting the final output to the authenticated user.

D. Model Context Protocol (MCP) with East-West Anti-SSRF Guardโ€‹

  • Standardized Agent Tool Bus: Implements Anthropic's Model Context Protocol (MCP), exposing structured tools (query_customer_ledger, lookup_sovereign_policy, execute_risk_score).
  • Strict Anti-SSRF Policy: Prompt injection attacks that attempt to weaponize agent tools to probe cloud metadata (169.254.169.254) or Kubernetes control plane ports (6443, 2379) are intercepted and dropped at the SDN firewall boundary by policy FGT-POL-001-ANTI-SSRF-METADATA.

E. Sovereign In-Cluster AI Model Servingโ€‹

  • Interacts directly with in-cluster local models (qwen2.5:1.5b and deepseek-r1:1.5b) running on the Okustera Kubernetes compute plane with zero external cloud egress fees and zero external telemetry leakage.

4. Network Topology & IP Allocation Planโ€‹

Segment / NetworkDocumentation CIDR (RFC 5737)Gateway InterfaceRole & Security Invariants
Hub WAN DMZ198.51.100.0/24198.51.100.1โ€ข Octavia Amphora VIP: 198.51.100.10
โ€ข FortiGate-VM port1 (WAN): 198.51.100.254
โ€ข Public Floating IP attached to Octavia VIP.
Hub Transit LAN198.51.101.0/24198.51.101.1โ€ข FortiGate-VM port2 (LAN): 198.51.101.254
โ€ข AI Gateway & Presidio Pods: 198.51.101.50
โ€ข allowed_address_pairs = ["0.0.0.0/0"] enabled.
Hub HA Sync192.0.2.0/24Noneโ€ข FortiGate-VM port3 (HA): 192.0.2.1
โ€ข Dedicated FortiGate Clustering Protocol (FGCP) heartbeat link.
Spoke MCP Tools203.0.113.0/24203.0.113.1โ€ข Model Context Protocol tools and private DBs.
โ€ข Subnet Route: 0.0.0.0/0 -> Next-Hop 198.51.101.254.

5. Directory Layoutโ€‹

okustera-secure-ai-gateway/
โ”œโ”€โ”€ README.md # Master architecture and operations manual
โ”œโ”€โ”€ app/
โ”‚ โ”œโ”€โ”€ main.py # FastAPI application & OpenAI proxy endpoint
โ”‚ โ”œโ”€โ”€ requirements.txt # Python dependencies (presidio-analyzer, presidio-anonymizer, fastapi, uvicorn)
โ”‚ โ”œโ”€โ”€ Dockerfile # Multi-stage container definition
โ”‚ โ”œโ”€โ”€ engine/
โ”‚ โ”‚ โ”œโ”€โ”€ ai_gateway.py # Orchestrator coordinating Presidio, MCP & LLM
โ”‚ โ”‚ โ”œโ”€โ”€ presidio_service.py # Presidio Analyzer & Anonymizer with custom patterns
โ”‚ โ”‚ โ””โ”€โ”€ mcp_server.py # Model Context Protocol server with anti-SSRF guard
โ”‚ โ””โ”€โ”€ templates/
โ”‚ โ””โ”€โ”€ index.html # Interactive visualizer dashboard and threat simulator
โ”œโ”€โ”€ config/
โ”‚ โ””โ”€โ”€ fortigate.conf # Declarative FortiOS 7.x appliance configuration
โ”œโ”€โ”€ terraform/
โ”‚ โ”œโ”€โ”€ main.tf # Provider configuration (okustera & openstack)
โ”‚ โ”œโ”€โ”€ networking_hub.tf # Hub VPC: WAN, LAN, HA Sync subnets & ports
โ”‚ โ”œโ”€โ”€ networking_spoke.tf # Spoke VPC: MCP subnet & static route interception
โ”‚ โ”œโ”€โ”€ loadbalancers.tf # Octavia Amphora Ingress Load Balancer & VIP
โ”‚ โ”œโ”€โ”€ fortigate_vm.tf # Multi-NIC FortiGate-VM instance provisioning
โ”‚ โ”œโ”€โ”€ ai_gateway_workload.tf # Kubernetes deployment manifest for tenant namespace
โ”‚ โ”œโ”€โ”€ variables.tf # Input variables and sizing parameters
โ”‚ โ””โ”€โ”€ outputs.tf # VIPs, endpoints, and route outputs
โ”œโ”€โ”€ k8s/
โ”‚ โ”œโ”€โ”€ edge-ingress.yaml # Undercloud NGINX Ingress (shield.okustera.com)
โ”‚ โ”œโ”€โ”€ apisix-ingress.yaml # Tenant APISIX Route & Cert-Manager TLS
โ”‚ โ””โ”€โ”€ shield-deployment.yaml # Kubernetes Deployment & Service in tenant-shield
โ””โ”€โ”€ scripts/
โ”œโ”€โ”€ deploy_tenant.sh # Cluster build and deployment automation
โ””โ”€โ”€ verify_security_suite.sh # Automated 6-test verification and threat simulation

6. Declarative Manifests & Code Implementationโ€‹

A. Undercloud & Tenant APISIX Ingressโ€‹

1. Undercloud Edge Ingress (k8s/edge-ingress.yaml):

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: omc-shield-ingress
namespace: openstack
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "20m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/upstream-vhost: "shield.okustera.com"
nginx.ingress.kubernetes.io/enable-modsecurity: "true"
nginx.ingress.kubernetes.io/enable-owasp-core-rules: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- shield.okustera.com
secretName: shield-tenant-tls
rules:
- host: shield.okustera.com
http:
paths:
- backend:
service:
name: okustera-demo-tenant-gateway
port:
number: 80
path: /
pathType: Prefix

2. Tenant APISIX Route & Cert-Manager TLS (k8s/apisix-ingress.yaml):

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: shield-okustera-tls
namespace: tenant-shield
spec:
secretName: shield-okustera-tls
issuerRef:
name: selfsigned-cluster-issuer
kind: ClusterIssuer
dnsNames:
- "shield.okustera.com"
---
apiVersion: apisix.apache.org/v2
kind: ApisixTls
metadata:
name: shield-tls
namespace: tenant-shield
spec:
hosts:
- "shield.okustera.com"
secret:
name: shield-okustera-tls
namespace: tenant-shield
---
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
name: shield-gateway-route
namespace: tenant-shield
spec:
ingressClassName: apisix
http:
- name: shield-app
priority: 100
match:
hosts:
- "shield.okustera.com"
paths:
- "/*"
backends:
- serviceName: sovereign-ai-gateway-service
servicePort: 8080
plugins:
- name: cors
enable: true
config:
allow_origins: "*"
allow_methods: "GET,POST,OPTIONS"
allow_headers: "Authorization,Content-Type,X-API-Key,apikey"
- name: proxy-rewrite
enable: true
config:
headers:
remove:
- "X-OMC-Caller-Role"
- "X-OMC-Tenant-ID"
set:
X-OMC-Tenant-ID: "tenant-demo-shield"

B. Hub-and-Spoke Terraform Networking (terraform/)โ€‹

# 1. FortiGate LAN Port with Transit Forwarding Allowed
resource "openstack_networking_port_v2" "fgt_lan_port" {
name = "fgt-lan-transit-port"
network_id = openstack_networking_network_v2.hub_lan.id

fixed_ip {
subnet_id = openstack_networking_subnet_v2.hub_lan_subnet.id
ip_address = "198.51.101.254"
}

# Allow FortiGate to route for spoke subnets
allowed_address_pairs {
ip_address = "0.0.0.0/0"
}
}

# 2. Intercept Spoke Subnet Egress to FortiGate LAN IP
resource "openstack_networking_subnet_route_v2" "spoke_to_fgt" {
subnet_id = openstack_networking_subnet_v2.spoke_mcp_subnet.id
destination_cidr = "0.0.0.0/0"
next_hop = "198.51.101.254"
}

# 3. Octavia Amphora Load Balancer VIP
resource "openstack_lb_loadbalancer_v2" "ingress_lb" {
name = "shield-ingress-lbaas"
vip_subnet_id = openstack_networking_subnet_v2.hub_wan_subnet.id
}

C. FortiOS 7.x Security Policies (config/fortigate.conf)โ€‹

config firewall policy
edit 101
set name "WAN-TO-AIGATEWAY-VIP"
set srcintf "port1"
set dstintf "port2"
set srcaddr "all"
set dstaddr "VIP-AIGATEWAY-8080"
set action accept
set schedule "always"
set service "HTTP" "HTTPS"
set utm-status enable
set waf-profile "OKUSTERA-WAF-PROFILE"
set ips-sensor "default"
set logtraffic all
next
edit 201
set name "FGT-POL-001-ANTI-SSRF-METADATA"
set srcintf "port2"
set dstintf "any"
set srcaddr "AI-GATEWAY-HOSTS"
set dstaddr "CLOUD-METADATA-169.254.169.254"
set action deny
set schedule "always"
set service "ALL"
set logtraffic all
next
edit 202
set name "FGT-POL-202-MCP-TOOLS"
set srcintf "port2"
set dstintf "port4"
set srcaddr "AI-GATEWAY-HOSTS"
set dstaddr "SPOKE-MCP-SERVERS"
set action accept
set schedule "always"
set service "HTTP"
set logtraffic all
next
end

D. Microsoft Presidio Sanitization Service (app/engine/presidio_service.py)โ€‹

from presidio_analyzer import AnalyzerEngine, PatternRecognizer, Pattern
from presidio_anonymizer import AnonymizerEngine
from presidio_anonymizer.entities import OperatorConfig

class SovereignPresidioService:
def __init__(self):
self.analyzer = AnalyzerEngine()
self.anonymizer = AnonymizerEngine()
self._register_custom_recognizers()
self.session_vault = {}

def _register_custom_recognizers(self):
# Swiss / International IBAN recognizer
iban_pattern = Pattern("IBAN Pattern", r"\b[A-Z]{2}\d{2}[A-Z0-9]{4}\d{7}([A-Z0-9]?){0,16}\b", 0.95)
iban_recognizer = PatternRecognizer(supported_entity="IBAN_CODE", patterns=[iban_pattern])
self.analyzer.registry.add_recognizer(iban_recognizer)

# Healthcare Medical Record Number (MRN)
mrn_pattern = Pattern("MRN Pattern", r"\bMRN-[0-9]{6,8}\b", 0.95)
mrn_recognizer = PatternRecognizer(supported_entity="MEDICAL_RECORD_NUMBER", patterns=[mrn_pattern])
self.analyzer.registry.add_recognizer(mrn_recognizer)

def mask_text(self, text: str, session_id: str) -> dict:
results = self.analyzer.analyze(text=text, language="en")
session_map = self.session_vault.setdefault(session_id, {})

anonymized_result = self.anonymizer.anonymize(
text=text,
analyzer_results=results,
operators={
"DEFAULT": OperatorConfig("replace", {"new_value": "<SANITIZED_ENTITY>"}),
"PERSON": OperatorConfig("replace", {"new_value": "<PERSON_1>"}),
"IBAN_CODE": OperatorConfig("replace", {"new_value": "<IBAN_CODE_1>"}),
"US_SSN": OperatorConfig("replace", {"new_value": "<US_SSN_1>"}),
"CREDIT_CARD": OperatorConfig("replace", {"new_value": "<CREDIT_CARD_1>"}),
"MEDICAL_RECORD_NUMBER": OperatorConfig("replace", {"new_value": "<MEDICAL_RECORD_NUMBER_1>"}),
},
)
return {"sanitized_text": anonymized_result.text, "entities_found": [r.entity_type for r in results]}

def restore_text(self, text: str, session_id: str) -> str:
session_map = self.session_vault.get(session_id, {})
for placeholder, original in session_map.items():
text = text.replace(placeholder, original)
return text

E. Model Context Protocol Server with Anti-SSRF Protection (app/engine/mcp_server.py)โ€‹

import ipaddress

BLOCKED_TARGETS = ["169.254.169.254", "localhost", "127.0.0.1"]
BLOCKED_PORTS = [6443, 2379, 10250]

class SovereignMCPServer:
def execute_tool(self, tool_name: str, arguments: dict) -> dict:
# 1. Anti-SSRF Defense: Intercept malicious target parameters
target_host = arguments.get("target_host", "")
if any(b in target_host for b in BLOCKED_TARGETS):
return {
"error": "Security Violation: Target IP blocked by FortiGate Policy FGT-POL-001-ANTI-SSRF-METADATA",
"blocked": True,
"threat": "SSRF_PROBE_METADATA",
}

# 2. Authorized Tool Execution
if tool_name == "query_customer_ledger":
account_id = arguments.get("account_id", "ACC-UNKNOWN")
return {
"account_id": account_id,
"balance": 48250.75,
"currency": "CHF",
"status": "ACTIVE",
"audited_by": "FortiGate-EastWest-IPS",
}

if tool_name == "lookup_sovereign_policy":
return {"standard": "EU-AI-ACT", "compliant": True, "residency": "SOVEREIGN_PRIVATE_CLOUD"}

return {"error": f"Tool {tool_name} not recognized"}

7. Deployment & Verification Runbookโ€‹

Step 1: Deploy Ingress & Workload into Tenant Namespaceโ€‹

# 1. Deploy tenant namespace manifests
kubectl --kubeconfig ~/.kube/config.tenant apply -f k8s/apisix-ingress.yaml
kubectl --kubeconfig ~/.kube/config.tenant apply -f k8s/shield-deployment.yaml

# 2. Deploy undercloud edge ingress
kubectl --kubeconfig ~/.kube/config apply -f k8s/edge-ingress.yaml

# 3. Verify deployment rollout
kubectl --kubeconfig ~/.kube/config.tenant rollout status deployment/sovereign-ai-gateway -n tenant-shield

Step 2: Run the Automated Security Verification Suiteโ€‹

The repository includes an end-to-end test suite (scripts/verify_security_suite.sh) covering all 6 verification stages:

cd okustera-secure-ai-gateway
./scripts/verify_security_suite.sh

Test Suite Execution Output:โ€‹

======================================================================
Okustera Sovereign AI Security Gateway: Test & Verification Suite
Target Gateway: https://shield.okustera.com
======================================================================

[TEST 1/6] Querying Gateway Telemetry & Registered Tools...
โœ” SUCCESS: Gateway telemetry responding normally.

[TEST 2/6] Verifying Microsoft Presidio PII Sanitization...
โœ” SUCCESS: Presidio masked personal entities to zero-retention placeholders.
Original: Sarah Connor, SSN 000-12-3456, IBAN CH93...
Masked : "Patient <PERSON_1>, SSN <US_SSN_1>, account IBAN <IBAN_CODE_1>, Card <CREDIT_CARD_1>"

[TEST 3/6] Verifying Authorized Model Context Protocol (MCP) Tool Call...
โœ” SUCCESS: MCP tool executed across FortiGate transit link.
Result: "Ledger Record for ACC-10928: Balance=48250.75 CHF | Status=ACTIVE"

[TEST 4/6] Simulating Threat: AI Agent SSRF Probe targeting 169.254.169.254...
โœ” SUCCESS (BLOCKED): FortiGate-VM dropped unauthorized metadata egress.
Policy : FGT-POL-001-ANTI-SSRF-METADATA
Action : DROP_AND_ALERT

[TEST 5/6] Simulating Threat: Ingress SQL Injection Attack in Prompt...
โœ” SUCCESS (BLOCKED): FortiGate L7 WAF halted execution at network border.
Policy : FGT-WAF-1001-SQL-INJECTION
Status : HTTP 403 Forbidden

[TEST 6/6] Verifying Full Pipeline: Prompt -> Mask -> LLM -> Tool -> Deanonymize...
โœ” SUCCESS: Complete pipeline executed.
- Raw Model Output Referenced : <PERSON_1>
- Restored Client Output Holds: Alice Henderson
- Latency : 1420 ms

======================================================================
ALL 6 SECURITY & VERIFICATION TESTS PASSED SUCCESSFULLY!
======================================================================

Step 3: Manual cURL Verificationโ€‹

1. Test Ingress WAF SQL Injection Mitigation:

curl -k -s -X POST https://shield.okustera.com/api/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"prompt": "DROP TABLE users; SELECT * FROM credentials WHERE 1=1--"}'
# Returns: HTTP 403 Forbidden with WAF block policy

2. Test In-Line PII Tokenization:

curl -k -s -X POST https://shield.okustera.com/api/v1/mask \
-H "Content-Type: application/json" \
-d '{"text": "Transfer 1000 EUR to Alice at IBAN CH9300000000000000000"}'
# Returns: {"sanitized_text": "Transfer 1000 EUR to <PERSON_1> at IBAN <IBAN_CODE_1>"}

8. Regulatory & Sovereign Compliance Alignmentโ€‹

Standard / RegulationMandatory MandateArchitectural Safeguard Implemented
GDPR (EU 2016/679)Article 9 & Chapter VIn-line Presidio tokenization guarantees that sensitive personal data is never transmitted to untrusted models or logged to third-party endpoints.
HIPAA (45 CFR ยง 164.514)Safe Harbor De-identificationAutomated detection and masking of all 18 PHI identifiers (names, medical record numbers, dates, SSN).
EU AI Act (2024/1689)Article 52 & High-Risk RulesFortiGate East-West firewall segmentation eliminates agent prompt injection risks and lateral movement to internal microservices.
NIS2 DirectiveArticle 21 Cyber Risk MeasuresOctavia Amphora health monitoring paired with FortiGate FGCP active-standby clustering ensures business continuity and zero single points of failure.
Zero Cloud EgressData Sovereignty MandateFull inference execution on in-cluster Kubernetes models with zero external cloud dependencies.