GateForge Logo

GateForge

Migrate from 3scale to Connectivity Link with zero risk.
Automated, AI-powered, and fully reversible.

Red Hat 3scale GateForge Connectivity Link
Install with Helm See Screenshots
v0.1.9
EXPERIMENTAL Independent open-source project — not an official Red Hat product. APIs may change without notice.
Artifact Hub Quay Backend Quay Frontend License OpenShift 4.20+

Core Capabilities

Organizations running Red Hat 3scale API Management need a clear, automated path to Kubernetes-native API management via Red Hat Connectivity Link (Kuadrant). GateForge automates this migration end-to-end.

Core Engine

Policy Mapping Engine

Translates 3scale Products, mapping rules, application plans, and credentials into Connectivity Link 1.3 resources: HTTPRoute, AuthPolicy, PlanPolicy, APIProduct, Secrets, and more. See Policy Mapping for full detail.

Discovery

Automatic 3scale Discovery

Discovers Products, Backends, Mapping Rules, and ActiveDocs via both CRD inspection and Admin API. Supports connecting to multiple 3scale instances simultaneously. Refresh discovery bypasses cache on demand.

AI-Powered

AI Resource Generation & Verification

LangChain4j-based AI agent generates equivalent Connectivity Link resources, then reviews correctness, identifies potential issues, and provides recommendations.

Multi-Cluster

Multi-Cluster Deployment

Apply migrations to any target OpenShift cluster with ArgoCD auto-discovery and per-cluster RBAC validation. Download YAML for GitOps workflows.

Revert

Safe Rollback to 3scale

One-click revert of individual plans or bulk revert to restore 3scale management. Full audit trail with before/after YAML snapshots for every operation.

NEW v0.1.9

APICast Discovery & Migration

Discovers APIManager CRDs cluster-wide to find self-managed and multi-tenant APICast instances. Analyzes staging/production specs, custom Lua policies, TLS, and OpenTracing configuration. Maps APICast to Istio Gateway, EnvoyFilter, DestinationRule, and TelemetryPolicy.

Advanced Features
Hub-Spoke

Centralized Control Plane

PostgreSQL-backed persistence with Flyway migrations. Federated audit log across clusters. Hub overview API with aggregated stats and topology graph.

GitOps

Helm Chart & ArgoCD Ready

Packaged as a Helm chart on Artifact Hub. Deploys backend, frontend, and PostgreSQL with least-privilege RBAC. ArgoCD-native with selfHeal support.

Developer Hub

Backstage Integration

Auto-discovers 3scale products. Generates Component entities with providesApis. Dynamic plugin with Observability, Topology, and Editor tabs.

kuadrantctl

kuadrantctl-Powered Generation

Generates HTTPRoute, AuthPolicy, and RateLimitPolicy from OpenAPI specs. Auto-consolidates rules exceeding the Gateway API 16-rule limit into prefix-based matches.

CL 1.3

Connectivity Link 1.3 CRDs

Generates APIProduct, PlanPolicy, and APIKey CRDs from 3scale Application Plans, credentials, and product metadata.

Performance

FAQ Cache with Data Grid

Common AI questions cached in Red Hat Data Grid for instant responses. Observability via OpenTelemetry, Prometheus, and Grafana.

Compatibility Matrix

GateForge has been tested with the following Red Hat product versions:

ProductVersionStatus
OpenShift Container Platform4.20, 4.21Tested
Red Hat Connectivity Link1.2, 1.3Tested
Kuadrant (upstream)1.1.x (bundled with Connectivity Link)Tested
Red Hat 3scale API Management2.16.x (2.16.2, 2.16.3)Tested
Red Hat Build of Keycloak (RHBK)26.4.xTested
Istio (Sail Operator / Service Mesh 3.x)3.xTested
PostgreSQL (RHEL 9)15.xTested
Flyway (Quarkus Extension)10.x (via Quarkus BOM)Tested
Gateway APIv1.2.x (bundled with OpenShift)Compatible
Microcks1.10.xCompatible
Red Hat Data Grid (Infinispan)15.x (Hot Rod protocol)Tested
Red Hat Developer Hub1.9.xTested
3scale Plugin for Developer Hub3.10.x (backstage-community-plugin-3scale-backend)Tested
kuadrantctl0.10.xTested
GateForge DevHub Plugin0.1.9 (quay.io/maximilianopizarro/gateforge-devhub-plugin)Tested
OpenTelemetry Operator0.x (Collector + Instrumentation)Compatible
Grafana Operator5.xCompatible

Screenshots

Click any image to enlarge.

Dashboard Click to enlarge

Dashboard — Cluster Overview

3scale Explorer Click to enlarge

3scale Explorer — Products & Backends

Migration Wizard Click to enlarge

Migration Wizard — Product Selection

AI Chat Assistant Click to enlarge

AI Chat — Migration Assistant

Audit Log Click to enlarge

Audit Log — Migration Trail

DevHub Observability Click to enlarge

Developer Hub — Observability Tab

DevHub Component Editor Click to enlarge

Developer Hub — Component Editor

Architecture

GateForge — Unified Solution Architecture

