Flex Gateway Part 2 — Production Ready
MuleSoft Series · Part 2

Flex Gateway:
Production Ready

Kubernetes deployments, enterprise security policies, and GitOps automation — from lab to production in one deep dive.

In Part 1, we demystified Flex Gateway and got it running locally in minutes. Now it's time to go further. Real-world API infrastructure demands more than a docker run — it demands resilience, automation, and defence-in-depth security.

This post takes you from a single container to a fully orchestrated, policy-driven gateway running inside Kubernetes — with a CI/CD pipeline that deploys config changes with zero downtime.

By the end, you'll have a production-grade template you can drop straight into your own infrastructure.

Section 01

Kubernetes Native Deployment

Kubernetes is the natural habitat for Flex Gateway. Its lightweight Envoy runtime fits perfectly into a pod, scales horizontally via HPA, and plugs into your existing observability stack without any friction.

We'll deploy using Helm — the Kubernetes package manager — and cover both operational modes.

☁️
Connected Mode
Fully managed through Anypoint Platform. Centralized policy definition, real-time analytics, and lifecycle management pushed down to the gateway.
Enterprise Teams Multi-Region Full Visibility
⚙️
Local Mode
Runs standalone from YAML config. No platform dependency — perfect for air-gapped networks, edge deployments, or GitOps-first teams.
Air-Gapped Edge / IoT GitOps
Kubernetes Resource Topology
Autoscaling
HorizontalPodAutoscaler
↓ scales
Workload
Deployment (3 → 10 replicas)
↓ manages
Networking
Service (Load Balancer)
Configuration
ConfigMap (gateway YAML)
helm/connected-values.yaml
# ✅ Production best practice: -f values.yaml, committed to Git. # Secrets are referenced by K8s Secret name — never stored in this file. anypointPlatform: connectedMode: true # Reference a pre-created Kubernetes Secret instead of inlining credentials secretName: flex-credentials # kubectl create secret generic flex-credentials ... deployment: replicaCount: 3 autoscaling: enabled: true minReplicas: 2 maxReplicas: 10 targetCPUUtilizationPercentage: 70
helm — connected mode (install command)
# Add the official MuleSoft Helm repository helm repo add mulesoft-helm https://mulesoft.github.io/helm-repos/ helm repo update # Deploy using values file — GitOps-safe, reviewable, diffable helm install flex-gateway mulesoft-helm/flex-gateway \ --namespace gateway-system \ --create-namespace \ -f helm/connected-values.yaml # For upgrades (idempotent): helm upgrade --install flex-gateway mulesoft-helm/flex-gateway \ --namespace gateway-system \ -f helm/connected-values.yaml
gateway-config.yaml — local mode
apiVersion: gateway.mulesoft.com/v1alpha1 kind: Gateway metadata: name: edge-gateway spec: listeners: - name: https-main port: 8443 protocol: HTTPS tls: mode: TERMINATE # Gateway handles TLS termination certificates: - certFile: /tls/tls.crt # ⚠️ Volume must be mounted — see local-values.yaml below keyFile: /tls/tls.key routes: - id: api-v1 path: ["/api/v1/*"] upstream: url: "http://backend-service:8080" --- # Apply to Kubernetes as a ConfigMap (idempotent) kubectl create configmap flex-gateway-config \ --namespace gateway-system \ --from-file=gateway-config.yaml \ -o yaml --dry-run=client | kubectl apply -f - # Install using a values file — not --set flags helm upgrade --install flex-gateway-standalone mulesoft-helm/flex-gateway \ --namespace gateway-system \ -f helm/local-values.yaml
helm/local-values.yaml
# ✅ Commit to Git — no secrets in this file. anypointPlatform: connectedMode: false # standalone / air-gapped mode deployment: configMapName: flex-gateway-config # ⚠️ Required: mount the TLS secret so /tls/tls.crt and /tls/tls.key exist in the pod. # Without this, the gateway pod will fail to start (CrashLoopBackOff). extraVolumes: - name: tls-certs secret: secretName: flex-gateway-tls # kubectl create secret tls flex-gateway-tls --cert=... --key=... extraVolumeMounts: - name: tls-certs mountPath: /tls readOnly: true
Why not --set in production?
--set flags are not GitOps-safe. They live only in your shell history, can't be code-reviewed via pull request, and are easy to mis-type. A values.yaml file committed to Git gives you a full audit trail, diff-able changes, and works seamlessly with Argo CD or Flux. Reserve --set for quick local experiments only.
Section 02