Click to enlarge
graph TB
  subgraph OCP["OpenShift Container Platform 4.20+"]
    direction TB

    subgraph gf["GateForge Platform"]
      FE["Frontend\nAngular 18 + Red Hat Design System"]
      BE["Backend\nQuarkus 3.x / Java 17"]
      PG[("PostgreSQL 15\n+ Flyway Migrations")]
      DG["Red Hat Data Grid\nInfinispan 15.x\nHot Rod Protocol"]
      DHPLUGIN["GateForge DevHub Plugin\nBackend + Frontend"]
    end

    subgraph aieng["AI Engine"]
      LC4J["LangChain4j\nMCP Tool Calling"]
      LITELLM["LiteLLM Gateway\nDeepSeek R1 14B"]
    end

    subgraph source["Red Hat 3scale API Management 2.16"]
      ADM["Admin API\nProducts - Backends - Plans - Credentials"]
      CRD3S["3scale Operator CRDs\ncapabilities.3scale.net"]
    end

    KCTL["kuadrantctl 0.10\nOpenAPI-to-Gateway API"]

    subgraph target["Red Hat Connectivity Link 1.3 / Kuadrant"]
      subgraph gwapi["Gateway API v1.2"]
        GW["Gateway\nIstio class"]
        HR["HTTPRoute\nmax 16 rules"]
      end
      subgraph kpol["Kuadrant Policies"]
        AP["AuthPolicy"]
        RLP["RateLimitPolicy"]
      end
      subgraph cl13["Connectivity Link 1.3 CRDs"]
        APROD["APIProduct\ndevportal.kuadrant.io"]
        PP["PlanPolicy\nextensions.kuadrant.io"]
        AK["APIKey\ndevportal.kuadrant.io"]
        TP["TelemetryPolicy\nextensions.kuadrant.io"]
      end
    end

    subgraph platform["Platform Services"]
      IST["Istio / Service Mesh 3.x\nSail Operator"]
      RHBK["Red Hat Build of Keycloak\nRHBK 26.4.x"]
      RHDH["Red Hat Developer Hub 1.9\n+ 3scale Auto-Discovery Plugin"]
      ARGO["ArgoCD\nCluster Discovery + GitOps"]
      MCK["Microcks 1.10\nAPI Mocking"]
    end

    subgraph obs["Observability - Optional"]
      OTEL["OpenTelemetry\nOperator + Collector"]
      PROM["Prometheus\nServiceMonitor"]
      GRAF["Grafana\nDashboard"]
      THANOS["Thanos Querier"]
    end
  end

  HELM["Helm Chart\nArtifact Hub"]

  FE -->|REST API| BE
  BE --> PG
  BE -->|FAQ + Products cache| DG
  BE --> LC4J
  LC4J --> LITELLM
  BE -->|discover products| ADM
  BE -->|Fabric8 Client| CRD3S
  BE -->|OpenAPI spec| KCTL
  KCTL -.->|generate| HR
  KCTL -.->|generate| AP
  KCTL -.->|generate| RLP
  BE ==>|apply CRDs| GW
  BE ==>|apply CRDs| HR
  BE ==>|apply CRDs| AP
  BE ==>|apply CRDs| RLP
  BE ==>|apply CRDs| APROD
  BE ==>|apply CRDs| PP
  BE ==>|apply CRDs| AK
  BE ==>|apply CRDs| TP
  IST --> GW
  AP -.->|auth delegation| RHBK
  BE -->|Scaffolder API| RHDH
  DHPLUGIN -->|Observability + Topology tabs| RHDH
  DHPLUGIN -->|proxy metrics| THANOS
  ARGO -->|cluster secrets| BE
  MCK -.->|mock backends| HR
  BE -.->|Micrometer metrics| OTEL
  OTEL --> PROM
  PROM --> GRAF
  HELM -.->|deploy| gf

  style gf fill:#fce4ec,stroke:#c62828,stroke-width:2px
  style target fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
  style source fill:#fff3e0,stroke:#e65100,stroke-width:2px
  style aieng fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
  style platform fill:#f3e5f5,stroke:#6a1b9a,stroke-width:1px
  style obs fill:#fafafa,stroke:#9e9e9e,stroke-width:1px,stroke-dasharray: 5 5
  style cl13 fill:#c8e6c9,stroke:#388e3c,stroke-width:1px
  style gwapi fill:#dcedc8,stroke:#558b2f,stroke-width:1px
  style kpol fill:#dcedc8,stroke:#558b2f,stroke-width:1px
  style OCP fill:#fafafa,stroke:#212121,stroke-width:3px
        

Migration Pipeline (kuadrantctl + AI Verification)

Click to enlarge
flowchart TD
  Analyze["POST /api/migration/analyze"] --> FetchOAS{"Fetch OpenAPI\nfrom backend?"}
  FetchOAS -->|Found| KuadrantCtl["kuadrantctl generate\nhttproute / authpolicy / ratelimitpolicy"]
  FetchOAS -->|Not found| BuildOAS["Build synthetic OpenAPI\nfrom 3scale mapping rules"]
  BuildOAS --> KuadrantCtl
  KuadrantCtl -->|Success| PostProcess["Post-process: namespace,\ngateway, labels"]
  KuadrantCtl -->|Fail| Fallback["Fallback:\nimproved Java templates"]
  PostProcess --> Consolidate{"Rules > 16?"}
  Consolidate -->|Yes| Merge["Consolidate to\nPathPrefix matches"]
  Consolidate -->|No| AIVerify
  Merge --> AIVerify["MigrationAgent:\nverify & recommend"]
  Fallback --> AIVerify
  AIVerify --> Plan["Store plan + AI analysis"]
  Plan --> DB["Persist to PostgreSQL"]
  Plan --> SELECT["Select Target Cluster"]
  SELECT --> APPLY["Apply to Target\n(editable YAML)"]
  APPLY --> AUDIT["Record in Audit Log"]
        

Developer Hub — 3scale Auto-Discovery + GateForge Plugin

Click to enlarge
sequenceDiagram
  participant ThreeScale as 3scale Admin API
  participant Plugin3s as RHDH 3scale Plugin
  participant Catalog as RHDH Catalog
  participant GateForge as GateForge Backend
  participant Scaffolder as RHDH Scaffolder
  participant K8s as OpenShift Cluster
  participant PluginGF as GateForge Frontend Plugin
  participant THANOS as Thanos Querier

  Plugin3s->>ThreeScale: Poll products (every 5 min)
  ThreeScale-->>Plugin3s: Product list
  Plugin3s->>Catalog: Create/update API entities

  GateForge->>K8s: Apply Kuadrant resources
  GateForge->>GateForge: Generate Component catalog-info.yaml
  GateForge->>Scaffolder: POST /api/scaffolder/v2/tasks (gateforge-register-component)
  Scaffolder->>Catalog: catalog:register (from GateForge URL)
  Note over GateForge,Scaffolder: On timeout → error to user

  PluginGF->>K8s: Fetch policies (AuthPolicy, RateLimitPolicy, etc.)
  PluginGF->>PluginGF: Render Policy Topology tab
  PluginGF->>THANOS: Proxy metrics query
  PluginGF->>PluginGF: Render Observability tab
        

Generated CRDs per Product (Connectivity Link 1.3)

Click to enlarge
flowchart LR
  Product["3scale Product"] --> Gateway["Gateway"]
  Product --> HTTPRoute["HTTPRoute"]
  Product --> AuthPolicy["AuthPolicy"]
  Product --> RateLimit["RateLimitPolicy"]
  Product --> APIProduct["APIProduct\n(devportal.kuadrant.io)"]
  Product --> Route["OpenShift Route"]

  Plans["Application Plans"] --> PlanPolicy["PlanPolicy\n(extensions.kuadrant.io)"]
  Keys["Application Keys"] --> APIKey["Secret\n(api_key from 3scale user_key)"]

  Observability{"Observability\nenabled?"} -->|Yes| TelemetryPolicy["TelemetryPolicy\n(extensions.kuadrant.io)"]
  Observability -->|No| Skip["Skipped"]

  style APIProduct fill:#e6f5e0,stroke:#2d6b24
  style PlanPolicy fill:#e0ecff,stroke:#0066cc
  style APIKey fill:#e0ecff,stroke:#0066cc
  style TelemetryPolicy fill:#fff3e0,stroke:#e65100
  style Skip fill:#f5f5f5,stroke:#999
        

AI Chat FAQ Cache Flow

Click to enlarge
flowchart LR
  User[User Question] --> Normalize[Normalize text]
  Normalize --> CacheCheck{FAQ Cache Hit?}
  CacheCheck -->|Yes| Instant["Return cached response (ms)"]
  CacheCheck -->|No| LLM["Call LLM (30-60s)"]
  LLM --> Response[Return AI response]
  Startup[App Startup] --> WarmUp["Background: send FAQ prompts to LLM"]
  WarmUp --> DataGrid["Store in Data Grid (gateforge-faq)"]
        

AI / MCP Tool Calling Flow

Click to enlarge
sequenceDiagram
  participant U as User
  participant Chat as ChatComponent
  participant Agent as MigrationAgent
  participant LLM as LiteLLM (deepseek-r1)
  participant Tools as GateForgeTools
  participant Svc as Backend Services

  U->>Chat: Ask question
  Chat->>Agent: POST /api/chat
  Agent->>LLM: Chat completion + tool definitions
  LLM-->>Agent: tool_call: listThreeScaleProducts()
  Agent->>Tools: invoke listThreeScaleProducts
  Tools->>Svc: ThreeScaleService.listProducts()
  Svc-->>Tools: Product list (all sources)
  Tools-->>Agent: Formatted product data
  Agent->>LLM: Tool result + continue
  LLM-->>Agent: Final answer with real data
  Agent-->>Chat: Response
  Chat-->>U: Display answer
        

Policy Mapping & Core Migration Engine

The original GateForge capability — and still its core — is translating Red Hat 3scale API Management configuration into Connectivity Link 1.3 (Kuadrant) resources. Analysis always produces the full resource set; cluster readiness is validated separately before apply.

Analysis vs. apply: POST /api/migration/analyze never skips resources due to missing operators. The Migration Wizard shows Required for apply, not for analysis prerequisites; use GET /api/cluster/readiness?planId=… to probe the target cluster. Machine-readable catalog: GET /api/migration/policy-mapping.

RHCL 1.3 policy taxonomy

Do not mix these layers when suggesting migration resources:

LayerAPI groupResources
Gateway APIgateway.networking.k8s.io/v1Gateway, HTTPRoute
Core RHCLkuadrant.io/v1AuthPolicy, RateLimitPolicy, TokenRateLimitPolicy, DNSPolicy, TLSPolicy
Extensionsextensions.kuadrant.io/v1alpha1PlanPolicy, OIDCPolicy, TelemetryPolicy
Developer Portaldevportal.kuadrant.io/v1alpha1APIProduct, APIKey
Platformv1, route.openshift.io/v1Secret, Route, Service, ServiceEntry

OIDCPolicy ≠ AuthPolicy JWT. OIDCPolicy orchestrates OAuth Authorization Code (browser) flows. Bearer JWT uses AuthPolicy.jwt.issuerUrl. Token introspection uses AuthPolicy.oauth2Introspection.

Consolidated mapping (3scale → RHCL 1.3)

3scaleRHCL 1.3GateForgeNotes
Product / exposureGateway + HTTPRoute + RouteGeneratedshared / dual / dedicated strategies
Backend / mapping rulesHTTPRoute.rules + backendRefsGeneratedPathPrefix; max 16 rules consolidated
Application (API Key)Secret + AuthPolicy.apiKeyGenerateduser_key preserved
Application (OIDC)AuthPolicy.jwtGeneratedNo consumer Secrets
Application Plan + limitsPlanPolicyGeneratedPrimary tier/limits vehicle
Global / edge limitRateLimitPolicyPartial100 req/60s placeholder baseline
Token-based limit (LLM)TokenRateLimitPolicySuggestedToken-metered APIs
TLS terminationTLSPolicySuggestedcert-manager / ACME
DNS / multiclusterDNSPolicySuggestedMulticluster exposure
Custom metrics labelsTelemetryPolicyGeneratedWhen observability enabled
OAuth browser flowOIDCPolicySuggestedNot a JWT substitute
API catalogAPIProductGeneratedOptional Developer Portal tier
Custom Lua policiesEnvoyFilter / WASMManualNo automatic migration
Header / URL rewriteHTTPRoute filtersSuggestedGateway API filters

3scale APIcast policies → RHCL 1.3

APIcast policyRHCL 1.3GateForge
API KeyAuthPolicy apiKey + SecretGenerated
OIDC (Bearer JWT)AuthPolicy jwt.issuerUrlGenerated
JWT Claim CheckAuthPolicy authorizationSuggested
OAuth 2.0 Token IntrospectionAuthPolicy oauth2IntrospectionSuggested
Keycloak Role CheckAuthPolicy authorization on JWT claimsSuggested
OAuth Auth Code (browser)OIDCPolicySuggested
mTLS / TLS Client CertTLSPolicy + AuthPolicy x509Suggested
Edge LimitingRateLimitPolicy + PlanPolicyPartial
Custom MetricsTelemetryPolicy + Envoy metricsPartial
WASM Plug-InEnvoy WASM / Extension SDKManual
Auth Caching / Batcher / ReferrerN/A3scale-specific
CORS, Retry, SOAP, CachingHTTPRoute filters / Istio / WASMManual