Security & Traffic Policy Chain

A gateway without policies is just a reverse proxy. The real power of Flex Gateway is its ability to compose a chain of policies — each request passes through every layer in sequence, giving you defence-in-depth with zero application code changes.

Request → Policy Chain → Upstream
POLICY 01
๐Ÿšฆ Rate Limiting
100 req/min per client IP. Prevents abuse and runaway clients from starving other consumers.
POLICY 02
✅ Request Validation
JSON Schema validation on query params and body. Rejects malformed payloads before they hit your service.
POLICY 03
๐Ÿ”‘ Client ID Enforcement
Every caller must identify itself. Unknown clients are rejected before touching any business logic.
POLICY 04
๐Ÿ” OAuth 2.0 Introspection
Token validated live against your IdP. Results cached (60s TTL) to avoid hammering the auth server.
POLICY 05
๐Ÿงน Header Sanitization
Strips internal headers and Authorization before forwarding. Adds X-API-Version and trace context upstream.
POLICY 06
๐Ÿ›ก️ Security Headers
Injects HSTS, X-Content-Type-Options into every response. Compliance coverage with zero code.
secured-gateway-config.yaml — full policy chain
apiVersion: gateway.mulesoft.com/v1alpha1 kind: Gateway metadata: name: secured-product-gateway spec: routes: - id: product-catalog path: ["/api/products/*"] methods: ["GET"] upstream: url: "http://product-service:3000" policies: # ── 1. Prevent abuse ────────────────────────────────────────── - rate-limiting: limit: 100 period: 60 identifier: $request.remoteAddress # ── 2. Validate inputs — required fields + type + pattern ──── - request-validation: schema: | { "type": "object", "required": ["productId", "quantity"], "properties": { "productId": { "type": "string", "pattern": "^PRD-[0-9]+$" }, "quantity": { "type": "integer", "minimum": 1 } }, "additionalProperties": false // deny unlisted fields — strict allow-list } # ── 3. Identify callers ─────────────────────────────────────── - client-id-enforcement # ── 4. Validate OAuth 2.0 tokens ───────────────────────────── - token-introspection: url: "https://auth-server.com/introspect" clientId: $env.INTROSPECTION_CLIENT_ID # never hardcode secrets clientSecret: $env.INTROSPECTION_CLIENT_SECRET cacheTtl: 60 # ── 5. Sanitize headers — strip internal & auth headers before forwarding ─ # X-Internal-* uses Envoy prefix-wildcard matching (supported natively by Flex Gateway). # This is an explicit deny-list; add X-Forwarded-For here too if not needed upstream. - request-headers-remove: headers: ["X-Internal-*", "Authorization"] # OAuth validated above — strip before upstream - request-headers-set: headers: X-API-Version: "v1" X-Gateway-Time: $datetime # ISO-8601 timestamp injected at gateway # ── 6. Harden response headers ──────────────────────────────── - response-headers-set: headers: Strict-Transport-Security: "max-age=31536000; includeSubDomains" X-Content-Type-Options: "nosniff"
Pro Tip — Secrets Management
Notice the $env.VARIABLE_NAME syntax in the OAuth policy. Never hardcode credentials in YAML. Reference environment variables injected via Kubernetes Secrets — this keeps your config files safe to commit to Git while secrets stay in a vault.
Section 03

GitOps CI/CD Automation

Manual config deployments are the enemy of reliability. Every change should flow through a pipeline — reviewed, validated, and rolled out automatically with zero downtime.

Here's a production-grade GitHub Actions workflow that treats your gateway config exactly like application code.