Object mapping reference (detail)

3scale ObjectConnectivity Link ResourceImplementation notes
ProductGateway + HTTPRoute + AuthPolicy + RateLimitPolicy + APIProduct + RouteOne resource bundle per selected product; labeled gateforge.io/product
BackendHTTPRoute backendRefsSingle-backend or multi-backend PathPrefix rules per usage path
Mapping RulesHTTPRoute rulesRegex $ anchor removed; {id} params normalized; max 16 rules → prefix consolidation
Application PlansPlanPolicy + RateLimitPolicyPlan limits → daily/monthly/custom windows; global 100 req/60s baseline on HTTPRoute
Application KeysSecret per appuser_key preserved as stringData.api_key; tier via secret.kuadrant.io/plan-id
OIDC appsAuthPolicy JWT + PlanPolicyNo Secrets; tiers match JWT clientID to 3scale application_id
Proxy authAuthPolicyAPI Key and OIDC are mutually exclusive per API (detected from proxy metadata)
External accessOpenShift RouteEdge TLS termination → Istio Gateway service
MetricsTelemetryPolicy (optional)Labels: product, auth_type, plan, user

Gateway strategies

StrategyGateway resources
shared (default)Single gateforge-shared Gateway for all products
dualSeparate internal and external Gateways
dedicatedOne Gateway per product ({systemName}-gw)

HTTPRoute generation pipeline

  1. Resolve backends — map 3scale backend usages to cluster Services (Admin API ID or name).
  2. OpenAPI discovery — probe backend URL for /q/openapi, /openapi.json, /swagger.json, etc.
  3. Synthetic OpenAPI — build OpenAPI 3.0 from mapping rules when no spec exists.
  4. kuadrantctl — generate HTTPRoute from OpenAPI (single-backend products only).
  5. Fallback templates — Java-built HTTPRoute when kuadrantctl fails or multi-backend routing is required.
  6. Rule consolidation — if rules exceed Gateway API limit (16), collapse to PathPrefix segments.

Mapping rule translation example

3scale regex patterns become Gateway API PathPrefix matches (not exact regex):

# 3scale Backend CRD (source) mappingRules: - httpMethod: GET pattern: "/api/v1/accounts$" - httpMethod: GET pattern: "/api/v1/accounts/{id}$" - httpMethod: POST pattern: "/api/v1/accounts$" # Connectivity Link HTTPRoute (generated) rules: - matches: - path: { type: PathPrefix, value: /api/v1/accounts } backendRefs: - name: accounts-service port: 8080

Authentication policies

API Key mode

  • AuthPolicy selects Secrets labeled app: <productSystemName> (Authorino-managed).
  • Each 3scale application with a user_key becomes a dedicated Secret preserving the original key.
  • PlanPolicy tiers use predicates on secret.kuadrant.io/plan-id.

OIDC mode

  • AuthPolicy uses jwt.issuerUrl from 3scale oidc_issuer_endpoint (embedded credentials stripped).
  • No consumer Secrets — clients keep IdP, token endpoint, and Authorization: Bearer.
  • PlanPolicy tiers match auth.identity.metadata.annotations["clientID"] to 3scale application_id.

PlanPolicy & rate limits

3scale application plan periods map to PlanPolicy limit fields:

3scale periodPlanPolicy field
minutecustom window 1m
hourcustom window 1h
daydaily
weekweekly
monthmonthly
year / eternityyearly

A global RateLimitPolicy (100 requests / 60s) is attached to each HTTPRoute as a baseline guardrail.

Apply order & prerequisites

Resources are applied in dependency order:

Gateway → HTTPRoute → APIProduct → PlanPolicy → Secret(s) → AuthPolicy → RateLimitPolicy → TelemetryPolicy → Route

Prerequisites inferred from generated resources:

PrerequisiteCRD probeTriggered by
Gateway APIgateways.gateway.networking.k8s.ioGateway, HTTPRoute
RHCL / Kuadrant coreauthpolicies.kuadrant.ioAuthPolicy, RateLimitPolicy
Kuadrant extensionsplanpolicies.extensions.kuadrant.ioPlanPolicy, TelemetryPolicy
Developer Portalapiproducts.devportal.kuadrant.ioAPIProduct
OpenShift Routesroutes.route.openshift.ioRoute
Authorino secretsSecret with api_key

Migration Wizard workflow

  1. Select products — multi-select from CRD + Admin API discovery.
  2. Gateway strategy — shared / dual / dedicated + target cluster.
  3. Analyze — full-page loading overlay; generates plan, AI review, prerequisites, editable YAML.
  4. Review — collapsible prerequisites and AI analysis panels; per-resource YAML edit/toggle.
  5. Apply / Revert — apply to cluster or bulk-revert to 3scale with audit trail.

API Reference

Core Migration & Discovery

EndpointMethodDescription
/api/cluster/projectsGETList all cluster projects
/api/threescale/productsGETList 3scale Products (all sources)
/api/threescale/backendsGETList 3scale Backends (all sources)
/api/threescale/statusGETAdmin API connectivity status
/api/threescale/refreshPOSTEvict discovery cache and reload products/backends from 3scale
/api/migration/policy-mappingGETConsolidated 3scale → RHCL 1.3 mapping catalog (taxonomy, consolidated table, APIcast policies)
/api/migration/analyzePOSTAnalyze and plan migration; returns prerequisites[] for apply-time readiness
/api/migration/plans/{id}/applyPOSTApply plan to target cluster
/api/migration/plans/{id}/revertPOSTRevert plan from target cluster
/api/migration/revert-bulkPOSTBulk revert to 3scale
/api/audit/reportsGETView audit log
/api/chatPOSTAI migration assistant (with FAQ cache)
/api/chat/warm-faqPOSTTrigger FAQ cache refresh
/api/chat/faq-statusGETCheck FAQ cache status (cached/total)

Phase 1 Multi-Source 3scale

EndpointMethodDescription
/api/threescale/sourcesGETList all 3scale sources
/api/threescale/sourcesPOSTAdd a new 3scale source
/api/threescale/sources/{id}DELETERemove a source
/api/threescale/sources/{id}/statusGETCheck source connectivity

Phase 2 Multi-Cluster Targets

EndpointMethodDescription
/api/cluster/targetsGETList target clusters
/api/cluster/targetsPOSTAdd a target cluster
/api/cluster/targets/{id}DELETERemove a target cluster
/api/cluster/targets/{id}/validateGETValidate RBAC access on target
/api/cluster/readinessGETProbe cluster RHCL readiness; optional planId and targetClusterId

Phase 3 Hub-Spoke & Federated

EndpointMethodDescription
/api/hub/overviewGETAggregated hub stats
/api/hub/audit?cluster=X&action=YGETFederated audit log with filtering
/api/hub/plans?cluster=X&status=YGETFederated plans with filtering
/api/hub/topologyGETCluster + source topology graph

Phase 6 APICast Discovery

EndpointMethodDescription
/api/apicast/discoverGETDiscover all APIManagers with self-managed APICast
/api/apicast/discover/{namespace}GETDiscover APIManagers by namespace
/api/apicast/analyze/{namespace}/{name}GETAnalyze specific APIManager configuration
/api/apicast/mapPOSTMap APICast config to Istio resources
/api/apicast/map-allPOSTBatch map all discovered APICasts

Phase 5 Developer Hub Integration

EndpointMethodDescription
/api/migration/plans/{id}/catalog-info/{product}GETServe generated catalog-info.yaml for catalog:register
/api/migration/plans/{id}/confirm-registrationPOSTConfirm Component registration (with optional edits)

Getting Started

Migration in 4 Steps

Click to enlarge
graph LR
    Discover["1. Discover APIs"] --> Analyze["2. AI Analysis"]
    Analyze --> Review["3. Review & Apply"]
    Review --> Verify["4. Verify in DevHub"]

    style Discover fill:#e0ecff,stroke:#0066cc,stroke-width:2px
    style Analyze fill:#fce4ec,stroke:#880e4f,stroke-width:2px
    style Review fill:#e6f5e0,stroke:#2d6b24,stroke-width:2px
    style Verify fill:#fff3e0,stroke:#e65100,stroke-width:2px
        

Watch the 3-minute demo

Coming Soon

Video walkthrough of the full migration workflow will be available here.

Helm Installation

Install GateForge on OpenShift with PostgreSQL persistence.

# Add repo
helm repo add gateforge \
  https://maximilianopizarro.github.io/gateforge/


# Install with persistence
helm install gateforge gateforge/gateforge \
  --set ai.apiKey=YOUR_KEY \
  --set threescale.adminApi.url=URL \
  --set threescale.adminApi.accessToken=TOKEN

Multi-Source Config

Connect to multiple 3scale Admin API instances.

# Via Helm values
--set threescale.sources='[
  {"id":"prod",
   "label":"Production 3scale",
   "adminUrl":"https://...",
   "accessToken":"TOKEN",
   "enabled":true}
]'

Multi-Cluster Config

Deploy to multiple OpenShift clusters or auto-discover via ArgoCD.

# ArgoCD discovery
--set argocd.clusterDiscovery=true

# Or explicit clusters
--set targetClusters='[
  {"id":"staging",
   "label":"Staging",
   "apiServerUrl":"https://...",
   "token":"TOKEN",
   "verifySsl":false,
   "enabled":true}
]'

Using GateForge — AI Prompt Examples

GateForge includes an AI-powered chat assistant. Here are some example prompts:

Discovery & Analysis

List all 3scale Products and Backends from all sources
Show kuadrantctl topology

Migration Planning

Analyze my 3scale configuration and generate a migration plan using shared gateway
Compare shared, dual, and dedicated gateway strategies

Policy Generation

Generate an AuthPolicy replacing 3scale API Key auth with Kuadrant AuthPolicy
Create a RateLimitPolicy for 100 req/min

Gateway Strategy Comparison

StrategyDescriptionBest For
sharedSingle Istio Gateway with multiple HTTPRoutesSmall to medium clusters
dualTwo Gateways (internal/external) split by exposureNetwork segmentation
dedicatedOne Gateway per Product, full isolationStrict isolation requirements

Helm Chart Values

ValueDefaultDescription
backend.image.tagv0.1.9Backend image tag
frontend.image.tagv0.1.9Frontend image tag
ai.endpointlitellm-prod...LLM endpoint URL
ai.modeldeepseek-r1-distill-qwen-14bAI model name
ai.apiKey""LLM API key
threescale.adminApi.url""3scale Admin Portal URL
threescale.adminApi.accessToken""3scale access token
threescale.sources""JSON array of additional 3scale sources
targetClusters""JSON array of target clusters
argocd.clusterDiscoveryfalseAuto-discover clusters from ArgoCD
postgresql.enabledtrueDeploy PostgreSQL
postgresql.usernamegateforgeDB username
postgresql.passwordgateforgeDB password
connectivityLink.gatewayStrategysharedshared / dual / dedicated
connectivityLink.gatewayClassNameistioGateway class
rbac.clusterAdminfalseUse cluster-admin vs least-privilege
route.enabledtrueCreate OpenShift Route
developerHub.enabledfalseEnable Developer Hub catalog-info generation
developerHub.url""Developer Hub URL for component registration
developerHub.scaffolderUrl""RHDH Scaffolder API URL for Component registration
developerHub.scaffolderToken""Bearer token for Scaffolder API authentication
developerHub.componentSuffix-productSuffix appended to the product name to form the Component entity name (e.g. nfl-wallet-apikey-product)
datagrid.enabledtrueDeploy Data Grid for caching
datagrid.cacheTtlSeconds3600Cache TTL for 3scale products/backends
observability.enabledfalseEnable OpenTelemetry + metrics export
observability.serviceMonitor.enabledfalseDeploy Prometheus ServiceMonitor
observability.grafanaDashboard.enabledfalseDeploy Grafana dashboard ConfigMap

Developer Hub Integration

GateForge integrates with Red Hat Developer Hub (RHDH) 1.9+ through two OCI-packaged dynamic plugins and standard Software Templates. This section explains how to configure every piece.

Overview