GitOps Deployment Flow
๐Ÿ“
Feature Branch Edit
๐Ÿ”
Pull Request + YAML Lint
Merge to Main
๐Ÿ”„
ConfigMap Update
๐Ÿš€
Rolling Restart (0 downtime)
.github/workflows/deploy-gateway-config.yaml
name: Deploy Flex Gateway Config on: push: branches: [main] paths: ['gateway-config/**'] # only trigger on config changes jobs: deploy: runs-on: ubuntu-latest steps: # ── Step 1: Checkout ────────────────────────────────────────── - name: Checkout Code uses: actions/checkout@v3 # ── Step 2: Lint YAML before deploying ──────────────────────── - name: Validate Gateway Config run: | yamllint gateway-config/prod.yaml echo "✅ YAML lint passed" # ── Step 2b: Helm dry-run — catch rendering errors pre-flight ─ - name: Helm Dry-Run Pre-flight run: | helm upgrade --install flex-gateway mulesoft-helm/flex-gateway --namespace gateway-system -f helm/connected-values.yaml --dry-run echo "✅ Helm dry-run passed" # ── Step 3: Connect to cluster ──────────────────────────────── - name: Configure K8s Context uses: azure/setup-kubectl@v3 - name: Set Kubeconfig run: | echo "${{ secrets.KUBECONFIG }}" | base64 -d > /tmp/kubeconfig.yaml export KUBECONFIG=/tmp/kubeconfig.yaml # injected from GitHub Secret # ── Step 4: Apply config (idempotent) ───────────────────────── - name: Deploy / Update ConfigMap run: | kubectl create configmap flex-gateway-prod-config \ --namespace gateway-system \ --from-file=gateway-config/prod.yaml \ -o yaml --dry-run=client | kubectl apply -f - # ── Step 5: Rolling restart — zero downtime ─────────────────── - name: Rolling Restart Gateway Pods run: | kubectl rollout restart deployment/flex-gateway \ --namespace gateway-system kubectl rollout status deployment/flex-gateway \ --namespace gateway-system --timeout=120s
Zero-Downtime Guarantee
The kubectl rollout restart command replaces pods one at a time. Combined with Kubernetes' readiness probes, no traffic is routed to a pod until it's fully started and healthy — making config updates completely transparent to consumers.
Section 04

Choosing Your Operational Mode

The most common question teams face is: when do I use Connected Mode vs Local Mode? The answer depends on your connectivity requirements, team structure, and compliance posture.

Scenario
Connected
Local
Central enterprise API management
✓ Recommended
Possible
Air-gapped / regulated environment
Not suitable
✓ Recommended
Edge / factory floor deployments
Unreliable
✓ Recommended
GitOps-first teams
Works well
✓ Native fit
Analytics & real-time dashboards
✓ Recommended
⇢ Externalized
Multi-cloud / hybrid environments
✓ Recommended
✓ Per-site
Hybrid Strategy
You don't have to choose one mode globally. Run Connected Mode in your central cloud regions for managed APIs and full analytics, while using Local Mode in edge factories or partner data centers — reusing the same policy definitions from Anypoint Platform's Design Center across both.
Wrap-up

The Strategic Gateway

MuleSoft Flex Gateway isn't just another reverse proxy — it's the enforcement layer that gives your platform teams the control they need without slowing down the delivery teams they serve.

๐Ÿš€
Deploy with Confidence
Kubernetes-native tooling, Helm charts, and GitOps pipelines make every release auditable and reversible.
๐Ÿ›ก️
Protect by Default
Security and rate-limiting policies embedded in every route — not bolted on as an afterthought.
๐ŸŒ
Operate Flexibly
The right mode for each environment. Cloud, edge, air-gapped — one gateway runtime, consistent governance.

The journey from a single docker run to a fully automated, policy-driven gateway is what transforms API management from a bottleneck into a genuine enabler of innovation.

Coming Up

Potential Part 3

๐Ÿ“Š
Observability
Prometheus + Grafana dashboards for Flex Gateway metrics
๐Ÿงฉ
Extensibility
Custom policy development with WebAssembly (WASM)
๐Ÿ”
Zero Trust
mTLS, service mesh integration, and advanced JWT flows
Performance
Benchmarking Flex Gateway throughput and latency at scale