After a successful migration, the GateForge backend triggers a Software Template (gateforge-register-component) via the RHDH Scaffolder API. The Scaffolder fetches the generated catalog-info.yaml from the GateForge backend and registers a Component entity in the catalog. Two dynamic plugins add frontend tabs (Observability, Policy Topology, Component Editor) and a backend processor for annotation-based entity enrichment.

1. GateForge Helm values

Set these values in your GateForge Helm chart deployment:

developerHub:
  enabled: true
  url: "https://backstage-developer-hub-<namespace>.<clusterDomain>"
  scaffolderUrl: "https://backstage-developer-hub-<namespace>.<clusterDomain>/api/scaffolder/v2/tasks"
  scaffolderToken: "<RHDH BACKEND_SECRET value>"
  componentSuffix: "-product"
ValueDescription
developerHub.scaffolderUrlFull URL to the Scaffolder task creation endpoint. Must match the RHDH external Route.
developerHub.scaffolderTokenThe BACKEND_SECRET value from the RHDH deployment. Used as Bearer token for Scaffolder API auth.
developerHub.componentSuffixSuffix added to the 3scale product name when creating Component entities (default: -product).

2. RHDH app-config-rhdh ConfigMap

Add the GateForge frontend Route to backend.reading.allow so the Scaffolder can fetch catalog-info.yaml:

backend:
  reading:
   allow:
    - host: github.com
    - host: raw.githubusercontent.com
    - host: gateforge-gateforge.<clusterDomain>

Register the Software Templates catalog in catalog.locations:

catalog:
  locations:
   - type: url
    target: https://github.com/your-org/repo/blob/main/software-templates/templates-catalog.yaml
  rules:
   - allow: [Component, Group, User, Resource, Location, Template, API]

3. Dynamic plugin registration (dynamic-plugins-rhdh)

Add both GateForge plugins to the dynamic-plugins-rhdh ConfigMap:

# Backend plugin (entity processor)
- package: oci://quay.io/maximilianopizarro/gateforge-devhub-plugin:0.1.9!gateforge-backstage-plugin-catalog-backend-module-gateforge
  disabled: false


# Frontend plugin (Observability, Topology, Editor tabs)
- package: oci://quay.io/maximilianopizarro/gateforge-devhub-frontend-plugin:0.1.9!gateforge-backstage-plugin-gateforge-frontend
  disabled: false
  pluginConfig:
   dynamicPlugins:
    frontend:
     gateforge.backstage-plugin-gateforge-frontend:
      mountPoints:
       - mountPoint: entity.page.observability/cards
        importName: GateForgeObservabilityTab
       - mountPoint: entity.page.topology/cards
        importName: GateForgeTopologyTab
       - mountPoint: entity.page.component/cards
        importName: GateForgeComponentEditorTab

4. RBAC permissions

Ensure users have the following permissions in rbac-policy-rhdh:

# Catalog — create locations and entities
p, role:default/authenticated, catalog.location.create, create, allow
p, role:default/authenticated, catalog.entity.create, create, allow


# Scaffolder — trigger templates
p, role:default/authenticated, scaffolder-template, read, allow
p, role:default/authenticated, scaffolder.task.read, read, allow
p, role:default/authenticated, scaffolder.task.create, create, allow
p, role:default/authenticated, scaffolder.action.execute, use, allow

5. Software Templates

Two templates are included in the GateForge repository:

TemplatePurposeTrigger
gateforge-register-componentRegisters a Component in the catalog using catalog:register action. Fetches catalog-info.yaml from the GateForge backend.Automatic (backend calls Scaffolder API after migration apply)
gateforge-unregister-componentRemoves a Component from the catalog using catalog:unregister action.Automatic (backend calls Scaffolder API on plan revert)

Registration flow

Click to enlarge
sequenceDiagram
  participant User as Platform Admin
  participant FE as GateForge Frontend
  participant BE as GateForge Backend
  participant SCF as RHDH Scaffolder
  participant CAT as RHDH Catalog
  participant K8s as OpenShift

  User->>FE: Click "Apply Migration"
  FE->>BE: POST /api/migration/plans/{id}/apply
  BE->>K8s: Apply Kuadrant resources
  BE-->>FE: Resources applied (editable Component YAML)
  User->>FE: Review/edit Component YAML
  User->>FE: Click "Register in Developer Hub"
  FE->>BE: POST /api/migration/plans/{id}/confirm-registration
  BE->>SCF: POST /api/scaffolder/v2/tasks (gateforge-register-component)
  SCF->>BE: GET /api/migration/plans/{id}/catalog-info/{product}
  BE-->>SCF: catalog-info.yaml (Component definition)
  SCF->>CAT: catalog:register
  CAT-->>SCF: entityRef
  SCF-->>BE: 201 Created (task ID)
  BE-->>FE: {status: "registered"}
        

ArgoCD Deployment

GateForge can be deployed through ArgoCD using the Helm chart from the GitHub Pages repository. Two deployment topologies are supported.

Single-Cluster (Standalone)

The simplest setup: GateForge and all target resources run on the same OpenShift cluster. Create a single ArgoCD Application pointing at the Helm chart.

# ArgoCD Application manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: gateforge
  namespace: openshift-gitops
spec:
  project: default
  source:
   repoURL: https://maximilianopizarro.github.io/gateforge/
   chart: gateforge
   targetRevision: "0.1.9"
   helm:
    values: |
     clusterDomain: apps.cluster.example.com
     ai:
      apiKey: YOUR_KEY
      endpoint: https://your-llm-endpoint/v1
     threescale:
      adminApi:
       url: https://3scale-admin.example.com
       accessToken: TOKEN
     developerHub:
      enabled: true
      scaffolderUrl: https://backstage-developer-hub-dev-hub.apps.example.com/api/scaffolder/v2/tasks
      scaffolderToken: BACKEND_SECRET_VALUE
  destination:
   server: https://kubernetes.default.svc
   namespace: gateforge
  syncPolicy:
   automated:
    selfHeal: true
    prune: true

Hub-Spoke (Multi-Cluster)

In a hub-spoke topology, GateForge runs on the hub cluster and migrates APIs to one or more spoke clusters. The hub holds the PostgreSQL database, Data Grid cache, and serves the UI. Spoke clusters only need Connectivity Link (Kuadrant) installed.

# Hub cluster — GateForge with multi-cluster config
clusterDomain: apps.hub.example.com
argocd:
  clusterDiscovery: true

# OR explicit target clusters:
targetClusters: |
  [
   {
    "id": "spoke-east",
    "label": "East Region",
    "apiServerUrl": "https://api.spoke-east.example.com:6443",
    "token": "sa-token-for-spoke",
    "authType": "token",
    "verifySsl": false,
    "enabled": true
   },
   {
    "id": "spoke-west",
    "label": "West Region",
    "apiServerUrl": "https://api.spoke-west.example.com:6443",
    "token": "sa-token-for-spoke",
    "authType": "token",
    "verifySsl": false,
    "enabled": true
   }
  ]

ArgoCD Hub-Spoke Topology

Click to enlarge
flowchart TB
  subgraph HubCluster["Hub Cluster (OpenShift)"]
    ARGO["ArgoCD\n(openshift-gitops)"]
    GF["GateForge\n(Helm chart)"]
    RHDH["Developer Hub\n(dynamic plugins)"]
    PG[("PostgreSQL")]
  end

  subgraph SpokeA["Spoke Cluster A"]
    CLA["Connectivity Link\n(Kuadrant)"]
    GWA["Gateway + HTTPRoute\nAuthPolicy + RateLimitPolicy"]
  end

  subgraph SpokeB["Spoke Cluster B"]
    CLB["Connectivity Link\n(Kuadrant)"]
    GWB["Gateway + HTTPRoute\nAuthPolicy + RateLimitPolicy"]
  end

  ARGO -->|deploy chart| GF
  GF --> PG
  GF -->|apply resources| CLA
  GF -->|apply resources| CLB
  GF -->|Scaffolder API| RHDH
  ARGO -.->|cluster secrets\nauto-discovery| GF

  style HubCluster fill:#fce4ec,stroke:#c62828,stroke-width:2px
  style SpokeA fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px
  style SpokeB fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px
        

ArgoCD tips

  • selfHeal: true ensures GateForge resources stay in sync with the chart.
  • Use ignoreDifferences for fields managed by OpenShift (e.g. Route status, Service cluster IPs).
  • To force a re-sync after updating the Helm chart at the same version, annotate the Application: argocd.argoproj.io/refresh=hard.
  • With argocd.clusterDiscovery: true, GateForge reads cluster secrets from the openshift-gitops namespace. The ServiceAccount needs get/list on Secrets in that namespace.

Installation Guide

Deploy GateForge on OpenShift or run it locally for development. Ensure prerequisites are satisfied before installing the Helm chart.

Prerequisites

  • OpenShift Container Platform 4.20+
  • Kuadrant Operator (Red Hat Connectivity Link)
  • 3scale Operator (for CRD-based discovery, where used)
  • Helm 3
  • kuadrantctl 0.10.x (bundled or installed where generation runs)

Quick start with Helm

# Add the GateForge chart repository
helm repo add gateforge https://maximilianopizarro.github.io/gateforge/

# Install with required values
helm install gateforge gateforge/gateforge \
  --set ai.apiKey=YOUR_KEY \
  --set threescale.adminApi.url=https://3scale-admin.example.com \
  --set threescale.adminApi.accessToken=TOKEN \
  --set clusterDomain=apps.cluster.example.com

Podman Compose (local development)

From the repository root, build and start local dependencies and services:

podman-compose up -d --build

Verify the deployment

  • Backend health: GET /q/health on the GateForge backend route or Service port
  • Frontend UI: served on port 4200 when running the dev stack locally

Configuration: Single-Tenant

Single-tenant mode uses one 3scale Admin API source and one target OpenShift cluster. This is the simplest production layout.

Key Helm values

ValueRole
threescale.adminApi.urlBase URL of the 3scale Admin Portal / Admin API
threescale.adminApi.accessTokenPersonal access token for the Admin API
clusterDomainApps domain for the target cluster (for routes and defaults)
connectivityLink.targetNamespaceNamespace where Kuadrant / Gateway API resources are applied
connectivityLink.gatewayStrategyshared (recommended for most), dual, or dedicated

Developer Hub integration

Enable catalog registration and Scaffolder-driven workflows with developerHub.enabled: true and set developerHub.scaffolderUrl to your Red Hat Developer Hub Scaffolder API base URL (plus optional token values as documented in the chart).

Example values.yaml snippet

ai:
  apiKey: YOUR_KEY
  endpoint: https://your-litellm-or-openai-compatible.example.com
  model: deepseek-r1-distill-qwen-14b
threescale:
  adminApi:
   url: https://3scale-admin.example.com
   accessToken: TOKEN
clusterDomain: apps.cluster.example.com
connectivityLink:
  targetNamespace: gateforge-migrations
  gatewayStrategy: shared
developerHub:
  enabled: true
  scaffolderUrl: https://developer-hub.example.com/api/scaffolder

Configuration: Multi-Tenant

Multi-tenant (hub-spoke) deployments connect GateForge to multiple 3scale sources and multiple target clusters. The hub cluster runs GateForge with PostgreSQL persistence and Data Grid; audit and plan data can be federated across spokes.

Multiple 3scale sources

Provide threescale.sources as a JSON array of source objects (id, label, admin URL, token, enabled flags). Each entry is discovered and listed independently in the UI and APIs.

Multiple target clusters

Set targetClusters to a JSON array of cluster definitions (API server URL, token, labels, TLS options). Migrations can target any registered cluster from the wizard.

Argo CD cluster discovery

With argocd.clusterDiscovery: true, GateForge discovers Argo CD cluster secrets and surfaces them as selectable targets without hard-coding kubeconfigs in values.

Persistence and audit

Keep postgresql.enabled: true on the hub for durable migration plans. Federated audit APIs aggregate events across clusters for compliance and troubleshooting.

Hub-spoke architecture

Click to enlarge
flowchart TB
  subgraph Hub["Hub cluster"]
    GF["GateForge\n(Backend + Frontend)"]
    PG[("PostgreSQL\nplans + audit")]
    DG["Red Hat Data Grid\nFAQ + product cache"]
  end

  subgraph Sources["Multiple 3scale sources"]
    S1["3scale instance A\nAdmin API + CRDs"]
    S2["3scale instance B\nAdmin API + CRDs"]
    S3["3scale instance N\n..."]
  end

  subgraph Targets["Target clusters"]
    C1["OpenShift cluster 1\nConnectivity Link"]
    C2["OpenShift cluster 2\nConnectivity Link"]
    CN["OpenShift cluster N\n..."]
  end

  GF --> PG
  GF --> DG
  GF --> S1
  GF --> S2
  GF --> S3
  GF --> C1
  GF --> C2
  GF --> CN

  style Hub fill:#fce4ec,stroke:#c62828,stroke-width:2px
  style Sources fill:#fff3e0,stroke:#e65100,stroke-width:1px
  style Targets fill:#e8f5e9,stroke:#2e7d32,stroke-width:1px
        

AI Model Configuration

GateForge talks to any OpenAI-compatible endpoint through LiteLLM (or a compatible proxy). The default chart model name (deepseek-r1-distill-qwen-14b) is a sensible starting point but is not mandatory—point ai.endpoint and ai.model at whatever serving stack you run.

Configuration properties

PropertyDescription
ai.endpointBase URL for chat completions (OpenAI-compatible)
ai.modelModel id as understood by the upstream server
ai.apiKeyBearer token or API key required by the endpoint
ai.temperatureSampling temperature for completions
ai.maxTokensUpper bound on generated tokens per response

Recommended models

ModelProviderNotes
deepseek-r1-distill-qwen-14bLiteLLM / vLLMDefault in chart. Strong reasoning for migration questions.
qwen2.5-coder-7b-instructvLLM / OllamaLighter and fast; good for interactive chat.
llama-3.1-8b-instructvLLM / OllamaGeneral-purpose instruct model.
granite-3.1-8b-instructIBM / RHEL AIAligned with Red Hat AI on RHEL OpenShift.
mistral-7b-instruct-v0.3vLLM / OllamaBalanced quality and footprint.
GPT-4o, Claude, etc.OpenAI / AnthropicVia LiteLLM proxy; typically best quality if budget allows.

Examples: Ollama and vLLM on OpenShift

Ollama (in-cluster Service exposing OpenAI-compatible API):

ai:
  endpoint: http://ollama.your-namespace.svc.cluster.local:11434/v1
  model: llama3.1
  apiKey: ""

vLLM (OpenAI-compatible server fronted by a Route or Service):

ai:
  endpoint: https://vllm-openai.apps.cluster.example.com/v1
  model: qwen2.5-coder-7b-instruct
  apiKey: YOUR_VLLM_TOKEN

AI-Powered Analysis Flow

The assistant uses context injection plus a single chat completion (and tool calls where enabled). It is not a RAG pipeline: there are no vector stores or embedding indexes in the request path for these answers.

Chat request path

Click to enlarge
flowchart LR
  A["User POST /api/chat"] --> B["Normalize input"]
  B --> C{"FAQ cache hit?\n(Data Grid)"}
  C -->|Yes| R["Return cached answer"]
  C -->|No| D["Build context:\n3scale products,\ncluster status,\nkuadrantctl version"]
  D --> E["Inject context\ninto user message"]
  E --> F["LLM chat completion\n(OpenAI-compatible)"]
  F --> G["Strip <redacted_thinking> blocks\nfrom reasoning models"]
  G --> H["Response to client"]

  style C fill:#e3f2fd,stroke:#1565c0
  style F fill:#fff3e0,stroke:#e65100
        

Design decisions

  • No vector store or embeddings for this chat path—context is assembled from live services and cached key-value data.
  • FAQ warmup: 10 pre-defined prompts are sent at startup; answers are stored in Data Grid with a 24-hour TTL for fast repeated questions.
  • MigrationAgent system prompt includes concrete mapping examples from 3scale to Connectivity Link.
  • AI verification runs after YAML / resource generation to review the plan.
  • Reasoning models may emit <redacted_thinking>...</redacted_thinking> blocks; these are stripped before the user sees the answer.

kuadrantctl Primitives

GateForge shells out to kuadrantctl for OpenAPI-driven generation. The table below lists the commands the platform uses or relates to; the migration pipeline primarily relies on HTTPRoute generation, with policies often produced in Java.

CommandPurposeInputOutput
kuadrantctl generate gatewayapi httproute --oas -Generate HTTPRouteOpenAPI YAML on stdinHTTPRoute YAML
kuadrantctl generate kuadrant authpolicy --oas -Generate AuthPolicyOpenAPI YAML on stdinAuthPolicy YAML
kuadrantctl generate kuadrant ratelimitpolicy --oas -Generate RateLimitPolicyOpenAPI YAML on stdinRateLimitPolicy YAML
kuadrantctl topology -n {namespace}Show policy topologyNamespaceTopology text
kuadrantctl versionCheck CLI versionVersion string

kuadrantctl in the migration pipeline

Click to enlarge
flowchart TD
  OAS["OpenAPI spec\n(fetched or synthetic)"] --> KH["kuadrantctl generate\nhttproute --oas -"]
  KH -->|success| PP["Post-process:\nnamespace, gateway, labels"]
  KH -->|failure| FB["Fallback:\nJava template generation"]
  PP --> RL{"Rules > 16?\nGateway API limit"}
  RL -->|yes| CO["Consolidate\nprefix matches"]
  RL -->|no| JV["Java builds\nAuthPolicy + RateLimitPolicy"]
  CO --> JV
  FB --> JV
  JV --> AI["AI verification\nof generated plan"]

  style KH fill:#e3f2fd,stroke:#1565c0
  style JV fill:#fff3e0,stroke:#e65100
  style FB fill:#ffebee,stroke:#c62828
        

Important notes

  • Only HTTPRoute generation via kuadrantctl is on the main migration path; AuthPolicy and RateLimitPolicy are typically built in Java for consistency with your cluster defaults.
  • Gateway API limits HTTPRoute matches to 16 rules; GateForge consolidates excess rules into prefix-style matches when needed.
  • If kuadrantctl exits with an error, the backend falls back to improved Java-based generation so migrations can continue.

Official Documentation